mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
apparmor: add a conditional version of get_newest_label
get_newest_label() will always return a refcount, on the profile it returns. However there are cases where we only need the refcount if the label is stale and get_newest_label() will return a different label. Optimize this by making the get/put happen conditionally, by keeping a flag indicating if the get was performed and a put is needed. Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
6d25e7b476
commit
f86ee868fd
|
|
@ -423,6 +423,38 @@ static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
|
|||
return aa_get_label(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* aa_get_newest_label_condref - find the newest version of @l
|
||||
* @l: the label to check for newer versions of
|
||||
* @needput: returns whether the reference needs put
|
||||
*
|
||||
* Returns: refcounted newest version of @l taking into account
|
||||
* replacement, renames and removals
|
||||
* return @l.
|
||||
*/
|
||||
static inline struct aa_label *aa_get_newest_label_condref(struct aa_label *l,
|
||||
bool *needput)
|
||||
{
|
||||
if (l && unlikely(label_is_stale(l))) {
|
||||
struct aa_label *tmp;
|
||||
|
||||
AA_BUG(!l->proxy);
|
||||
AA_BUG(!l->proxy->label);
|
||||
/* BUG: only way this can happen is @l ref count and its
|
||||
* replacement count have gone to 0 and are on their way
|
||||
* to destruction. ie. we have a refcounting error
|
||||
*/
|
||||
tmp = aa_get_label_rcu(&l->proxy->label);
|
||||
AA_BUG(!tmp);
|
||||
|
||||
*needput = true;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
*needput = false;
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline void aa_put_label(struct aa_label *l)
|
||||
{
|
||||
if (l)
|
||||
|
|
|
|||
|
|
@ -1176,22 +1176,21 @@ static struct aa_label *__label_find_merge(struct aa_labelset *ls,
|
|||
struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b)
|
||||
{
|
||||
struct aa_labelset *ls;
|
||||
struct aa_label *label, *ar = NULL, *br = NULL;
|
||||
struct aa_label *label;
|
||||
unsigned long flags;
|
||||
bool a_needput, b_needput;
|
||||
|
||||
AA_BUG(!a);
|
||||
AA_BUG(!b);
|
||||
|
||||
if (label_is_stale(a))
|
||||
a = ar = aa_get_newest_label(a);
|
||||
if (label_is_stale(b))
|
||||
b = br = aa_get_newest_label(b);
|
||||
a = aa_get_newest_label_condref(a, &a_needput);
|
||||
b = aa_get_newest_label_condref(b, &b_needput);
|
||||
ls = labelset_of_merge(a, b);
|
||||
read_lock_irqsave(&ls->lock, flags);
|
||||
label = __label_find_merge(ls, a, b);
|
||||
read_unlock_irqrestore(&ls->lock, flags);
|
||||
aa_put_label(ar);
|
||||
aa_put_label(br);
|
||||
aa_put_label_condref(a, a_needput);
|
||||
aa_put_label_condref(b, b_needput);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
|
@ -1228,9 +1227,10 @@ struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
|
|||
|
||||
if (!label) {
|
||||
struct aa_label *new;
|
||||
bool a_needput, b_needput;
|
||||
|
||||
a = aa_get_newest_label(a);
|
||||
b = aa_get_newest_label(b);
|
||||
a = aa_get_newest_label_condref(a, &a_needput);
|
||||
b = aa_get_newest_label_condref(b, &b_needput);
|
||||
|
||||
/* could use label_merge_len(a, b), but requires double
|
||||
* comparison for small savings
|
||||
|
|
@ -1242,8 +1242,8 @@ struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
|
|||
label = label_merge_insert(new, a, b);
|
||||
label_free_or_put_new(label, new);
|
||||
out:
|
||||
aa_put_label(a);
|
||||
aa_put_label(b);
|
||||
aa_put_label_condref(a, a_needput);
|
||||
aa_put_label_condref(b, b_needput);
|
||||
}
|
||||
|
||||
return label;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user