1 #include <linux/types.h>
2 #include <linux/kernel.h>
3 #include <linux/kallsyms.h>
4 #include <linux/init.h>
5 #include <linux/bootmem.h>
8 void __init
pre_alloc_dyn_array(void)
10 #ifdef CONFIG_HAVE_DYN_ARRAY
11 unsigned long total_size
= 0, size
, phys
;
12 unsigned long max_align
= 1;
13 struct dyn_array
**daa
;
16 /* get the total size at first */
17 for (daa
= __dyn_array_start
; daa
< __dyn_array_end
; daa
++) {
18 struct dyn_array
*da
= *daa
;
20 printk(KERN_DEBUG
"dyn_array %pF size:%#lx nr:%d align:%#lx\n",
21 da
->name
, da
->size
, *da
->nr
, da
->align
);
22 size
= da
->size
* (*da
->nr
);
23 total_size
+= roundup(size
, da
->align
);
24 if (da
->align
> max_align
)
25 max_align
= da
->align
;
28 printk(KERN_DEBUG
"dyn_array total_size: %#lx\n",
33 /* allocate them all together */
34 max_align
= max_t(unsigned long, max_align
, PAGE_SIZE
);
35 ptr
= __alloc_bootmem(total_size
, max_align
, 0);
36 phys
= virt_to_phys(ptr
);
38 for (daa
= __dyn_array_start
; daa
< __dyn_array_end
; daa
++) {
39 struct dyn_array
*da
= *daa
;
41 size
= da
->size
* (*da
->nr
);
42 phys
= roundup(phys
, da
->align
);
43 printk(KERN_DEBUG
"dyn_array %pF ==> [%#lx - %#lx]\n",
44 da
->name
, phys
, phys
+ size
);
45 *da
->name
= phys_to_virt(phys
);
53 #ifdef CONFIG_GENERIC_HARDIRQS
56 for (i
= 0; i
< NR_IRQS
; i
++)
62 unsigned long __init
per_cpu_dyn_array_size(unsigned long *align
)
64 unsigned long total_size
= 0;
65 #ifdef CONFIG_HAVE_DYN_ARRAY
67 struct dyn_array
**daa
;
68 unsigned max_align
= 1;
70 for (daa
= __per_cpu_dyn_array_start
; daa
< __per_cpu_dyn_array_end
; daa
++) {
71 struct dyn_array
*da
= *daa
;
73 printk(KERN_DEBUG
"per_cpu_dyn_array %pF size:%#lx nr:%d align:%#lx\n",
74 da
->name
, da
->size
, *da
->nr
, da
->align
);
75 size
= da
->size
* (*da
->nr
);
76 total_size
+= roundup(size
, da
->align
);
77 if (da
->align
> max_align
)
78 max_align
= da
->align
;
81 printk(KERN_DEBUG
"per_cpu_dyn_array total_size: %#lx\n",
90 void __init
per_cpu_alloc_dyn_array(int cpu
, char *ptr
)
92 #ifdef CONFIG_HAVE_DYN_ARRAY
93 unsigned long size
, phys
;
94 struct dyn_array
**daa
;
98 phys
= virt_to_phys(ptr
);
99 for (daa
= __per_cpu_dyn_array_start
; daa
< __per_cpu_dyn_array_end
; daa
++) {
100 struct dyn_array
*da
= *daa
;
102 size
= da
->size
* (*da
->nr
);
103 phys
= roundup(phys
, da
->align
);
104 printk(KERN_DEBUG
"per_cpu_dyn_array %pF ==> [%#lx - %#lx]\n",
105 da
->name
, phys
, phys
+ size
);
107 addr
= (unsigned long)da
->name
;
108 addr
+= per_cpu_offset(cpu
);
109 array
= (void **)addr
;
110 *array
= phys_to_virt(phys
);
111 *da
->name
= *array
; /* so init_work could use it directly */