diff options
-rw-r--r-- | include/linux/percpu.h | 47 | ||||
-rw-r--r-- | mm/allocpercpu.c | 32 |
2 files changed, 41 insertions, 38 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 1fdaee93c04d..d99e24ae1811 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -82,46 +82,43 @@ struct percpu_data { | |||
82 | 82 | ||
83 | #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) | 83 | #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) |
84 | 84 | ||
85 | extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); | 85 | /* |
86 | extern void percpu_free(void *__pdata); | 86 | * Use this to get to a cpu's version of the per-cpu object |
87 | * dynamically allocated. Non-atomic access to the current CPU's | ||
88 | * version should probably be combined with get_cpu()/put_cpu(). | ||
89 | */ | ||
90 | #define per_cpu_ptr(ptr, cpu) \ | ||
91 | ({ \ | ||
92 | struct percpu_data *__p = __percpu_disguise(ptr); \ | ||
93 | (__typeof__(ptr))__p->ptrs[(cpu)]; \ | ||
94 | }) | ||
95 | |||
96 | extern void *__alloc_percpu(size_t size, size_t align); | ||
97 | extern void free_percpu(void *__pdata); | ||
87 | 98 | ||
88 | #else /* CONFIG_SMP */ | 99 | #else /* CONFIG_SMP */ |
89 | 100 | ||
90 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) | 101 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) |
91 | 102 | ||
92 | static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) | 103 | static inline void *__alloc_percpu(size_t size, size_t align) |
93 | { | 104 | { |
105 | /* | ||
106 | * Can't easily make larger alignment work with kmalloc. WARN | ||
107 | * on it. Larger alignment should only be used for module | ||
108 | * percpu sections on SMP for which this path isn't used. | ||
109 | */ | ||
110 | WARN_ON_ONCE(align > __alignof__(unsigned long long)); | ||
94 | return kzalloc(size, gfp); | 111 | return kzalloc(size, gfp); |
95 | } | 112 | } |
96 | 113 | ||
97 | static inline void percpu_free(void *__pdata) | 114 | static inline void free_percpu(void *p) |
98 | { | 115 | { |
99 | kfree(__pdata); | 116 | kfree(p); |
100 | } | 117 | } |
101 | 118 | ||
102 | #endif /* CONFIG_SMP */ | 119 | #endif /* CONFIG_SMP */ |
103 | 120 | ||
104 | #define percpu_alloc_mask(size, gfp, mask) \ | ||
105 | __percpu_alloc_mask((size), (gfp), &(mask)) | ||
106 | |||
107 | #define percpu_alloc(size, gfp) percpu_alloc_mask((size), (gfp), cpu_online_map) | ||
108 | |||
109 | /* (legacy) interface for use without CPU hotplug handling */ | ||
110 | |||
111 | #define __alloc_percpu(size, align) percpu_alloc_mask((size), GFP_KERNEL, \ | ||
112 | cpu_possible_map) | ||
113 | #define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ | 121 | #define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ |
114 | __alignof__(type)) | 122 | __alignof__(type)) |
115 | #define free_percpu(ptr) percpu_free((ptr)) | ||
116 | /* | ||
117 | * Use this to get to a cpu's version of the per-cpu object dynamically | ||
118 | * allocated. Non-atomic access to the current CPU's version should | ||
119 | * probably be combined with get_cpu()/put_cpu(). | ||
120 | */ | ||
121 | #define per_cpu_ptr(ptr, cpu) \ | ||
122 | ({ \ | ||
123 | struct percpu_data *__p = __percpu_disguise(ptr); \ | ||
124 | (__typeof__(ptr))__p->ptrs[(cpu)]; \ | ||
125 | }) | ||
126 | 123 | ||
127 | #endif /* __LINUX_PERCPU_H */ | 124 | #endif /* __LINUX_PERCPU_H */ |
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 4297bc41bfd2..3653c570232b 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c | |||
@@ -99,45 +99,51 @@ static int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, | |||
99 | __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) | 99 | __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * percpu_alloc_mask - initial setup of per-cpu data | 102 | * alloc_percpu - initial setup of per-cpu data |
103 | * @size: size of per-cpu object | 103 | * @size: size of per-cpu object |
104 | * @gfp: may sleep or not etc. | 104 | * @align: alignment |
105 | * @mask: populate per-data for cpu's selected through mask bits | ||
106 | * | 105 | * |
107 | * Populating per-cpu data for all online cpu's would be a typical use case, | 106 | * Allocate dynamic percpu area. Percpu objects are populated with |
108 | * which is simplified by the percpu_alloc() wrapper. | 107 | * zeroed buffers. |
109 | * Per-cpu objects are populated with zeroed buffers. | ||
110 | */ | 108 | */ |
111 | void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) | 109 | void *__alloc_percpu(size_t size, size_t align) |
112 | { | 110 | { |
113 | /* | 111 | /* |
114 | * We allocate whole cache lines to avoid false sharing | 112 | * We allocate whole cache lines to avoid false sharing |
115 | */ | 113 | */ |
116 | size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); | 114 | size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); |
117 | void *pdata = kzalloc(sz, gfp); | 115 | void *pdata = kzalloc(sz, GFP_KERNEL); |
118 | void *__pdata = __percpu_disguise(pdata); | 116 | void *__pdata = __percpu_disguise(pdata); |
119 | 117 | ||
118 | /* | ||
119 | * Can't easily make larger alignment work with kmalloc. WARN | ||
120 | * on it. Larger alignment should only be used for module | ||
121 | * percpu sections on SMP for which this path isn't used. | ||
122 | */ | ||
123 | WARN_ON_ONCE(align > __alignof__(unsigned long long)); | ||
124 | |||
120 | if (unlikely(!pdata)) | 125 | if (unlikely(!pdata)) |
121 | return NULL; | 126 | return NULL; |
122 | if (likely(!__percpu_populate_mask(__pdata, size, gfp, mask))) | 127 | if (likely(!__percpu_populate_mask(__pdata, size, GFP_KERNEL, |
128 | &cpu_possible_map))) | ||
123 | return __pdata; | 129 | return __pdata; |
124 | kfree(pdata); | 130 | kfree(pdata); |
125 | return NULL; | 131 | return NULL; |
126 | } | 132 | } |
127 | EXPORT_SYMBOL_GPL(__percpu_alloc_mask); | 133 | EXPORT_SYMBOL_GPL(__alloc_percpu); |
128 | 134 | ||
129 | /** | 135 | /** |
130 | * percpu_free - final cleanup of per-cpu data | 136 | * free_percpu - final cleanup of per-cpu data |
131 | * @__pdata: object to clean up | 137 | * @__pdata: object to clean up |
132 | * | 138 | * |
133 | * We simply clean up any per-cpu object left. No need for the client to | 139 | * We simply clean up any per-cpu object left. No need for the client to |
134 | * track and specify through a bis mask which per-cpu objects are to free. | 140 | * track and specify through a bis mask which per-cpu objects are to free. |
135 | */ | 141 | */ |
136 | void percpu_free(void *__pdata) | 142 | void free_percpu(void *__pdata) |
137 | { | 143 | { |
138 | if (unlikely(!__pdata)) | 144 | if (unlikely(!__pdata)) |
139 | return; | 145 | return; |
140 | __percpu_depopulate_mask(__pdata, &cpu_possible_map); | 146 | __percpu_depopulate_mask(__pdata, &cpu_possible_map); |
141 | kfree(__percpu_disguise(__pdata)); | 147 | kfree(__percpu_disguise(__pdata)); |
142 | } | 148 | } |
143 | EXPORT_SYMBOL_GPL(percpu_free); | 149 | EXPORT_SYMBOL_GPL(free_percpu); |