diff options
author | Tejun Heo <tj@kernel.org> | 2009-02-20 02:29:08 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-02-20 02:29:08 -0500 |
commit | fbf59bc9d74d1fb30b8e0630743aff2806eafcea (patch) | |
tree | 3f0a7b7cf809a25e27b7a5ba0b16321fdb901801 /kernel | |
parent | 8fc48985006da4ceba24508db64ec77fc0dfe3bb (diff) |
percpu: implement new dynamic percpu allocator
Impact: new scalable dynamic percpu allocator which allows dynamic
percpu areas to be accessed the same way as static ones
Implement scalable dynamic percpu allocator which can be used for both
static and dynamic percpu areas. This will allow static and dynamic
areas to share faster direct access methods. This feature is optional
and enabled only when CONFIG_HAVE_DYNAMIC_PER_CPU_AREA is defined by
arch. Please read comment on top of mm/percpu.c for details.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c index 52b3497b8748..1f0657ae555b 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/tracepoint.h> | 51 | #include <linux/tracepoint.h> |
52 | #include <linux/ftrace.h> | 52 | #include <linux/ftrace.h> |
53 | #include <linux/async.h> | 53 | #include <linux/async.h> |
54 | #include <linux/percpu.h> | ||
54 | 55 | ||
55 | #if 0 | 56 | #if 0 |
56 | #define DEBUGP printk | 57 | #define DEBUGP printk |
@@ -366,6 +367,34 @@ static struct module *find_module(const char *name) | |||
366 | } | 367 | } |
367 | 368 | ||
368 | #ifdef CONFIG_SMP | 369 | #ifdef CONFIG_SMP |
370 | |||
371 | #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA | ||
372 | |||
373 | static void *percpu_modalloc(unsigned long size, unsigned long align, | ||
374 | const char *name) | ||
375 | { | ||
376 | void *ptr; | ||
377 | |||
378 | if (align > PAGE_SIZE) { | ||
379 | printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", | ||
380 | name, align, PAGE_SIZE); | ||
381 | align = PAGE_SIZE; | ||
382 | } | ||
383 | |||
384 | ptr = __alloc_percpu(size, align); | ||
385 | if (!ptr) | ||
386 | printk(KERN_WARNING | ||
387 | "Could not allocate %lu bytes percpu data\n", size); | ||
388 | return ptr; | ||
389 | } | ||
390 | |||
391 | static void percpu_modfree(void *freeme) | ||
392 | { | ||
393 | free_percpu(freeme); | ||
394 | } | ||
395 | |||
396 | #else /* ... !CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | ||
397 | |||
369 | /* Number of blocks used and allocated. */ | 398 | /* Number of blocks used and allocated. */ |
370 | static unsigned int pcpu_num_used, pcpu_num_allocated; | 399 | static unsigned int pcpu_num_used, pcpu_num_allocated; |
371 | /* Size of each block. -ve means used. */ | 400 | /* Size of each block. -ve means used. */ |
@@ -499,6 +528,8 @@ static int percpu_modinit(void) | |||
499 | } | 528 | } |
500 | __initcall(percpu_modinit); | 529 | __initcall(percpu_modinit); |
501 | 530 | ||
531 | #endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | ||
532 | |||
502 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | 533 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, |
503 | Elf_Shdr *sechdrs, | 534 | Elf_Shdr *sechdrs, |
504 | const char *secstrings) | 535 | const char *secstrings) |