aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/percpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/percpu.h')
-rw-r--r--include/linux/percpu.h88
1 files changed, 75 insertions, 13 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 26fd9d12f050..878836ca999c 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -34,7 +34,7 @@
34 34
35#ifdef CONFIG_SMP 35#ifdef CONFIG_SMP
36 36
37#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA 37#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
38 38
39/* minimum unit size, also is the maximum supported allocation size */ 39/* minimum unit size, also is the maximum supported allocation size */
40#define PCPU_MIN_UNIT_SIZE PFN_ALIGN(64 << 10) 40#define PCPU_MIN_UNIT_SIZE PFN_ALIGN(64 << 10)
@@ -57,19 +57,70 @@
57#endif 57#endif
58 58
59extern void *pcpu_base_addr; 59extern void *pcpu_base_addr;
60extern const unsigned long *pcpu_unit_offsets;
60 61
61typedef struct page * (*pcpu_get_page_fn_t)(unsigned int cpu, int pageno); 62struct pcpu_group_info {
62typedef void (*pcpu_populate_pte_fn_t)(unsigned long addr); 63 int nr_units; /* aligned # of units */
64 unsigned long base_offset; /* base address offset */
65 unsigned int *cpu_map; /* unit->cpu map, empty
66 * entries contain NR_CPUS */
67};
68
69struct pcpu_alloc_info {
70 size_t static_size;
71 size_t reserved_size;
72 size_t dyn_size;
73 size_t unit_size;
74 size_t atom_size;
75 size_t alloc_size;
76 size_t __ai_size; /* internal, don't use */
77 int nr_groups; /* 0 if grouping unnecessary */
78 struct pcpu_group_info groups[];
79};
63 80
64extern size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn, 81enum pcpu_fc {
65 size_t static_size, size_t reserved_size, 82 PCPU_FC_AUTO,
66 ssize_t dyn_size, ssize_t unit_size, 83 PCPU_FC_EMBED,
67 void *base_addr, 84 PCPU_FC_PAGE,
68 pcpu_populate_pte_fn_t populate_pte_fn);
69 85
70extern ssize_t __init pcpu_embed_first_chunk( 86 PCPU_FC_NR,
71 size_t static_size, size_t reserved_size, 87};
72 ssize_t dyn_size, ssize_t unit_size); 88extern const char *pcpu_fc_names[PCPU_FC_NR];
89
90extern enum pcpu_fc pcpu_chosen_fc;
91
92typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size,
93 size_t align);
94typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size);
95typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr);
96typedef int (pcpu_fc_cpu_distance_fn_t)(unsigned int from, unsigned int to);
97
98extern struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups,
99 int nr_units);
100extern void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai);
101
102extern struct pcpu_alloc_info * __init pcpu_build_alloc_info(
103 size_t reserved_size, ssize_t dyn_size,
104 size_t atom_size,
105 pcpu_fc_cpu_distance_fn_t cpu_distance_fn);
106
107extern int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
108 void *base_addr);
109
110#ifdef CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK
111extern int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
112 size_t atom_size,
113 pcpu_fc_cpu_distance_fn_t cpu_distance_fn,
114 pcpu_fc_alloc_fn_t alloc_fn,
115 pcpu_fc_free_fn_t free_fn);
116#endif
117
118#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
119extern int __init pcpu_page_first_chunk(size_t reserved_size,
120 pcpu_fc_alloc_fn_t alloc_fn,
121 pcpu_fc_free_fn_t free_fn,
122 pcpu_fc_populate_pte_fn_t populate_pte_fn);
123#endif
73 124
74/* 125/*
75 * Use this to get to a cpu's version of the per-cpu object 126 * Use this to get to a cpu's version of the per-cpu object
@@ -80,7 +131,7 @@ extern ssize_t __init pcpu_embed_first_chunk(
80 131
81extern void *__alloc_reserved_percpu(size_t size, size_t align); 132extern void *__alloc_reserved_percpu(size_t size, size_t align);
82 133
83#else /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ 134#else /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */
84 135
85struct percpu_data { 136struct percpu_data {
86 void *ptrs[1]; 137 void *ptrs[1];
@@ -99,11 +150,15 @@ struct percpu_data {
99 (__typeof__(ptr))__p->ptrs[(cpu)]; \ 150 (__typeof__(ptr))__p->ptrs[(cpu)]; \
100}) 151})
101 152
102#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ 153#endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */
103 154
104extern void *__alloc_percpu(size_t size, size_t align); 155extern void *__alloc_percpu(size_t size, size_t align);
105extern void free_percpu(void *__pdata); 156extern void free_percpu(void *__pdata);
106 157
158#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
159extern void __init setup_per_cpu_areas(void);
160#endif
161
107#else /* CONFIG_SMP */ 162#else /* CONFIG_SMP */
108 163
109#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) 164#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
@@ -124,6 +179,13 @@ static inline void free_percpu(void *p)
124 kfree(p); 179 kfree(p);
125} 180}
126 181
182static inline void __init setup_per_cpu_areas(void) { }
183
184static inline void *pcpu_lpage_remapped(void *kaddr)
185{
186 return NULL;
187}
188
127#endif /* CONFIG_SMP */ 189#endif /* CONFIG_SMP */
128 190
129#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ 191#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \