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.h191
1 files changed, 127 insertions, 64 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 9f2a3751873a..1581ff235c7e 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -5,53 +5,22 @@
5#include <linux/slab.h> /* For kmalloc() */ 5#include <linux/slab.h> /* For kmalloc() */
6#include <linux/smp.h> 6#include <linux/smp.h>
7#include <linux/cpumask.h> 7#include <linux/cpumask.h>
8#include <linux/pfn.h>
8 9
9#include <asm/percpu.h> 10#include <asm/percpu.h>
10 11
11#ifdef CONFIG_SMP 12/* enough to cover all DEFINE_PER_CPUs in modules */
12#define DEFINE_PER_CPU(type, name) \
13 __attribute__((__section__(".data.percpu"))) \
14 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
15
16#ifdef MODULE
17#define SHARED_ALIGNED_SECTION ".data.percpu"
18#else
19#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned"
20#endif
21
22#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
23 __attribute__((__section__(SHARED_ALIGNED_SECTION))) \
24 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \
25 ____cacheline_aligned_in_smp
26
27#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
28 __attribute__((__section__(".data.percpu.page_aligned"))) \
29 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
30#else
31#define DEFINE_PER_CPU(type, name) \
32 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
33
34#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
35 DEFINE_PER_CPU(type, name)
36
37#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
38 DEFINE_PER_CPU(type, name)
39#endif
40
41#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
42#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
43
44/* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */
45#ifndef PERCPU_ENOUGH_ROOM
46#ifdef CONFIG_MODULES 13#ifdef CONFIG_MODULES
47#define PERCPU_MODULE_RESERVE 8192 14#define PERCPU_MODULE_RESERVE (8 << 10)
48#else 15#else
49#define PERCPU_MODULE_RESERVE 0 16#define PERCPU_MODULE_RESERVE 0
50#endif 17#endif
51 18
19#ifndef PERCPU_ENOUGH_ROOM
52#define PERCPU_ENOUGH_ROOM \ 20#define PERCPU_ENOUGH_ROOM \
53 (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE) 21 (ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \
54#endif /* PERCPU_ENOUGH_ROOM */ 22 PERCPU_MODULE_RESERVE)
23#endif
55 24
56/* 25/*
57 * Must be an lvalue. Since @var must be a simple identifier, 26 * Must be an lvalue. Since @var must be a simple identifier,
@@ -65,52 +34,146 @@
65 34
66#ifdef CONFIG_SMP 35#ifdef CONFIG_SMP
67 36
37#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
38
39/* minimum unit size, also is the maximum supported allocation size */
40#define PCPU_MIN_UNIT_SIZE PFN_ALIGN(64 << 10)
41
42/*
43 * PERCPU_DYNAMIC_RESERVE indicates the amount of free area to piggy
44 * back on the first chunk for dynamic percpu allocation if arch is
45 * manually allocating and mapping it for faster access (as a part of
46 * large page mapping for example).
47 *
48 * The following values give between one and two pages of free space
49 * after typical minimal boot (2-way SMP, single disk and NIC) with
50 * both defconfig and a distro config on x86_64 and 32. More
51 * intelligent way to determine this would be nice.
52 */
53#if BITS_PER_LONG > 32
54#define PERCPU_DYNAMIC_RESERVE (20 << 10)
55#else
56#define PERCPU_DYNAMIC_RESERVE (12 << 10)
57#endif
58
59extern void *pcpu_base_addr;
60
61typedef struct page * (*pcpu_get_page_fn_t)(unsigned int cpu, int pageno);
62typedef void (*pcpu_populate_pte_fn_t)(unsigned long addr);
63
64extern size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
65 size_t static_size, size_t reserved_size,
66 ssize_t dyn_size, ssize_t unit_size,
67 void *base_addr,
68 pcpu_populate_pte_fn_t populate_pte_fn);
69
70extern ssize_t __init pcpu_embed_first_chunk(
71 size_t static_size, size_t reserved_size,
72 ssize_t dyn_size, ssize_t unit_size);
73
74/*
75 * Use this to get to a cpu's version of the per-cpu object
76 * dynamically allocated. Non-atomic access to the current CPU's
77 * version should probably be combined with get_cpu()/put_cpu().
78 */
79#define per_cpu_ptr(ptr, cpu) SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)))
80
81extern void *__alloc_reserved_percpu(size_t size, size_t align);
82
83#else /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
84
68struct percpu_data { 85struct percpu_data {
69 void *ptrs[1]; 86 void *ptrs[1];
70}; 87};
71 88
72#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) 89#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata)
73/* 90
74 * Use this to get to a cpu's version of the per-cpu object dynamically 91#define per_cpu_ptr(ptr, cpu) \
75 * allocated. Non-atomic access to the current CPU's version should 92({ \
76 * probably be combined with get_cpu()/put_cpu(). 93 struct percpu_data *__p = __percpu_disguise(ptr); \
77 */ 94 (__typeof__(ptr))__p->ptrs[(cpu)]; \
78#define percpu_ptr(ptr, cpu) \
79({ \
80 struct percpu_data *__p = __percpu_disguise(ptr); \
81 (__typeof__(ptr))__p->ptrs[(cpu)]; \
82}) 95})
83 96
84extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); 97#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
85extern void percpu_free(void *__pdata); 98
99extern void *__alloc_percpu(size_t size, size_t align);
100extern void free_percpu(void *__pdata);
86 101
87#else /* CONFIG_SMP */ 102#else /* CONFIG_SMP */
88 103
89#define percpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) 104#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
90 105
91static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) 106static inline void *__alloc_percpu(size_t size, size_t align)
92{ 107{
93 return kzalloc(size, gfp); 108 /*
109 * Can't easily make larger alignment work with kmalloc. WARN
110 * on it. Larger alignment should only be used for module
111 * percpu sections on SMP for which this path isn't used.
112 */
113 WARN_ON_ONCE(align > SMP_CACHE_BYTES);
114 return kzalloc(size, GFP_KERNEL);
94} 115}
95 116
96static inline void percpu_free(void *__pdata) 117static inline void free_percpu(void *p)
97{ 118{
98 kfree(__pdata); 119 kfree(p);
99} 120}
100 121
101#endif /* CONFIG_SMP */ 122#endif /* CONFIG_SMP */
102 123
103#define percpu_alloc_mask(size, gfp, mask) \ 124#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \
104 __percpu_alloc_mask((size), (gfp), &(mask)) 125 __alignof__(type))
105 126
106#define percpu_alloc(size, gfp) percpu_alloc_mask((size), (gfp), cpu_online_map) 127/*
128 * Optional methods for optimized non-lvalue per-cpu variable access.
129 *
130 * @var can be a percpu variable or a field of it and its size should
131 * equal char, int or long. percpu_read() evaluates to a lvalue and
132 * all others to void.
133 *
134 * These operations are guaranteed to be atomic w.r.t. preemption.
135 * The generic versions use plain get/put_cpu_var(). Archs are
136 * encouraged to implement single-instruction alternatives which don't
137 * require preemption protection.
138 */
139#ifndef percpu_read
140# define percpu_read(var) \
141 ({ \
142 typeof(per_cpu_var(var)) __tmp_var__; \
143 __tmp_var__ = get_cpu_var(var); \
144 put_cpu_var(var); \
145 __tmp_var__; \
146 })
147#endif
107 148
108/* (legacy) interface for use without CPU hotplug handling */ 149#define __percpu_generic_to_op(var, val, op) \
150do { \
151 get_cpu_var(var) op val; \
152 put_cpu_var(var); \
153} while (0)
109 154
110#define __alloc_percpu(size) percpu_alloc_mask((size), GFP_KERNEL, \ 155#ifndef percpu_write
111 cpu_possible_map) 156# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =)
112#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type)) 157#endif
113#define free_percpu(ptr) percpu_free((ptr)) 158
114#define per_cpu_ptr(ptr, cpu) percpu_ptr((ptr), (cpu)) 159#ifndef percpu_add
160# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=)
161#endif
162
163#ifndef percpu_sub
164# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=)
165#endif
166
167#ifndef percpu_and
168# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=)
169#endif
170
171#ifndef percpu_or
172# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=)
173#endif
174
175#ifndef percpu_xor
176# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=)
177#endif
115 178
116#endif /* __LINUX_PERCPU_H */ 179#endif /* __LINUX_PERCPU_H */