diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-14 14:46:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-14 14:46:25 -0400 |
| commit | b6daa51b9a6a02a644dcf6b880fd50c1f70ec07f (patch) | |
| tree | 745ebeefb8f4225460774ef0037ca2f9022d4a4a /include/asm-generic | |
| parent | f96ed2612260a8a415512eed4fe3f5c77247d4a1 (diff) | |
| parent | 9b7396624a7b503220d85428654634b60762f2b0 (diff) | |
Merge branch 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
Pull percpu updates from Tejun Heo:
- Nick improved generic implementations of percpu operations which
modify the variable and return so that they calculate the physical
address only once.
- percpu_ref percpu <-> atomic mode switching improvements. The
patchset was originally posted about a year ago but fell through the
crack.
- misc non-critical fixes.
* 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu:
mm/percpu.c: fix potential memory leakage for pcpu_embed_first_chunk()
mm/percpu.c: correct max_distance calculation for pcpu_embed_first_chunk()
percpu: eliminate two sparse warnings
percpu: improve generic percpu modify-return implementation
percpu-refcount: init ->confirm_switch member properly
percpu_ref: allow operation mode switching operations to be called concurrently
percpu_ref: restructure operation mode switching
percpu_ref: unify staggered atomic switching wait behavior
percpu_ref: reorganize __percpu_ref_switch_to_atomic() and relocate percpu_ref_switch_to_atomic()
percpu_ref: remove unnecessary RCU grace period for staggered atomic switching confirmation
Diffstat (limited to 'include/asm-generic')
| -rw-r--r-- | include/asm-generic/percpu.h | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4d9f233c4ba8..40e887068da2 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h | |||
| @@ -65,6 +65,11 @@ extern void setup_per_cpu_areas(void); | |||
| 65 | #define PER_CPU_DEF_ATTRIBUTES | 65 | #define PER_CPU_DEF_ATTRIBUTES |
| 66 | #endif | 66 | #endif |
| 67 | 67 | ||
| 68 | #define raw_cpu_generic_read(pcp) \ | ||
| 69 | ({ \ | ||
| 70 | *raw_cpu_ptr(&(pcp)); \ | ||
| 71 | }) | ||
| 72 | |||
| 68 | #define raw_cpu_generic_to_op(pcp, val, op) \ | 73 | #define raw_cpu_generic_to_op(pcp, val, op) \ |
| 69 | do { \ | 74 | do { \ |
| 70 | *raw_cpu_ptr(&(pcp)) op val; \ | 75 | *raw_cpu_ptr(&(pcp)) op val; \ |
| @@ -72,34 +77,39 @@ do { \ | |||
| 72 | 77 | ||
| 73 | #define raw_cpu_generic_add_return(pcp, val) \ | 78 | #define raw_cpu_generic_add_return(pcp, val) \ |
| 74 | ({ \ | 79 | ({ \ |
| 75 | raw_cpu_add(pcp, val); \ | 80 | typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ |
| 76 | raw_cpu_read(pcp); \ | 81 | \ |
| 82 | *__p += val; \ | ||
| 83 | *__p; \ | ||
| 77 | }) | 84 | }) |
| 78 | 85 | ||
| 79 | #define raw_cpu_generic_xchg(pcp, nval) \ | 86 | #define raw_cpu_generic_xchg(pcp, nval) \ |
| 80 | ({ \ | 87 | ({ \ |
| 88 | typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ | ||
| 81 | typeof(pcp) __ret; \ | 89 | typeof(pcp) __ret; \ |
| 82 | __ret = raw_cpu_read(pcp); \ | 90 | __ret = *__p; \ |
| 83 | raw_cpu_write(pcp, nval); \ | 91 | *__p = nval; \ |
| 84 | __ret; \ | 92 | __ret; \ |
| 85 | }) | 93 | }) |
| 86 | 94 | ||
| 87 | #define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ | 95 | #define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ |
| 88 | ({ \ | 96 | ({ \ |
| 97 | typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ | ||
| 89 | typeof(pcp) __ret; \ | 98 | typeof(pcp) __ret; \ |
| 90 | __ret = raw_cpu_read(pcp); \ | 99 | __ret = *__p; \ |
| 91 | if (__ret == (oval)) \ | 100 | if (__ret == (oval)) \ |
| 92 | raw_cpu_write(pcp, nval); \ | 101 | *__p = nval; \ |
| 93 | __ret; \ | 102 | __ret; \ |
| 94 | }) | 103 | }) |
| 95 | 104 | ||
| 96 | #define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | 105 | #define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ |
| 97 | ({ \ | 106 | ({ \ |
| 107 | typeof(&(pcp1)) __p1 = raw_cpu_ptr(&(pcp1)); \ | ||
| 108 | typeof(&(pcp2)) __p2 = raw_cpu_ptr(&(pcp2)); \ | ||
| 98 | int __ret = 0; \ | 109 | int __ret = 0; \ |
| 99 | if (raw_cpu_read(pcp1) == (oval1) && \ | 110 | if (*__p1 == (oval1) && *__p2 == (oval2)) { \ |
| 100 | raw_cpu_read(pcp2) == (oval2)) { \ | 111 | *__p1 = nval1; \ |
| 101 | raw_cpu_write(pcp1, nval1); \ | 112 | *__p2 = nval2; \ |
| 102 | raw_cpu_write(pcp2, nval2); \ | ||
| 103 | __ret = 1; \ | 113 | __ret = 1; \ |
| 104 | } \ | 114 | } \ |
| 105 | (__ret); \ | 115 | (__ret); \ |
| @@ -109,7 +119,7 @@ do { \ | |||
| 109 | ({ \ | 119 | ({ \ |
| 110 | typeof(pcp) __ret; \ | 120 | typeof(pcp) __ret; \ |
| 111 | preempt_disable(); \ | 121 | preempt_disable(); \ |
| 112 | __ret = *this_cpu_ptr(&(pcp)); \ | 122 | __ret = raw_cpu_generic_read(pcp); \ |
| 113 | preempt_enable(); \ | 123 | preempt_enable(); \ |
| 114 | __ret; \ | 124 | __ret; \ |
| 115 | }) | 125 | }) |
| @@ -118,17 +128,17 @@ do { \ | |||
| 118 | do { \ | 128 | do { \ |
| 119 | unsigned long __flags; \ | 129 | unsigned long __flags; \ |
| 120 | raw_local_irq_save(__flags); \ | 130 | raw_local_irq_save(__flags); \ |
| 121 | *raw_cpu_ptr(&(pcp)) op val; \ | 131 | raw_cpu_generic_to_op(pcp, val, op); \ |
| 122 | raw_local_irq_restore(__flags); \ | 132 | raw_local_irq_restore(__flags); \ |
| 123 | } while (0) | 133 | } while (0) |
| 124 | 134 | ||
| 135 | |||
| 125 | #define this_cpu_generic_add_return(pcp, val) \ | 136 | #define this_cpu_generic_add_return(pcp, val) \ |
| 126 | ({ \ | 137 | ({ \ |
| 127 | typeof(pcp) __ret; \ | 138 | typeof(pcp) __ret; \ |
| 128 | unsigned long __flags; \ | 139 | unsigned long __flags; \ |
| 129 | raw_local_irq_save(__flags); \ | 140 | raw_local_irq_save(__flags); \ |
| 130 | raw_cpu_add(pcp, val); \ | 141 | __ret = raw_cpu_generic_add_return(pcp, val); \ |
| 131 | __ret = raw_cpu_read(pcp); \ | ||
| 132 | raw_local_irq_restore(__flags); \ | 142 | raw_local_irq_restore(__flags); \ |
| 133 | __ret; \ | 143 | __ret; \ |
| 134 | }) | 144 | }) |
| @@ -138,8 +148,7 @@ do { \ | |||
| 138 | typeof(pcp) __ret; \ | 148 | typeof(pcp) __ret; \ |
| 139 | unsigned long __flags; \ | 149 | unsigned long __flags; \ |
| 140 | raw_local_irq_save(__flags); \ | 150 | raw_local_irq_save(__flags); \ |
| 141 | __ret = raw_cpu_read(pcp); \ | 151 | __ret = raw_cpu_generic_xchg(pcp, nval); \ |
| 142 | raw_cpu_write(pcp, nval); \ | ||
| 143 | raw_local_irq_restore(__flags); \ | 152 | raw_local_irq_restore(__flags); \ |
| 144 | __ret; \ | 153 | __ret; \ |
| 145 | }) | 154 | }) |
| @@ -149,9 +158,7 @@ do { \ | |||
| 149 | typeof(pcp) __ret; \ | 158 | typeof(pcp) __ret; \ |
| 150 | unsigned long __flags; \ | 159 | unsigned long __flags; \ |
| 151 | raw_local_irq_save(__flags); \ | 160 | raw_local_irq_save(__flags); \ |
| 152 | __ret = raw_cpu_read(pcp); \ | 161 | __ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \ |
| 153 | if (__ret == (oval)) \ | ||
| 154 | raw_cpu_write(pcp, nval); \ | ||
| 155 | raw_local_irq_restore(__flags); \ | 162 | raw_local_irq_restore(__flags); \ |
| 156 | __ret; \ | 163 | __ret; \ |
| 157 | }) | 164 | }) |
| @@ -168,16 +175,16 @@ do { \ | |||
| 168 | }) | 175 | }) |
| 169 | 176 | ||
| 170 | #ifndef raw_cpu_read_1 | 177 | #ifndef raw_cpu_read_1 |
| 171 | #define raw_cpu_read_1(pcp) (*raw_cpu_ptr(&(pcp))) | 178 | #define raw_cpu_read_1(pcp) raw_cpu_generic_read(pcp) |
| 172 | #endif | 179 | #endif |
| 173 | #ifndef raw_cpu_read_2 | 180 | #ifndef raw_cpu_read_2 |
| 174 | #define raw_cpu_read_2(pcp) (*raw_cpu_ptr(&(pcp))) | 181 | #define raw_cpu_read_2(pcp) raw_cpu_generic_read(pcp) |
| 175 | #endif | 182 | #endif |
| 176 | #ifndef raw_cpu_read_4 | 183 | #ifndef raw_cpu_read_4 |
| 177 | #define raw_cpu_read_4(pcp) (*raw_cpu_ptr(&(pcp))) | 184 | #define raw_cpu_read_4(pcp) raw_cpu_generic_read(pcp) |
| 178 | #endif | 185 | #endif |
| 179 | #ifndef raw_cpu_read_8 | 186 | #ifndef raw_cpu_read_8 |
| 180 | #define raw_cpu_read_8(pcp) (*raw_cpu_ptr(&(pcp))) | 187 | #define raw_cpu_read_8(pcp) raw_cpu_generic_read(pcp) |
| 181 | #endif | 188 | #endif |
| 182 | 189 | ||
| 183 | #ifndef raw_cpu_write_1 | 190 | #ifndef raw_cpu_write_1 |
