mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
ucounts: move kfree() out of critical zone protected by ucounts_lock
Although kfree is a non-sleep function, it is possible to enter a long chain of calls probabilistically, so it looks better to move kfree from alloc_ucounts() out of the critical zone of ucounts_lock. Link: https://lkml.kernel.org/r/1733458427-11794-1-git-send-email-mengensun@tencent.com Signed-off-by: MengEn Sun <mengensun@tencent.com> Reviewed-by: YueHong Wu <yuehongwu@tencent.com> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Andrei Vagin <avagin@google.com> Cc: Joel Granados <joel.granados@kernel.org> Cc: Thomas Weißschuh <linux@weissschuh.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
2616a8828b
commit
2b05eacc98
@ -164,8 +164,8 @@ struct ucounts *get_ucounts(struct ucounts *ucounts)
|
|||||||
struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
|
struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
|
||||||
{
|
{
|
||||||
struct hlist_head *hashent = ucounts_hashentry(ns, uid);
|
struct hlist_head *hashent = ucounts_hashentry(ns, uid);
|
||||||
struct ucounts *ucounts, *new;
|
|
||||||
bool wrapped;
|
bool wrapped;
|
||||||
|
struct ucounts *ucounts, *new = NULL;
|
||||||
|
|
||||||
spin_lock_irq(&ucounts_lock);
|
spin_lock_irq(&ucounts_lock);
|
||||||
ucounts = find_ucounts(ns, uid, hashent);
|
ucounts = find_ucounts(ns, uid, hashent);
|
||||||
@ -182,17 +182,17 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
|
|||||||
|
|
||||||
spin_lock_irq(&ucounts_lock);
|
spin_lock_irq(&ucounts_lock);
|
||||||
ucounts = find_ucounts(ns, uid, hashent);
|
ucounts = find_ucounts(ns, uid, hashent);
|
||||||
if (ucounts) {
|
if (!ucounts) {
|
||||||
kfree(new);
|
|
||||||
} else {
|
|
||||||
hlist_add_head(&new->node, hashent);
|
hlist_add_head(&new->node, hashent);
|
||||||
get_user_ns(new->ns);
|
get_user_ns(new->ns);
|
||||||
spin_unlock_irq(&ucounts_lock);
|
spin_unlock_irq(&ucounts_lock);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapped = !get_ucounts_or_wrap(ucounts);
|
wrapped = !get_ucounts_or_wrap(ucounts);
|
||||||
spin_unlock_irq(&ucounts_lock);
|
spin_unlock_irq(&ucounts_lock);
|
||||||
|
kfree(new);
|
||||||
if (wrapped) {
|
if (wrapped) {
|
||||||
put_ucounts(ucounts);
|
put_ucounts(ucounts);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user