diff options
author | Tejun Heo <tj@kernel.org> | 2013-11-29 10:42:59 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-11-29 10:42:59 -0500 |
commit | e6b817103d168a76e4044ebcdbc08225d77a81cb (patch) | |
tree | 2bb6a201b17387f933fea715253f432ef0c7bc81 /kernel | |
parent | 62236858f3cc558135d1ab6b2af44d22c489bb7f (diff) |
cgroup: refactor cgroup_pidlist_find()
Rename cgroup_pidlist_find() to cgroup_pidlist_find_create() and
separate out finding proper to cgroup_pidlist_find(). Also, move
locking to the caller.
This patch is preparation for pidlist restructure and doesn't
introduce any behavior changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ef019c075d5d..d58c30d3b828 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -3575,48 +3575,50 @@ static int cmppid(const void *a, const void *b) | |||
3575 | return *(pid_t *)a - *(pid_t *)b; | 3575 | return *(pid_t *)a - *(pid_t *)b; |
3576 | } | 3576 | } |
3577 | 3577 | ||
3578 | static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp, | ||
3579 | enum cgroup_filetype type) | ||
3580 | { | ||
3581 | struct cgroup_pidlist *l; | ||
3582 | /* don't need task_nsproxy() if we're looking at ourself */ | ||
3583 | struct pid_namespace *ns = task_active_pid_ns(current); | ||
3584 | |||
3585 | lockdep_assert_held(&cgrp->pidlist_mutex); | ||
3586 | |||
3587 | list_for_each_entry(l, &cgrp->pidlists, links) | ||
3588 | if (l->key.type == type && l->key.ns == ns) | ||
3589 | return l; | ||
3590 | return NULL; | ||
3591 | } | ||
3592 | |||
3578 | /* | 3593 | /* |
3579 | * find the appropriate pidlist for our purpose (given procs vs tasks) | 3594 | * find the appropriate pidlist for our purpose (given procs vs tasks) |
3580 | * returns with the lock on that pidlist already held, and takes care | 3595 | * returns with the lock on that pidlist already held, and takes care |
3581 | * of the use count, or returns NULL with no locks held if we're out of | 3596 | * of the use count, or returns NULL with no locks held if we're out of |
3582 | * memory. | 3597 | * memory. |
3583 | */ | 3598 | */ |
3584 | static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp, | 3599 | static struct cgroup_pidlist *cgroup_pidlist_find_create(struct cgroup *cgrp, |
3585 | enum cgroup_filetype type) | 3600 | enum cgroup_filetype type) |
3586 | { | 3601 | { |
3587 | struct cgroup_pidlist *l; | 3602 | struct cgroup_pidlist *l; |
3588 | /* don't need task_nsproxy() if we're looking at ourself */ | ||
3589 | struct pid_namespace *ns = task_active_pid_ns(current); | ||
3590 | 3603 | ||
3591 | /* | 3604 | lockdep_assert_held(&cgrp->pidlist_mutex); |
3592 | * We can't drop the pidlist_mutex before taking the l->rwsem in case | 3605 | |
3593 | * the last ref-holder is trying to remove l from the list at the same | 3606 | l = cgroup_pidlist_find(cgrp, type); |
3594 | * time. Holding the pidlist_mutex precludes somebody taking whichever | 3607 | if (l) |
3595 | * list we find out from under us - compare release_pid_array(). | 3608 | return l; |
3596 | */ | 3609 | |
3597 | mutex_lock(&cgrp->pidlist_mutex); | ||
3598 | list_for_each_entry(l, &cgrp->pidlists, links) { | ||
3599 | if (l->key.type == type && l->key.ns == ns) { | ||
3600 | /* make sure l doesn't vanish out from under us */ | ||
3601 | down_write(&l->rwsem); | ||
3602 | mutex_unlock(&cgrp->pidlist_mutex); | ||
3603 | return l; | ||
3604 | } | ||
3605 | } | ||
3606 | /* entry not found; create a new one */ | 3610 | /* entry not found; create a new one */ |
3607 | l = kzalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL); | 3611 | l = kzalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL); |
3608 | if (!l) { | 3612 | if (!l) |
3609 | mutex_unlock(&cgrp->pidlist_mutex); | ||
3610 | return l; | 3613 | return l; |
3611 | } | 3614 | |
3612 | init_rwsem(&l->rwsem); | 3615 | init_rwsem(&l->rwsem); |
3613 | INIT_DELAYED_WORK(&l->destroy_dwork, cgroup_pidlist_destroy_work_fn); | 3616 | INIT_DELAYED_WORK(&l->destroy_dwork, cgroup_pidlist_destroy_work_fn); |
3614 | down_write(&l->rwsem); | ||
3615 | l->key.type = type; | 3617 | l->key.type = type; |
3616 | l->key.ns = get_pid_ns(ns); | 3618 | /* don't need task_nsproxy() if we're looking at ourself */ |
3619 | l->key.ns = get_pid_ns(task_active_pid_ns(current)); | ||
3617 | l->owner = cgrp; | 3620 | l->owner = cgrp; |
3618 | list_add(&l->links, &cgrp->pidlists); | 3621 | list_add(&l->links, &cgrp->pidlists); |
3619 | mutex_unlock(&cgrp->pidlist_mutex); | ||
3620 | return l; | 3622 | return l; |
3621 | } | 3623 | } |
3622 | 3624 | ||
@@ -3662,17 +3664,26 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type, | |||
3662 | sort(array, length, sizeof(pid_t), cmppid, NULL); | 3664 | sort(array, length, sizeof(pid_t), cmppid, NULL); |
3663 | if (type == CGROUP_FILE_PROCS) | 3665 | if (type == CGROUP_FILE_PROCS) |
3664 | length = pidlist_uniq(array, length); | 3666 | length = pidlist_uniq(array, length); |
3665 | l = cgroup_pidlist_find(cgrp, type); | 3667 | |
3668 | mutex_lock(&cgrp->pidlist_mutex); | ||
3669 | |||
3670 | l = cgroup_pidlist_find_create(cgrp, type); | ||
3666 | if (!l) { | 3671 | if (!l) { |
3672 | mutex_unlock(&cgrp->pidlist_mutex); | ||
3667 | pidlist_free(array); | 3673 | pidlist_free(array); |
3668 | return -ENOMEM; | 3674 | return -ENOMEM; |
3669 | } | 3675 | } |
3670 | /* store array, freeing old if necessary - lock already held */ | 3676 | |
3677 | /* store array, freeing old if necessary */ | ||
3678 | down_write(&l->rwsem); | ||
3671 | pidlist_free(l->list); | 3679 | pidlist_free(l->list); |
3672 | l->list = array; | 3680 | l->list = array; |
3673 | l->length = length; | 3681 | l->length = length; |
3674 | l->use_count++; | 3682 | l->use_count++; |
3675 | up_write(&l->rwsem); | 3683 | up_write(&l->rwsem); |
3684 | |||
3685 | mutex_unlock(&cgrp->pidlist_mutex); | ||
3686 | |||
3676 | *lp = l; | 3687 | *lp = l; |
3677 | return 0; | 3688 | return 0; |
3678 | } | 3689 | } |