aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 20:49:44 -0700
committerIngo Molnar <mingo@elte.hu>2008-10-16 16:52:03 +0200
commit1f3fcd4b1adc972d5c6a34cfed98931c46575b49 (patch)
treea79b6c656a09a8424863a0025d5b20e7264d6999 /include
parent3ddfda11861d305b02ed810b522dcf48b74ca808 (diff)
add per_cpu_dyn_array support
allow dyn-array in per_cpu area, allocated dynamically. usage: | /* in .h */ | struct kernel_stat { | struct cpu_usage_stat cpustat; | unsigned int *irqs; | }; | | /* in .c */ | DEFINE_PER_CPU(struct kernel_stat, kstat); | | DEFINE_PER_CPU_DYN_ARRAY_ADDR(per_cpu__kstat_irqs, per_cpu__kstat.irqs, sizeof(unsigned int), nr_irqs, sizeof(unsigned long), NULL); after setup_percpu()/per_cpu_alloc_dyn_array(), the dyn_array in per_cpu area is ready to use. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/vmlinux.lds.h6
-rw-r--r--include/linux/init.h27
2 files changed, 30 insertions, 3 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7881406c03e..c68eda9d9a9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -216,6 +216,12 @@
VMLINUX_SYMBOL(__dyn_array_start) = .; \
*(.dyn_array.init) \
VMLINUX_SYMBOL(__dyn_array_end) = .; \
+ } \
+ . = ALIGN((align)); \
+ .per_cpu_dyn_array.init : AT(ADDR(.per_cpu_dyn_array.init) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__per_cpu_dyn_array_start) = .; \
+ *(.per_cpu_dyn_array.init) \
+ VMLINUX_SYMBOL(__per_cpu_dyn_array_end) = .; \
}
#define SECURITY_INIT \
.security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
diff --git a/include/linux/init.h b/include/linux/init.h
index cf9fa7f174a..332806826b8 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -255,12 +255,13 @@ struct dyn_array {
void (*init_work)(void *);
};
extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[];
+extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[];
-#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+#define DEFINE_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \
static struct dyn_array __dyn_array_##nameX __initdata = \
- { .name = (void **)&nameX,\
+ { .name = (void **)&(nameX),\
.size = sizeX,\
- .nr = &nrX,\
+ .nr = &(nrX),\
.align = alignX,\
.init_work = init_workX,\
}; \
@@ -268,7 +269,27 @@ extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[];
__attribute__((__section__(".dyn_array.init"))) = \
&__dyn_array_##nameX
+#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+ DEFINE_DYN_ARRAY_ADDR(nameX, nameX, sizeX, nrX, alignX, init_workX)
+
+#define DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \
+ static struct dyn_array __per_cpu_dyn_array_##nameX __initdata = \
+ { .name = (void **)&(addrX),\
+ .size = sizeX,\
+ .nr = &(nrX),\
+ .align = alignX,\
+ .init_work = init_workX,\
+ }; \
+ static struct dyn_array *__per_cpu_dyn_array_ptr_##nameX __used \
+ __attribute__((__section__(".per_cpu_dyn_array.init"))) = \
+ &__per_cpu_dyn_array_##nameX
+
+#define DEFINE_PER_CPU_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+ DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX)
+
extern void pre_alloc_dyn_array(void);
+extern unsigned long per_cpu_dyn_array_size(void);
+extern void per_cpu_alloc_dyn_array(int cpu, char *ptr);
#endif /* __ASSEMBLY__ */
/**