aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLi Zefan <lizefan@huawei.com>2013-03-12 18:36:00 -0400
committerTejun Heo <tj@kernel.org>2013-03-12 18:36:00 -0400
commit6ee211ad0a22869af81eef10845922ac4dcb2d38 (patch)
tree7123b4fd50e0b67c7daf8d243f8b2542eea84e86 /kernel
parentd7eeac1913ff86a17f891cb4b73f03d4b94907d0 (diff)
cgroup: don't bother to resize pid array
When we open cgroup.procs, we'll allocate an buffer and store all tasks' tgid in it, and then duplicate entries will be stripped. If that results in a much smaller pid list, we'll re-allocate a smaller buffer. But we've already sucessfully allocated memory and reading the procs file is a short period and the memory will be freed very soon, so why bother to re-allocate memory. Signed-off-by: Li Zefan <lizefan@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c37
1 files changed, 3 insertions, 34 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 49297cbc134d..29c77a714731 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -3400,35 +3400,14 @@ static void pidlist_free(void *p)
3400 else 3400 else
3401 kfree(p); 3401 kfree(p);
3402} 3402}
3403static void *pidlist_resize(void *p, int newcount)
3404{
3405 void *newlist;
3406 /* note: if new alloc fails, old p will still be valid either way */
3407 if (is_vmalloc_addr(p)) {
3408 newlist = vmalloc(newcount * sizeof(pid_t));
3409 if (!newlist)
3410 return NULL;
3411 memcpy(newlist, p, newcount * sizeof(pid_t));
3412 vfree(p);
3413 } else {
3414 newlist = krealloc(p, newcount * sizeof(pid_t), GFP_KERNEL);
3415 }
3416 return newlist;
3417}
3418 3403
3419/* 3404/*
3420 * pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries 3405 * pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries
3421 * If the new stripped list is sufficiently smaller and there's enough memory 3406 * Returns the number of unique elements.
3422 * to allocate a new buffer, will let go of the unneeded memory. Returns the
3423 * number of unique elements.
3424 */ 3407 */
3425/* is the size difference enough that we should re-allocate the array? */ 3408static int pidlist_uniq(pid_t *list, int length)
3426#define PIDLIST_REALLOC_DIFFERENCE(old, new) ((old) - PAGE_SIZE >= (new))
3427static int pidlist_uniq(pid_t **p, int length)
3428{ 3409{
3429 int src, dest = 1; 3410 int src, dest = 1;
3430 pid_t *list = *p;
3431 pid_t *newlist;
3432 3411
3433 /* 3412 /*
3434 * we presume the 0th element is unique, so i starts at 1. trivial 3413 * we presume the 0th element is unique, so i starts at 1. trivial
@@ -3449,16 +3428,6 @@ static int pidlist_uniq(pid_t **p, int length)
3449 dest++; 3428 dest++;
3450 } 3429 }
3451after: 3430after:
3452 /*
3453 * if the length difference is large enough, we want to allocate a
3454 * smaller buffer to save memory. if this fails due to out of memory,
3455 * we'll just stay with what we've got.
3456 */
3457 if (PIDLIST_REALLOC_DIFFERENCE(length, dest)) {
3458 newlist = pidlist_resize(list, dest);
3459 if (newlist)
3460 *p = newlist;
3461 }
3462 return dest; 3431 return dest;
3463} 3432}
3464 3433
@@ -3554,7 +3523,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
3554 /* now sort & (if procs) strip out duplicates */ 3523 /* now sort & (if procs) strip out duplicates */
3555 sort(array, length, sizeof(pid_t), cmppid, NULL); 3524 sort(array, length, sizeof(pid_t), cmppid, NULL);
3556 if (type == CGROUP_FILE_PROCS) 3525 if (type == CGROUP_FILE_PROCS)
3557 length = pidlist_uniq(&array, length); 3526 length = pidlist_uniq(array, length);
3558 l = cgroup_pidlist_find(cgrp, type); 3527 l = cgroup_pidlist_find(cgrp, type);
3559 if (!l) { 3528 if (!l) {
3560 pidlist_free(array); 3529 pidlist_free(array);