[PATCH v21 001/100] eclone (1/11): Factor out code to allocate pidmap page
From: Oren Laadan <hidden>
Date: 2010-05-01 14:26:44
Also in:
linux-s390, linuxppc-dev, lkml
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Sukadev Bhattiprolu <redacted> To simplify alloc_pidmap(), move code to allocate a pid map page to a separate function. Changelog[v4]: - [Oren Laadan] Adapt to kernel 2.6.33-rc5 Changelog[v3]: - Earlier version of patchset called alloc_pidmap_page() from two places. But now its called from only one place. Even so, moving this code out into a separate function simplifies alloc_pidmap(). Changelog[v2]: - (Matt Helsley, Dave Hansen) Have alloc_pidmap_page() return -ENOMEM on error instead of -1. Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org Cc: linux-s390-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linuxppc-dev-mnsaURCQ41sdnm+yROfE0A@public.gmane.org Signed-off-by: Sukadev Bhattiprolu <redacted> Acked-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> Tested-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> Reviewed-by: Oren Laadan <redacted> --- kernel/pid.c | 41 ++++++++++++++++++++++++++--------------- 1 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/kernel/pid.c b/kernel/pid.c
index aebb30d..52a371a 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c@@ -122,6 +122,30 @@ static void free_pidmap(struct upid *upid) atomic_inc(&map->nr_free); } +static int alloc_pidmap_page(struct pidmap *map) +{ + void *page; + + if (likely(map->page)) + return 0; + + page = kzalloc(PAGE_SIZE, GFP_KERNEL); + /* + * Free the page if someone raced with us installing it: + */ + spin_lock_irq(&pidmap_lock); + if (!map->page) { + map->page = page; + page = NULL; + } + spin_unlock_irq(&pidmap_lock); + kfree(page); + if (unlikely(!map->page)) + return -1; + + return 0; +} + static int alloc_pidmap(struct pid_namespace *pid_ns) { int i, offset, max_scan, pid, last = pid_ns->last_pid;
@@ -134,22 +158,9 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) map = &pid_ns->pidmap[pid/BITS_PER_PAGE]; max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset; for (i = 0; i <= max_scan; ++i) { - if (unlikely(!map->page)) { - void *page = kzalloc(PAGE_SIZE, GFP_KERNEL); - /* - * Free the page if someone raced with us - * installing it: - */ - spin_lock_irq(&pidmap_lock); - if (!map->page) { - map->page = page; - page = NULL; - } - spin_unlock_irq(&pidmap_lock); - kfree(page); - if (unlikely(!map->page)) + if (unlikely(!map->page)) + if (alloc_pidmap_page(map) < 0) break; - } if (likely(atomic_read(&map->nr_free))) { do { if (!test_and_set_bit(offset, map->page)) {
--
1.6.3.3