From: Paul Menage <menage@google.com>
To: akpm@linux-foundation.org, bblum@andrew.cmu.edu, lizf@cn.fujitsu.com
Cc: linux-kernel@vger.kernel.org, containers@lists.linux-foundation.org
Subject: [PATCH 4/8] Use vmalloc for large cgroups pidlist allocations
Date: Tue, 18 Aug 2009 16:58:27 -0700 [thread overview]
Message-ID: <20090818235827.22531.60306.stgit@menage.mtv.corp.google.com> (raw)
In-Reply-To: <20090818235059.22531.42618.stgit@menage.mtv.corp.google.com>
From: Ben Blum <bblum@google.com>
Use vmalloc for large cgroups pidlist allocations
Separates all pidlist allocation requests to a separate function that judges
based on the requested size whether or not the array needs to be vmalloced or
can be gotten via kmalloc, and similar for kfree/vfree.
Signed-off-by: Ben Blum <bblum@google.com>
Signed-off-by: Paul Menage <menage@google.com>
---
kernel/cgroup.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index d207871..7e2b285 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -50,6 +50,7 @@
#include <linux/smp_lock.h>
#include <linux/pid_namespace.h>
#include <linux/idr.h>
+#include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
#include <asm/atomic.h>
@@ -2351,6 +2352,42 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan)
*/
/*
+ * The following two functions "fix" the issue where there are more pids
+ * than kmalloc will give memory for; in such cases, we use vmalloc/vfree.
+ * TODO: replace with a kernel-wide solution to this problem
+ */
+#define PIDLIST_TOO_LARGE(c) ((c) * sizeof(pid_t) > (PAGE_SIZE * 2))
+static void *pidlist_allocate(int count)
+{
+ if (PIDLIST_TOO_LARGE(count))
+ return vmalloc(count * sizeof(pid_t));
+ else
+ return kmalloc(count * sizeof(pid_t), GFP_KERNEL);
+}
+static void pidlist_free(void *p)
+{
+ if (is_vmalloc_addr(p))
+ vfree(p);
+ else
+ kfree(p);
+}
+static void *pidlist_resize(void *p, int newcount)
+{
+ void *newlist;
+ /* note: if new alloc fails, old p will still be valid either way */
+ if (is_vmalloc_addr(p)) {
+ newlist = vmalloc(newcount * sizeof(pid_t));
+ if (!newlist)
+ return NULL;
+ memcpy(newlist, p, newcount * sizeof(pid_t));
+ vfree(p);
+ } else {
+ newlist = krealloc(p, newcount * sizeof(pid_t), GFP_KERNEL);
+ }
+ return newlist;
+}
+
+/*
* pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries
* If the new stripped list is sufficiently smaller and there's enough memory
* to allocate a new buffer, will let go of the unneeded memory. Returns the
@@ -2389,7 +2426,7 @@ after:
* we'll just stay with what we've got.
*/
if (PIDLIST_REALLOC_DIFFERENCE(length, dest)) {
- newlist = krealloc(list, dest * sizeof(pid_t), GFP_KERNEL);
+ newlist = pidlist_resize(list, dest);
if (newlist)
*p = newlist;
}
@@ -2470,7 +2507,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
* show up until sometime later on.
*/
length = cgroup_task_count(cgrp);
- array = kmalloc(length * sizeof(pid_t), GFP_KERNEL);
+ array = pidlist_allocate(length);
if (!array)
return -ENOMEM;
/* now, populate the array */
@@ -2494,11 +2531,11 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
length = pidlist_uniq(&array, length);
l = cgroup_pidlist_find(cgrp, type);
if (!l) {
- kfree(array);
+ pidlist_free(array);
return -ENOMEM;
}
/* store array, freeing old if necessary - lock already held */
- kfree(l->list);
+ pidlist_free(l->list);
l->list = array;
l->length = length;
l->use_count++;
@@ -2659,7 +2696,7 @@ static void cgroup_release_pid_array(struct cgroup_pidlist *l)
/* we're the last user if refcount is 0; remove and free */
list_del(&l->links);
mutex_unlock(&l->owner->pidlist_mutex);
- kfree(l->list);
+ pidlist_free(l->list);
put_pid_ns(l->key.ns);
up_write(&l->mutex);
kfree(l);
next prev parent reply other threads:[~2009-08-18 23:58 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-18 23:58 [PATCH 0/8] CGroups: cgroup memberlist enhancements/fixes Paul Menage
2009-08-18 23:58 ` [PATCH 1/8] Revert commit 8827c288feb7810185aa7c2e37537202fc709869 Paul Menage
2009-08-20 2:34 ` Li Zefan
2009-08-20 2:41 ` Paul Menage
2009-08-20 3:11 ` Li Zefan
2009-08-20 3:13 ` Paul Menage
2009-08-20 3:17 ` Li Zefan
2009-08-20 4:40 ` Matt Helsley
2009-08-20 4:49 ` Paul Menage
2009-08-20 21:13 ` Andrew Morton
2009-08-18 23:58 ` [PATCH 2/8] Adds a read-only "procs" file similar to "tasks" that shows only unique tgids Paul Menage
2009-08-20 2:34 ` Li Zefan
2009-08-18 23:58 ` [PATCH 3/8] Ensures correct concurrent opening/reading of pidlists across pid namespaces Paul Menage
2009-08-18 23:58 ` Paul Menage [this message]
2009-08-20 2:37 ` [PATCH 4/8] Use vmalloc for large cgroups pidlist allocations Li Zefan
2009-08-20 2:41 ` Paul Menage
2009-08-20 2:54 ` Li Zefan
2009-08-20 3:04 ` Paul Menage
2009-08-20 21:14 ` Andrew Morton
2009-08-20 22:35 ` Jonathan Corbet
2009-08-20 22:56 ` David Rientjes
2009-08-21 0:53 ` Li Zefan
2009-08-18 23:58 ` [PATCH 5/8] Changes css_set freeing mechanism to be under RCU Paul Menage
2009-08-20 2:38 ` Li Zefan
2009-08-18 23:58 ` [PATCH 6/8] Lets ss->can_attach and ss->attach do whole threadgroups at a time Paul Menage
2009-08-20 3:06 ` Li Zefan
2009-08-20 4:38 ` Matt Helsley
2009-08-18 23:58 ` [PATCH 7/8] Adds functionality to read/write lock CLONE_THREAD fork()ing per-threadgroup Paul Menage
2009-08-20 2:39 ` Li Zefan
2009-08-20 2:45 ` Paul Menage
2009-08-20 21:13 ` Andrew Morton
2009-08-20 21:16 ` Paul Menage
2009-08-21 4:24 ` Ben Blum
2009-08-21 4:50 ` Andrew Morton
2009-08-21 4:58 ` Paul Menage
2009-08-18 23:58 ` [PATCH 8/8] Adds ability to move all threads in a process to a new cgroup atomically Paul Menage
2009-08-20 3:00 ` Li Zefan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090818235827.22531.60306.stgit@menage.mtv.corp.google.com \
--to=menage@google.com \
--cc=akpm@linux-foundation.org \
--cc=bblum@andrew.cmu.edu \
--cc=containers@lists.linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®