* [thisops uV3 01/18] percpucounter: Optimize __percpu_counter_add a bit through the use of this_cpu() options.
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 02/18] vmstat: Optimize zone counter modifications through the use of this cpu operations Christoph Lameter
` (17 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: percpu_fixes --]
[-- Type: text/plain, Size: 4595 bytes --]
The this_cpu_* options can be used to optimize __percpu_counter_add a bit. Avoids
some address arithmetic and saves 12 bytes.
Before:
00000000000001d3 <__percpu_counter_add>:
1d3: 55 push %rbp
1d4: 48 89 e5 mov %rsp,%rbp
1d7: 41 55 push %r13
1d9: 41 54 push %r12
1db: 53 push %rbx
1dc: 48 89 fb mov %rdi,%rbx
1df: 48 83 ec 08 sub $0x8,%rsp
1e3: 4c 8b 67 30 mov 0x30(%rdi),%r12
1e7: 65 4c 03 24 25 00 00 add %gs:0x0,%r12
1ee: 00 00
1f0: 4d 63 2c 24 movslq (%r12),%r13
1f4: 48 63 c2 movslq %edx,%rax
1f7: 49 01 f5 add %rsi,%r13
1fa: 49 39 c5 cmp %rax,%r13
1fd: 7d 0a jge 209 <__percpu_counter_add+0x36>
1ff: f7 da neg %edx
201: 48 63 d2 movslq %edx,%rdx
204: 49 39 d5 cmp %rdx,%r13
207: 7f 1e jg 227 <__percpu_counter_add+0x54>
209: 48 89 df mov %rbx,%rdi
20c: e8 00 00 00 00 callq 211 <__percpu_counter_add+0x3e>
211: 4c 01 6b 18 add %r13,0x18(%rbx)
215: 48 89 df mov %rbx,%rdi
218: 41 c7 04 24 00 00 00 movl $0x0,(%r12)
21f: 00
220: e8 00 00 00 00 callq 225 <__percpu_counter_add+0x52>
225: eb 04 jmp 22b <__percpu_counter_add+0x58>
227: 45 89 2c 24 mov %r13d,(%r12)
22b: 5b pop %rbx
22c: 5b pop %rbx
22d: 41 5c pop %r12
22f: 41 5d pop %r13
231: c9 leaveq
232: c3 retq
After:
00000000000001d3 <__percpu_counter_add>:
1d3: 55 push %rbp
1d4: 48 63 ca movslq %edx,%rcx
1d7: 48 89 e5 mov %rsp,%rbp
1da: 41 54 push %r12
1dc: 53 push %rbx
1dd: 48 89 fb mov %rdi,%rbx
1e0: 48 8b 47 30 mov 0x30(%rdi),%rax
1e4: 65 44 8b 20 mov %gs:(%rax),%r12d
1e8: 4d 63 e4 movslq %r12d,%r12
1eb: 49 01 f4 add %rsi,%r12
1ee: 49 39 cc cmp %rcx,%r12
1f1: 7d 0a jge 1fd <__percpu_counter_add+0x2a>
1f3: f7 da neg %edx
1f5: 48 63 d2 movslq %edx,%rdx
1f8: 49 39 d4 cmp %rdx,%r12
1fb: 7f 21 jg 21e <__percpu_counter_add+0x4b>
1fd: 48 89 df mov %rbx,%rdi
200: e8 00 00 00 00 callq 205 <__percpu_counter_add+0x32>
205: 4c 01 63 18 add %r12,0x18(%rbx)
209: 48 8b 43 30 mov 0x30(%rbx),%rax
20d: 48 89 df mov %rbx,%rdi
210: 65 c7 00 00 00 00 00 movl $0x0,%gs:(%rax)
217: e8 00 00 00 00 callq 21c <__percpu_counter_add+0x49>
21c: eb 04 jmp 222 <__percpu_counter_add+0x4f>
21e: 65 44 89 20 mov %r12d,%gs:(%rax)
222: 5b pop %rbx
223: 41 5c pop %r12
225: c9 leaveq
226: c3 retq
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Reviewed-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
lib/percpu_counter.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
Index: linux-2.6/lib/percpu_counter.c
===================================================================
--- linux-2.6.orig/lib/percpu_counter.c 2010-11-03 12:25:37.000000000 -0500
+++ linux-2.6/lib/percpu_counter.c 2010-11-03 12:27:27.000000000 -0500
@@ -72,18 +72,16 @@ EXPORT_SYMBOL(percpu_counter_set);
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
{
s64 count;
- s32 *pcount;
preempt_disable();
- pcount = this_cpu_ptr(fbc->counters);
- count = *pcount + amount;
+ count = __this_cpu_read(*fbc->counters) + amount;
if (count >= batch || count <= -batch) {
spin_lock(&fbc->lock);
fbc->count += count;
- *pcount = 0;
+ __this_cpu_write(*fbc->counters, 0);
spin_unlock(&fbc->lock);
} else {
- *pcount = count;
+ __this_cpu_write(*fbc->counters, count);
}
preempt_enable();
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 02/18] vmstat: Optimize zone counter modifications through the use of this cpu operations
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 01/18] percpucounter: Optimize __percpu_counter_add a bit through the use of this_cpu() options Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 03/18] percpu: Generic support for this_cpu_add,sub,dec,inc_return Christoph Lameter
` (16 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: vmstat_this_cpu --]
[-- Type: text/plain, Size: 3473 bytes --]
this cpu operations can be used to slightly optimize the function. The
changes will avoid some address calculations and replace them with the
use of the percpu segment register.
If one would have this_cpu_inc_return and this_cpu_dec_return then it
would be possible to optimize inc_zone_page_state and dec_zone_page_state even
more.
V1->V2:
- Fix __dec_zone_state overflow handling
- Use s8 variables for temporary storage.
V2->V3:
- Put __percpu annotations in correct places.
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
mm/vmstat.c | 56 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 32 insertions(+), 24 deletions(-)
Index: linux-2.6/mm/vmstat.c
===================================================================
--- linux-2.6.orig/mm/vmstat.c 2010-11-29 10:17:28.000000000 -0600
+++ linux-2.6/mm/vmstat.c 2010-11-29 10:36:16.000000000 -0600
@@ -167,18 +167,20 @@ static void refresh_zone_stat_thresholds
void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
int delta)
{
- struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset);
-
- s8 *p = pcp->vm_stat_diff + item;
+ struct per_cpu_pageset __percpu *pcp = zone->pageset;
+ s8 __percpu *p = pcp->vm_stat_diff + item;
long x;
+ long t;
+
+ x = delta + __this_cpu_read(*p);
- x = delta + *p;
+ t = __this_cpu_read(pcp->stat_threshold);
- if (unlikely(x > pcp->stat_threshold || x < -pcp->stat_threshold)) {
+ if (unlikely(x > t || x < -t)) {
zone_page_state_add(x, zone, item);
x = 0;
}
- *p = x;
+ __this_cpu_write(*p, x);
}
EXPORT_SYMBOL(__mod_zone_page_state);
@@ -221,16 +223,19 @@ EXPORT_SYMBOL(mod_zone_page_state);
*/
void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
{
- struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset);
- s8 *p = pcp->vm_stat_diff + item;
-
- (*p)++;
+ struct per_cpu_pageset __percpu *pcp = zone->pageset;
+ s8 __percpu *p = pcp->vm_stat_diff + item;
+ s8 v, t;
+
+ __this_cpu_inc(*p);
+
+ v = __this_cpu_read(*p);
+ t = __this_cpu_read(pcp->stat_threshold);
+ if (unlikely(v > t)) {
+ s8 overstep = t >> 1;
- if (unlikely(*p > pcp->stat_threshold)) {
- int overstep = pcp->stat_threshold / 2;
-
- zone_page_state_add(*p + overstep, zone, item);
- *p = -overstep;
+ zone_page_state_add(v + overstep, zone, item);
+ __this_cpu_write(*p, - overstep);
}
}
@@ -242,16 +247,19 @@ EXPORT_SYMBOL(__inc_zone_page_state);
void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
{
- struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset);
- s8 *p = pcp->vm_stat_diff + item;
-
- (*p)--;
-
- if (unlikely(*p < - pcp->stat_threshold)) {
- int overstep = pcp->stat_threshold / 2;
+ struct per_cpu_pageset __percpu *pcp = zone->pageset;
+ s8 __percpu *p = pcp->vm_stat_diff + item;
+ s8 v, t;
+
+ __this_cpu_dec(*p);
+
+ v = __this_cpu_read(*p);
+ t = __this_cpu_read(pcp->stat_threshold);
+ if (unlikely(v < - t)) {
+ s8 overstep = t >> 1;
- zone_page_state_add(*p - overstep, zone, item);
- *p = overstep;
+ zone_page_state_add(v - overstep, zone, item);
+ __this_cpu_write(*p, overstep);
}
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 03/18] percpu: Generic support for this_cpu_add,sub,dec,inc_return
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 01/18] percpucounter: Optimize __percpu_counter_add a bit through the use of this_cpu() options Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 02/18] vmstat: Optimize zone counter modifications through the use of this cpu operations Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 04/18] x86: Support " Christoph Lameter
` (15 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_add_dec_return --]
[-- Type: text/plain, Size: 4093 bytes --]
Introduce generic support for this_cpu_add_return etc.
The fallback is to realize these operations with simpler __this_cpu_ops.
Reviewed-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/linux/percpu.h | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
Index: linux-2.6/include/linux/percpu.h
===================================================================
--- linux-2.6.orig/include/linux/percpu.h 2010-11-29 10:19:28.000000000 -0600
+++ linux-2.6/include/linux/percpu.h 2010-11-29 10:24:57.000000000 -0600
@@ -240,6 +240,25 @@ extern void __bad_size_call_parameter(vo
pscr_ret__; \
})
+#define __pcpu_size_call_return2(stem, pcp, ...) \
+({ \
+ typeof(pcp) ret__; \
+ __verify_pcpu_ptr(&(pcp)); \
+ switch(sizeof(pcp)) { \
+ case 1: ret__ = stem##1(pcp, __VA_ARGS__); \
+ break; \
+ case 2: ret__ = stem##2(pcp, __VA_ARGS__); \
+ break; \
+ case 4: ret__ = stem##4(pcp, __VA_ARGS__); \
+ break; \
+ case 8: ret__ = stem##8(pcp, __VA_ARGS__); \
+ break; \
+ default: \
+ __bad_size_call_parameter();break; \
+ } \
+ ret__; \
+})
+
#define __pcpu_size_call(stem, variable, ...) \
do { \
__verify_pcpu_ptr(&(variable)); \
@@ -529,6 +548,64 @@ do { \
# define __this_cpu_xor(pcp, val) __pcpu_size_call(__this_cpu_xor_, (pcp), (val))
#endif
+#define _this_cpu_generic_add_return(pcp, val) \
+({ \
+ typeof(pcp) ret__; \
+ preempt_disable(); \
+ __this_cpu_add(pcp, val); \
+ ret__ = __this_cpu_read(pcp); \
+ preempt_enable(); \
+ ret__; \
+})
+
+#ifndef this_cpu_add_return
+# ifndef this_cpu_add_return_1
+# define this_cpu_add_return_1(pcp, val) _this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef this_cpu_add_return_2
+# define this_cpu_add_return_2(pcp, val) _this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef this_cpu_add_return_4
+# define this_cpu_add_return_4(pcp, val) _this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef this_cpu_add_return_8
+# define this_cpu_add_return_8(pcp, val) _this_cpu_generic_add_return(pcp, val)
+# endif
+# define this_cpu_add_return(pcp, val) __pcpu_size_call_return2(this_cpu_add_return_, pcp, val)
+#endif
+
+#define this_cpu_sub_return(pcp, val) this_cpu_add_return(pcp, -(val))
+#define this_cpu_inc_return(pcp) this_cpu_add_return(pcp, 1)
+#define this_cpu_dec_return(pcp) this_cpu_add_return(pcp, -1)
+
+#define __this_cpu_generic_add_return(pcp, val) \
+({ \
+ typeof(pcp) ret__; \
+ __this_cpu_add(pcp, val); \
+ ret__ = __this_cpu_read(pcp); \
+ ret__; \
+})
+
+#ifndef __this_cpu_add_return
+# ifndef __this_cpu_add_return_1
+# define __this_cpu_add_return_1(pcp, val) __this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef __this_cpu_add_return_2
+# define __this_cpu_add_return_2(pcp, val) __this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef __this_cpu_add_return_4
+# define __this_cpu_add_return_4(pcp, val) __this_cpu_generic_add_return(pcp, val)
+# endif
+# ifndef __this_cpu_add_return_8
+# define __this_cpu_add_return_8(pcp, val) __this_cpu_generic_add_return(pcp, val)
+# endif
+# define __this_cpu_add_return(pcp, val) __pcpu_size_call_return2(this_cpu_add_return_, pcp, val)
+#endif
+
+#define __this_cpu_sub_return(pcp, val) this_cpu_add_return(pcp, -(val))
+#define __this_cpu_inc_return(pcp) this_cpu_add_return(pcp, 1)
+#define __this_cpu_dec_return(pcp) this_cpu_add_return(pcp, -1)
+
/*
* IRQ safe versions of the per cpu RMW operations. Note that these operations
* are *not* safe against modification of the same variable from another
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 04/18] x86: Support for this_cpu_add,sub,dec,inc_return
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (2 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 03/18] percpu: Generic support for this_cpu_add,sub,dec,inc_return Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 05/18] x86: Use this_cpu_inc_return for nmi counter Christoph Lameter
` (14 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_add_x86 --]
[-- Type: text/plain, Size: 3107 bytes --]
Supply an implementation for x86 in order to generate more efficient code.
V2->V3:
- Cleanup
- Remove strange type checking from percpu_add_return_op.
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/include/asm/percpu.h | 46 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
Index: linux-2.6/arch/x86/include/asm/percpu.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/percpu.h 2010-11-29 14:29:13.000000000 -0600
+++ linux-2.6/arch/x86/include/asm/percpu.h 2010-11-30 08:42:02.000000000 -0600
@@ -177,6 +177,41 @@ do { \
} \
} while (0)
+
+/*
+ * Add return operation
+ */
+#define percpu_add_return_op(var, val) \
+({ \
+ typedef typeof(var) pao_T__; \
+ typeof(var) ret__ = val; \
+ switch (sizeof(var)) { \
+ case 1: \
+ asm("xaddb %0, "__percpu_arg(1) \
+ : "+q" (ret__), "+m" (var) \
+ : : "memory"); \
+ break; \
+ case 2: \
+ asm("xaddw %0, "__percpu_arg(1) \
+ : "+r" (ret__), "+m" (var) \
+ : : "memory"); \
+ break; \
+ case 4: \
+ asm("xaddl %0, "__percpu_arg(1) \
+ : "+r"(ret__), "+m" (var) \
+ : : "memory"); \
+ break; \
+ case 8: \
+ asm("xaddq %0, "__percpu_arg(1) \
+ : "+re" (ret__), "+m" (var) \
+ : : "memory"); \
+ break; \
+ default: __bad_percpu_size(); \
+ } \
+ ret__ += val; \
+ ret__; \
+})
+
#define percpu_from_op(op, var, constraint) \
({ \
typeof(var) pfo_ret__; \
@@ -300,6 +335,14 @@ do { \
#define irqsafe_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val)
#define irqsafe_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val)
+#ifndef CONFIG_M386
+#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
+#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
+#define __this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
+#define this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
+#define this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
+#define this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
+#endif
/*
* Per cpu atomic 64 bit operations are only available under 64 bit.
* 32 bit must fall back to generic operations.
@@ -324,6 +367,9 @@ do { \
#define irqsafe_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val)
#define irqsafe_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val)
+#define __this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)
+#define this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)
+
#endif
/* This is not atomic against other CPUs -- CPU preemption needs to be off */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 05/18] x86: Use this_cpu_inc_return for nmi counter
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (3 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 04/18] x86: Support " Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 06/18] vmstat: Use this_cpu_inc_return for vm statistics Christoph Lameter
` (13 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_add_nmi --]
[-- Type: text/plain, Size: 1305 bytes --]
this_cpu_inc_return() saves us a memory access there.
Reviewed-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/kernel/apic/nmi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
Index: linux-2.6/arch/x86/kernel/apic/nmi.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/nmi.c 2010-11-23 16:35:19.000000000 -0600
+++ linux-2.6/arch/x86/kernel/apic/nmi.c 2010-11-23 16:38:29.000000000 -0600
@@ -432,8 +432,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
* Ayiee, looks like this CPU is stuck ...
* wait a few IRQs (5 seconds) before doing the oops ...
*/
- __this_cpu_inc(alert_counter);
- if (__this_cpu_read(alert_counter) == 5 * nmi_hz)
+ if (__this_cpu_inc_return(alert_counter) == 5 * nmi_hz)
/*
* die_nmi will return ONLY if NOTIFY_STOP happens..
*/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 06/18] vmstat: Use this_cpu_inc_return for vm statistics
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (4 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 05/18] x86: Use this_cpu_inc_return for nmi counter Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations Christoph Lameter
` (12 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_add_vmstat --]
[-- Type: text/plain, Size: 1532 bytes --]
this_cpu_inc_return() saves us a memory access there. Code
size does not change.
V1->V2:
- Fixed the location of the __per_cpu pointer attributes
- Sparse checked
V2->V3:
- Move fixes to __percpu attribute usage to earlier patch
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
mm/vmstat.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
Index: linux-2.6/mm/vmstat.c
===================================================================
--- linux-2.6.orig/mm/vmstat.c 2010-11-29 10:36:16.000000000 -0600
+++ linux-2.6/mm/vmstat.c 2010-11-29 10:38:50.000000000 -0600
@@ -227,9 +227,7 @@ void __inc_zone_state(struct zone *zone,
s8 __percpu *p = pcp->vm_stat_diff + item;
s8 v, t;
- __this_cpu_inc(*p);
-
- v = __this_cpu_read(*p);
+ v = __this_cpu_inc_return(*p);
t = __this_cpu_read(pcp->stat_threshold);
if (unlikely(v > t)) {
s8 overstep = t >> 1;
@@ -251,9 +249,7 @@ void __dec_zone_state(struct zone *zone,
s8 __percpu *p = pcp->vm_stat_diff + item;
s8 v, t;
- __this_cpu_dec(*p);
-
- v = __this_cpu_read(*p);
+ v = __this_cpu_dec_return(*p);
t = __this_cpu_read(pcp->stat_threshold);
if (unlikely(v < - t)) {
s8 overstep = t >> 1;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (5 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 06/18] vmstat: Use this_cpu_inc_return for vm statistics Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:13 ` Eric Dumazet
2010-11-30 19:07 ` [thisops uV3 08/18] Taskstats: Use this_cpu_ops Christoph Lameter
` (11 subsequent siblings)
18 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Peter Zijlstra, Catalin Marinas, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_highmem --]
[-- Type: text/plain, Size: 1690 bytes --]
Use this_cpu operations to optimize access primitives for highmem.
The main effect is the avoidance of address calculations through the
use of a segment prefix.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/linux/highmem.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
Index: linux-2.6/include/linux/highmem.h
===================================================================
--- linux-2.6.orig/include/linux/highmem.h 2010-11-22 14:43:40.000000000 -0600
+++ linux-2.6/include/linux/highmem.h 2010-11-22 14:45:02.000000000 -0600
@@ -81,7 +81,8 @@ DECLARE_PER_CPU(int, __kmap_atomic_idx);
static inline int kmap_atomic_idx_push(void)
{
- int idx = __get_cpu_var(__kmap_atomic_idx)++;
+ int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;
+
#ifdef CONFIG_DEBUG_HIGHMEM
WARN_ON_ONCE(in_irq() && !irqs_disabled());
BUG_ON(idx > KM_TYPE_NR);
@@ -91,12 +92,12 @@ static inline int kmap_atomic_idx_push(v
static inline int kmap_atomic_idx(void)
{
- return __get_cpu_var(__kmap_atomic_idx) - 1;
+ return __this_cpu_read(__kmap_atomic_idx) - 1;
}
static inline int kmap_atomic_idx_pop(void)
{
- int idx = --__get_cpu_var(__kmap_atomic_idx);
+ int idx = __this_cpu_dec_return(__kmap_atomic_idx);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(idx < 0);
#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:07 ` [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations Christoph Lameter
@ 2010-11-30 19:13 ` Eric Dumazet
2010-11-30 19:19 ` Peter Zijlstra
2010-11-30 19:26 ` Christoph Lameter
0 siblings, 2 replies; 35+ messages in thread
From: Eric Dumazet @ 2010-11-30 19:13 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, Pekka Enberg, Peter Zijlstra, Catalin Marinas, linux-kernel,
Mathieu Desnoyers, Tejun Heo, linux-mm
Le mardi 30 novembre 2010 A 13:07 -0600, Christoph Lameter a A(C)crit :
> piA?ce jointe document texte brut (this_cpu_highmem)
> Use this_cpu operations to optimize access primitives for highmem.
>
> The main effect is the avoidance of address calculations through the
> use of a segment prefix.
>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Christoph Lameter <cl@linux.com>
>
> ---
> include/linux/highmem.h | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> Index: linux-2.6/include/linux/highmem.h
> ===================================================================
> --- linux-2.6.orig/include/linux/highmem.h 2010-11-22 14:43:40.000000000 -0600
> +++ linux-2.6/include/linux/highmem.h 2010-11-22 14:45:02.000000000 -0600
> @@ -81,7 +81,8 @@ DECLARE_PER_CPU(int, __kmap_atomic_idx);
>
> static inline int kmap_atomic_idx_push(void)
> {
> - int idx = __get_cpu_var(__kmap_atomic_idx)++;
> + int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;
> +
> #ifdef CONFIG_DEBUG_HIGHMEM
> WARN_ON_ONCE(in_irq() && !irqs_disabled());
> BUG_ON(idx > KM_TYPE_NR);
> @@ -91,12 +92,12 @@ static inline int kmap_atomic_idx_push(v
>
> static inline int kmap_atomic_idx(void)
> {
> - return __get_cpu_var(__kmap_atomic_idx) - 1;
> + return __this_cpu_read(__kmap_atomic_idx) - 1;
> }
>
> static inline int kmap_atomic_idx_pop(void)
> {
> - int idx = --__get_cpu_var(__kmap_atomic_idx);
> + int idx = __this_cpu_dec_return(__kmap_atomic_idx);
__this_cpu_dec_return() is only needed if CONFIG_DEBUG_HIGHMEM
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(idx < 0);
> #endif
>
You could change kmap_atomic_idx_pop() to return void, and use
__this_cpu_dec(__kmap_atomic_idx)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:13 ` Eric Dumazet
@ 2010-11-30 19:19 ` Peter Zijlstra
2010-11-30 19:26 ` Christoph Lameter
1 sibling, 0 replies; 35+ messages in thread
From: Peter Zijlstra @ 2010-11-30 19:19 UTC (permalink / raw)
To: Eric Dumazet
Cc: Christoph Lameter, akpm, Pekka Enberg, Catalin Marinas,
linux-kernel, Mathieu Desnoyers, Tejun Heo, linux-mm
On Tue, 2010-11-30 at 20:13 +0100, Eric Dumazet wrote:
> Le mardi 30 novembre 2010 à 13:07 -0600, Christoph Lameter a écrit :
> > pièce jointe document texte brut (this_cpu_highmem)
> > Use this_cpu operations to optimize access primitives for highmem.
> >
> > The main effect is the avoidance of address calculations through the
> > use of a segment prefix.
> >
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Christoph Lameter <cl@linux.com>
> >
> > ---
> > include/linux/highmem.h | 7 ++++---
> > 1 file changed, 4 insertions(+), 3 deletions(-)
> >
> > Index: linux-2.6/include/linux/highmem.h
> > ===================================================================
> > --- linux-2.6.orig/include/linux/highmem.h 2010-11-22 14:43:40.000000000 -0600
> > +++ linux-2.6/include/linux/highmem.h 2010-11-22 14:45:02.000000000 -0600
> > @@ -81,7 +81,8 @@ DECLARE_PER_CPU(int, __kmap_atomic_idx);
> >
> > static inline int kmap_atomic_idx_push(void)
> > {
> > - int idx = __get_cpu_var(__kmap_atomic_idx)++;
> > + int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;
> > +
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > WARN_ON_ONCE(in_irq() && !irqs_disabled());
> > BUG_ON(idx > KM_TYPE_NR);
> > @@ -91,12 +92,12 @@ static inline int kmap_atomic_idx_push(v
> >
> > static inline int kmap_atomic_idx(void)
> > {
> > - return __get_cpu_var(__kmap_atomic_idx) - 1;
> > + return __this_cpu_read(__kmap_atomic_idx) - 1;
> > }
> >
> > static inline int kmap_atomic_idx_pop(void)
> > {
> > - int idx = --__get_cpu_var(__kmap_atomic_idx);
> > + int idx = __this_cpu_dec_return(__kmap_atomic_idx);
>
> __this_cpu_dec_return() is only needed if CONFIG_DEBUG_HIGHMEM
>
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > BUG_ON(idx < 0);
> > #endif
> >
>
> You could change kmap_atomic_idx_pop() to return void, and use
> __this_cpu_dec(__kmap_atomic_idx)
You can do the void change unconditionally, the debug code already uses
kmap_atomic_idx() because of:
---
commit 20273941f2129aa5a432796d98a276ed73d60782
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Wed Oct 27 15:32:58 2010 -0700
mm: fix race in kunmap_atomic()
Christoph reported a nice splat which illustrated a race in the new stack
based kmap_atomic implementation.
The problem is that we pop our stack slot before we're completely done
resetting its state -- in particular clearing the PTE (sometimes that's
CONFIG_DEBUG_HIGHMEM). If an interrupt happens before we actually clear
the PTE used for the last slot, that interrupt can reuse the slot in a
dirty state, which triggers a BUG in kmap_atomic().
Fix this by introducing kmap_atomic_idx() which reports the current slot
index without actually releasing it and use that to find the PTE and delay
the _pop() until after we're completely done.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Reported-by: Christoph Hellwig <hch@infradead.org>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index c00f119..c435fd9 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -89,7 +89,7 @@ void __kunmap_atomic(void *kvaddr)
int idx, type;
if (kvaddr >= (void *)FIXADDR_START) {
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
if (cache_is_vivt())
@@ -101,6 +101,7 @@ void __kunmap_atomic(void *kvaddr)
#else
(void) idx; /* to kill a warning */
#endif
+ kmap_atomic_idx_pop();
} else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
/* this address was obtained through kmap_high_get() */
kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 61088dc..fd7fcd4 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(__kmap_atomic);
void __kunmap_atomic(void *kvaddr)
{
- int type = kmap_atomic_idx_pop();
+ int type = kmap_atomic_idx();
switch (type) {
case 0: __kunmap_atomic_primary(4, 6); break;
case 1: __kunmap_atomic_primary(5, 7); break;
@@ -83,6 +83,7 @@ void __kunmap_atomic(void *kvaddr)
default:
BUG();
}
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 1e69b1f..3634c7e 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -74,7 +74,7 @@ void __kunmap_atomic(void *kvaddr)
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
int idx = type + KM_TYPE_NR * smp_processor_id();
@@ -89,6 +89,7 @@ void __kunmap_atomic(void *kvaddr)
local_flush_tlb_one(vaddr);
}
#endif
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h
index f577ba2..e2155e6 100644
--- a/arch/mn10300/include/asm/highmem.h
+++ b/arch/mn10300/include/asm/highmem.h
@@ -101,7 +101,7 @@ static inline void __kunmap_atomic(unsigned long vaddr)
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#if HIGHMEM_DEBUG
{
@@ -119,6 +119,8 @@ static inline void __kunmap_atomic(unsigned long vaddr)
__flush_tlb_one(vaddr);
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c
index b0848b4..e7450bd 100644
--- a/arch/powerpc/mm/highmem.c
+++ b/arch/powerpc/mm/highmem.c
@@ -62,7 +62,7 @@ void __kunmap_atomic(void *kvaddr)
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
@@ -79,6 +79,8 @@ void __kunmap_atomic(void *kvaddr)
local_flush_tlb_page(NULL, vaddr);
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 5e50c09..4730eac 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -75,7 +75,7 @@ void __kunmap_atomic(void *kvaddr)
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
@@ -104,6 +104,8 @@ void __kunmap_atomic(void *kvaddr)
#endif
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
index 8ef6595..abb5733 100644
--- a/arch/tile/mm/highmem.c
+++ b/arch/tile/mm/highmem.c
@@ -241,7 +241,7 @@ void __kunmap_atomic(void *kvaddr)
pte_t pteval = *pte;
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR*smp_processor_id();
/*
@@ -252,6 +252,7 @@ void __kunmap_atomic(void *kvaddr)
BUG_ON(!pte_present(pteval) && !pte_migrating(pteval));
kmap_atomic_unregister(pte_page(pteval), vaddr);
kpte_clear_flush(pte, vaddr);
+ kmap_atomic_idx_pop();
} else {
/* Must be a lowmem page */
BUG_ON(vaddr < PAGE_OFFSET);
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index d723e36..b499626 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -74,7 +74,7 @@ void __kunmap_atomic(void *kvaddr)
vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -87,6 +87,7 @@ void __kunmap_atomic(void *kvaddr)
* attributes or becomes a protected page in a hypervisor.
*/
kpte_clear_flush(kmap_pte-idx, vaddr);
+ kmap_atomic_idx_pop();
}
#ifdef CONFIG_DEBUG_HIGHMEM
else {
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index 75a3d7f..7b179b4 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -98,7 +98,7 @@ iounmap_atomic(void __iomem *kvaddr)
vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -111,6 +111,7 @@ iounmap_atomic(void __iomem *kvaddr)
* attributes or becomes a protected page in a hypervisor.
*/
kpte_clear_flush(kmap_pte-idx, vaddr);
+ kmap_atomic_idx_pop();
}
pagefault_enable();
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 102f76b..e913819 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -88,6 +88,11 @@ static inline int kmap_atomic_idx_push(void)
return idx;
}
+static inline int kmap_atomic_idx(void)
+{
+ return __get_cpu_var(__kmap_atomic_idx) - 1;
+}
+
static inline int kmap_atomic_idx_pop(void)
{
int idx = --__get_cpu_var(__kmap_atomic_idx);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:13 ` Eric Dumazet
2010-11-30 19:19 ` Peter Zijlstra
@ 2010-11-30 19:26 ` Christoph Lameter
2010-11-30 19:29 ` Eric Dumazet
1 sibling, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:26 UTC (permalink / raw)
To: Eric Dumazet
Cc: akpm, Pekka Enberg, Peter Zijlstra, Catalin Marinas, linux-kernel,
Mathieu Desnoyers, Tejun Heo, linux-mm
On Tue, 30 Nov 2010, Eric Dumazet wrote:
> > {
> > - int idx = --__get_cpu_var(__kmap_atomic_idx);
> > + int idx = __this_cpu_dec_return(__kmap_atomic_idx);
>
> __this_cpu_dec_return() is only needed if CONFIG_DEBUG_HIGHMEM
>
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > BUG_ON(idx < 0);
> > #endif
> >
>
> You could change kmap_atomic_idx_pop() to return void, and use
> __this_cpu_dec(__kmap_atomic_idx)
The following would do?
Subject: highmem: Use this_cpu_dec instead of __this_cpu_dec_return if !DEBUG_HIGHMEM
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/linux/highmem.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
Index: linux-2.6/include/linux/highmem.h
===================================================================
--- linux-2.6.orig/include/linux/highmem.h 2010-11-30 13:23:44.000000000 -0600
+++ linux-2.6/include/linux/highmem.h 2010-11-30 13:24:54.000000000 -0600
@@ -95,14 +95,19 @@ static inline int kmap_atomic_idx(void)
return __this_cpu_read(__kmap_atomic_idx) - 1;
}
+#ifdef CONFIG_DEBUG_HIGHMEM
static inline int kmap_atomic_idx_pop(void)
{
int idx = __this_cpu_dec_return(__kmap_atomic_idx);
-#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(idx < 0);
-#endif
return idx;
}
+#else
+static inline void kmap_atomic_idx_pop(void)
+{
+ __this_cpu_dec(__kmap_atomic_idx);
+}
+#endif
#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:26 ` Christoph Lameter
@ 2010-11-30 19:29 ` Eric Dumazet
2010-11-30 19:38 ` Peter Zijlstra
0 siblings, 1 reply; 35+ messages in thread
From: Eric Dumazet @ 2010-11-30 19:29 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, Pekka Enberg, Peter Zijlstra, Catalin Marinas, linux-kernel,
Mathieu Desnoyers, Tejun Heo, linux-mm
Le mardi 30 novembre 2010 A 13:26 -0600, Christoph Lameter a A(C)crit :
> On Tue, 30 Nov 2010, Eric Dumazet wrote:
>
> > > {
> > > - int idx = --__get_cpu_var(__kmap_atomic_idx);
> > > + int idx = __this_cpu_dec_return(__kmap_atomic_idx);
> >
> > __this_cpu_dec_return() is only needed if CONFIG_DEBUG_HIGHMEM
> >
> > > #ifdef CONFIG_DEBUG_HIGHMEM
> > > BUG_ON(idx < 0);
> > > #endif
> > >
> >
> > You could change kmap_atomic_idx_pop() to return void, and use
> > __this_cpu_dec(__kmap_atomic_idx)
>
> The following would do?
>
>
> Subject: highmem: Use this_cpu_dec instead of __this_cpu_dec_return if !DEBUG_HIGHMEM
>
> Signed-off-by: Christoph Lameter <cl@linux.com>
>
> ---
> include/linux/highmem.h | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> Index: linux-2.6/include/linux/highmem.h
> ===================================================================
> --- linux-2.6.orig/include/linux/highmem.h 2010-11-30 13:23:44.000000000 -0600
> +++ linux-2.6/include/linux/highmem.h 2010-11-30 13:24:54.000000000 -0600
> @@ -95,14 +95,19 @@ static inline int kmap_atomic_idx(void)
> return __this_cpu_read(__kmap_atomic_idx) - 1;
> }
>
> +#ifdef CONFIG_DEBUG_HIGHMEM
> static inline int kmap_atomic_idx_pop(void)
> {
> int idx = __this_cpu_dec_return(__kmap_atomic_idx);
> -#ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(idx < 0);
> -#endif
> return idx;
> }
> +#else
> +static inline void kmap_atomic_idx_pop(void)
> +{
> + __this_cpu_dec(__kmap_atomic_idx);
> +}
> +#endif
>
> #endif
>
well maybe a single prototype ;)
static inline void kmap_atomic_idx_pop(void)
{
#ifdef CONFIG_DEBUG_HIGHMEM
int idx = __this_cpu_dec_return(__kmap_atomic_idx);
BUG_ON(idx < 0);
#else
__this_cpu_dec(__kmap_atomic_idx);
#endif
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:29 ` Eric Dumazet
@ 2010-11-30 19:38 ` Peter Zijlstra
2010-11-30 19:53 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Peter Zijlstra @ 2010-11-30 19:38 UTC (permalink / raw)
To: Eric Dumazet
Cc: Christoph Lameter, akpm, Pekka Enberg, Catalin Marinas,
linux-kernel, Mathieu Desnoyers, Tejun Heo, linux-mm
On Tue, 2010-11-30 at 20:29 +0100, Eric Dumazet wrote:
>
> well maybe a single prototype ;)
>
> static inline void kmap_atomic_idx_pop(void)
> {
> #ifdef CONFIG_DEBUG_HIGHMEM
> int idx = __this_cpu_dec_return(__kmap_atomic_idx);
> BUG_ON(idx < 0);
> #else
> __this_cpu_dec(__kmap_atomic_idx);
> #endif
> }
Right, at least a consistent prototype, the above looks fine to me.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations
2010-11-30 19:38 ` Peter Zijlstra
@ 2010-11-30 19:53 ` Christoph Lameter
0 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:53 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Eric Dumazet, akpm, Pekka Enberg, Catalin Marinas, linux-kernel,
Mathieu Desnoyers, Tejun Heo, linux-mm
On Tue, 30 Nov 2010, Peter Zijlstra wrote:
> On Tue, 2010-11-30 at 20:29 +0100, Eric Dumazet wrote:
> >
> > well maybe a single prototype ;)
> >
> > static inline void kmap_atomic_idx_pop(void)
> > {
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > int idx = __this_cpu_dec_return(__kmap_atomic_idx);
> > BUG_ON(idx < 0);
> > #else
> > __this_cpu_dec(__kmap_atomic_idx);
> > #endif
> > }
>
> Right, at least a consistent prototype, the above looks fine to me.
Ok with right spacing this is:
Subject: highmem: Use this_cpu_dec instead of __this_cpu_dec_return if
!DEBUG_HIGHMEM
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/linux/highmem.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
Index: linux-2.6/include/linux/highmem.h
===================================================================
--- linux-2.6.orig/include/linux/highmem.h 2010-11-30 13:23:44.000000000 -0600
+++ linux-2.6/include/linux/highmem.h 2010-11-30 13:51:39.000000000 -0600
@@ -95,13 +95,15 @@ static inline int kmap_atomic_idx(void)
return __this_cpu_read(__kmap_atomic_idx) - 1;
}
-static inline int kmap_atomic_idx_pop(void)
+static inline void kmap_atomic_idx_pop(void)
{
- int idx = __this_cpu_dec_return(__kmap_atomic_idx);
#ifdef CONFIG_DEBUG_HIGHMEM
+ int idx = __this_cpu_dec_return(__kmap_atomic_idx);
+
BUG_ON(idx < 0);
+#else
+ __this_cpu_dec(__kmap_atomic_idx);
#endif
- return idx;
}
#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 08/18] Taskstats: Use this_cpu_ops
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (6 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 07/18] highmem: Use this_cpu_xx_return() operations Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-12-01 18:06 ` Michael Holzheu
2010-11-30 19:07 ` [thisops uV3 09/18] fs: Use this_cpu_xx operations in buffer.c Christoph Lameter
` (10 subsequent siblings)
18 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Michael Holzheu, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_taskstats --]
[-- Type: text/plain, Size: 1336 bytes --]
Use this_cpu_inc_return in one place and avoid ugly __raw_get_cpu in another.
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
kernel/taskstats.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
Index: linux-2.6/kernel/taskstats.c
===================================================================
--- linux-2.6.orig/kernel/taskstats.c 2010-11-30 10:06:35.000000000 -0600
+++ linux-2.6/kernel/taskstats.c 2010-11-30 10:10:14.000000000 -0600
@@ -89,8 +89,7 @@ static int prepare_reply(struct genl_inf
return -ENOMEM;
if (!info) {
- int seq = get_cpu_var(taskstats_seqnum)++;
- put_cpu_var(taskstats_seqnum);
+ int seq = this_cpu_inc_return(taskstats_seqnum);
reply = genlmsg_put(skb, 0, seq, &family, 0, cmd);
} else
@@ -581,7 +580,7 @@ void taskstats_exit(struct task_struct *
fill_tgid_exit(tsk);
}
- listeners = &__raw_get_cpu_var(listener_array);
+ listeners = __this_cpu_ptr(listener_array);
if (list_empty(&listeners->list))
return;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops
2010-11-30 19:07 ` [thisops uV3 08/18] Taskstats: Use this_cpu_ops Christoph Lameter
@ 2010-12-01 18:06 ` Michael Holzheu
2010-12-01 18:13 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Michael Holzheu @ 2010-12-01 18:06 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm, Balbir Singh
Hello Christoph,
On Tue, 2010-11-30 at 13:07 -0600, Christoph Lameter wrote:
> plain text document attachment (this_cpu_taskstats)
> Use this_cpu_inc_return in one place and avoid ugly __raw_get_cpu in another.
>
> Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> Signed-off-by: Christoph Lameter <cl@linux.com>
>
> ---
> kernel/taskstats.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> Index: linux-2.6/kernel/taskstats.c
> ===================================================================
> --- linux-2.6.orig/kernel/taskstats.c 2010-11-30 10:06:35.000000000 -0600
> +++ linux-2.6/kernel/taskstats.c 2010-11-30 10:10:14.000000000 -0600
> @@ -89,8 +89,7 @@ static int prepare_reply(struct genl_inf
> return -ENOMEM;
>
> if (!info) {
> - int seq = get_cpu_var(taskstats_seqnum)++;
> - put_cpu_var(taskstats_seqnum);
> + int seq = this_cpu_inc_return(taskstats_seqnum);
Hmmm, wouldn't seq now always be one more than before?
I think that "seq = get_cpu_var(taskstats_seqnum)++" first assigns
taskstats_seqnum to seq and then increases the value in contrast to
this_cpu_inc_return() that returns the already increased value, correct?
Maybe that does not hurt here, Balbir?
> reply = genlmsg_put(skb, 0, seq, &family, 0, cmd);
> } else
> @@ -581,7 +580,7 @@ void taskstats_exit(struct task_struct *
> fill_tgid_exit(tsk);
> }
>
> - listeners = &__raw_get_cpu_var(listener_array);
> + listeners = __this_cpu_ptr(listener_array);
> if (list_empty(&listeners->list))
> return;
>
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops
2010-12-01 18:06 ` Michael Holzheu
@ 2010-12-01 18:13 ` Christoph Lameter
2010-12-06 14:32 ` Balbir Singh
0 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-12-01 18:13 UTC (permalink / raw)
To: Michael Holzheu
Cc: akpm, Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm, Balbir Singh
On Wed, 1 Dec 2010, Michael Holzheu wrote:
> > return -ENOMEM;
> >
> > if (!info) {
> > - int seq = get_cpu_var(taskstats_seqnum)++;
> > - put_cpu_var(taskstats_seqnum);
> > + int seq = this_cpu_inc_return(taskstats_seqnum);
>
> Hmmm, wouldn't seq now always be one more than before?
>
> I think that "seq = get_cpu_var(taskstats_seqnum)++" first assigns
> taskstats_seqnum to seq and then increases the value in contrast to
> this_cpu_inc_return() that returns the already increased value, correct?
Correct. We need to subtract one from that (which will eliminate the minus
-1 that the inline this_cpu_inc_return creates).
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops
2010-12-01 18:13 ` Christoph Lameter
@ 2010-12-06 14:32 ` Balbir Singh
2010-12-07 14:39 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Balbir Singh @ 2010-12-06 14:32 UTC (permalink / raw)
To: Christoph Lameter
Cc: Michael Holzheu, akpm, Pekka Enberg, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
* Christoph Lameter <cl@linux.com> [2010-12-01 12:13:44]:
> On Wed, 1 Dec 2010, Michael Holzheu wrote:
>
> > > return -ENOMEM;
> > >
> > > if (!info) {
> > > - int seq = get_cpu_var(taskstats_seqnum)++;
> > > - put_cpu_var(taskstats_seqnum);
> > > + int seq = this_cpu_inc_return(taskstats_seqnum);
> >
> > Hmmm, wouldn't seq now always be one more than before?
> >
> > I think that "seq = get_cpu_var(taskstats_seqnum)++" first assigns
> > taskstats_seqnum to seq and then increases the value in contrast to
> > this_cpu_inc_return() that returns the already increased value, correct?
>
> Correct. We need to subtract one from that (which will eliminate the minus
> -1 that the inline this_cpu_inc_return creates).
>
But that breaks current behaviour, we should probably initialize all
of the array to -1?
--
Three Cheers,
Balbir
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops
2010-12-06 14:32 ` Balbir Singh
@ 2010-12-07 14:39 ` Christoph Lameter
0 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-12-07 14:39 UTC (permalink / raw)
To: Balbir Singh
Cc: Michael Holzheu, akpm, Pekka Enberg, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
On Mon, 6 Dec 2010, Balbir Singh wrote:
> > Correct. We need to subtract one from that (which will eliminate the minus
> > -1 that the inline this_cpu_inc_return creates).
> >
>
> But that breaks current behaviour, we should probably initialize all
> of the array to -1?
Not necessary. This_cpu_inc() uses an xadd instruction which retrieves
the value and then increments the memory location. Then it adds 1. The -1
eliminates that add.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 09/18] fs: Use this_cpu_xx operations in buffer.c
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (7 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 08/18] Taskstats: Use this_cpu_ops Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 10/18] x86: Use this_cpu_ops to optimize code Christoph Lameter
` (9 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Wu Fengguang, Christoph Hellwig, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_buffer --]
[-- Type: text/plain, Size: 4530 bytes --]
Optimize various per cpu area operations through the new this cpu
operations. These operations avoid address calculations through the use
of segment prefixes avoid multiple memory references through RMW
instructions etc.
Reduces code size:
Before:
christoph@linux-2.6$ size fs/buffer.o
text data bss dec hex filename
19169 80 28 19277 4b4d fs/buffer.o
After:
christoph@linux-2.6$ size fs/buffer.o
text data bss dec hex filename
19138 80 28 19246 4b2e fs/buffer.o
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
fs/buffer.c | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)
Index: linux-2.6/fs/buffer.c
===================================================================
--- linux-2.6.orig/fs/buffer.c 2010-11-30 09:41:30.000000000 -0600
+++ linux-2.6/fs/buffer.c 2010-11-30 09:55:55.000000000 -0600
@@ -1270,12 +1270,10 @@ static inline void check_irqs_on(void)
static void bh_lru_install(struct buffer_head *bh)
{
struct buffer_head *evictee = NULL;
- struct bh_lru *lru;
check_irqs_on();
bh_lru_lock();
- lru = &__get_cpu_var(bh_lrus);
- if (lru->bhs[0] != bh) {
+ if (__this_cpu_read(bh_lrus.bhs[0]) != bh) {
struct buffer_head *bhs[BH_LRU_SIZE];
int in;
int out = 0;
@@ -1283,7 +1281,8 @@ static void bh_lru_install(struct buffer
get_bh(bh);
bhs[out++] = bh;
for (in = 0; in < BH_LRU_SIZE; in++) {
- struct buffer_head *bh2 = lru->bhs[in];
+ struct buffer_head *bh2 =
+ __this_cpu_read(bh_lrus.bhs[in]);
if (bh2 == bh) {
__brelse(bh2);
@@ -1298,7 +1297,7 @@ static void bh_lru_install(struct buffer
}
while (out < BH_LRU_SIZE)
bhs[out++] = NULL;
- memcpy(lru->bhs, bhs, sizeof(bhs));
+ memcpy(__this_cpu_ptr(&bh_lrus.bhs), bhs, sizeof(bhs));
}
bh_lru_unlock();
@@ -1313,23 +1312,22 @@ static struct buffer_head *
lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size)
{
struct buffer_head *ret = NULL;
- struct bh_lru *lru;
unsigned int i;
check_irqs_on();
bh_lru_lock();
- lru = &__get_cpu_var(bh_lrus);
for (i = 0; i < BH_LRU_SIZE; i++) {
- struct buffer_head *bh = lru->bhs[i];
+ struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]);
if (bh && bh->b_bdev == bdev &&
bh->b_blocknr == block && bh->b_size == size) {
if (i) {
while (i) {
- lru->bhs[i] = lru->bhs[i - 1];
+ __this_cpu_write(bh_lrus.bhs[i],
+ __this_cpu_read(bh_lrus.bhs[i - 1]));
i--;
}
- lru->bhs[0] = bh;
+ __this_cpu_write(bh_lrus.bhs[0], bh);
}
get_bh(bh);
ret = bh;
@@ -3203,22 +3201,23 @@ static void recalc_bh_state(void)
int i;
int tot = 0;
- if (__get_cpu_var(bh_accounting).ratelimit++ < 4096)
+ if (__this_cpu_inc_return(bh_accounting.ratelimit) < 4096)
return;
- __get_cpu_var(bh_accounting).ratelimit = 0;
+ __this_cpu_write(bh_accounting.ratelimit, 0);
for_each_online_cpu(i)
tot += per_cpu(bh_accounting, i).nr;
buffer_heads_over_limit = (tot > max_buffer_heads);
}
-
+
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
{
struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
if (ret) {
INIT_LIST_HEAD(&ret->b_assoc_buffers);
- get_cpu_var(bh_accounting).nr++;
+ preempt_disable();
+ __this_cpu_inc(bh_accounting.nr);
recalc_bh_state();
- put_cpu_var(bh_accounting);
+ preempt_enable();
}
return ret;
}
@@ -3228,9 +3227,10 @@ void free_buffer_head(struct buffer_head
{
BUG_ON(!list_empty(&bh->b_assoc_buffers));
kmem_cache_free(bh_cachep, bh);
- get_cpu_var(bh_accounting).nr--;
+ preempt_disable();
+ __this_cpu_dec(bh_accounting.nr);
recalc_bh_state();
- put_cpu_var(bh_accounting);
+ preempt_enable();
}
EXPORT_SYMBOL(free_buffer_head);
@@ -3243,9 +3243,8 @@ static void buffer_exit_cpu(int cpu)
brelse(b->bhs[i]);
b->bhs[i] = NULL;
}
- get_cpu_var(bh_accounting).nr += per_cpu(bh_accounting, cpu).nr;
+ this_cpu_add(bh_accounting.nr, per_cpu(bh_accounting, cpu).nr);
per_cpu(bh_accounting, cpu).nr = 0;
- put_cpu_var(bh_accounting);
}
static int buffer_cpu_notify(struct notifier_block *self,
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 10/18] x86: Use this_cpu_ops to optimize code
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (8 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 09/18] fs: Use this_cpu_xx operations in buffer.c Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 11/18] x86: Use this_cpu_ops for current_cpu_data accesses Christoph Lameter
` (8 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Yinghai Lu, Ingo Molnar, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_x86 --]
[-- Type: text/plain, Size: 19152 bytes --]
Go through x86 code and replace __get_cpu_var and get_cpu_var instances
that refer to a scalar and are not used for address determinations.
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/include/asm/debugreg.h | 2 -
arch/x86/kernel/apic/io_apic.c | 4 +--
arch/x86/kernel/apic/nmi.c | 24 +++++++++++-----------
arch/x86/kernel/apic/x2apic_uv_x.c | 8 +++----
arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 2 -
arch/x86/kernel/cpu/mcheck/mce.c | 6 ++---
arch/x86/kernel/cpu/perf_event.c | 32 ++++++++++++------------------
arch/x86/kernel/cpu/perf_event_intel.c | 4 +--
arch/x86/kernel/ftrace.c | 6 ++---
arch/x86/kernel/hw_breakpoint.c | 12 +++++------
arch/x86/kernel/irq.c | 6 ++---
arch/x86/kernel/irq_32.c | 4 +--
arch/x86/kernel/tsc.c | 2 -
arch/x86/kvm/x86.c | 8 +++----
arch/x86/oprofile/nmi_int.c | 2 -
15 files changed, 58 insertions(+), 64 deletions(-)
Index: linux-2.6/arch/x86/include/asm/debugreg.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/debugreg.h 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/include/asm/debugreg.h 2010-11-30 12:37:10.000000000 -0600
@@ -94,7 +94,7 @@ static inline void hw_breakpoint_disable
static inline int hw_breakpoint_active(void)
{
- return __get_cpu_var(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
+ return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
}
extern void aout_dump_debugregs(struct user *dump);
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c 2010-11-30 12:37:10.000000000 -0600
@@ -2302,7 +2302,7 @@ asmlinkage void smp_irq_move_cleanup_int
unsigned int irr;
struct irq_desc *desc;
struct irq_cfg *cfg;
- irq = __get_cpu_var(vector_irq)[vector];
+ irq = __this_cpu_read(vector_irq[vector]);
if (irq == -1)
continue;
@@ -2336,7 +2336,7 @@ asmlinkage void smp_irq_move_cleanup_int
apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
goto unlock;
}
- __get_cpu_var(vector_irq)[vector] = -1;
+ __this_cpu_write(vector_irq[vector], -1);
unlock:
raw_spin_unlock(&desc->lock);
}
Index: linux-2.6/arch/x86/kernel/apic/nmi.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/nmi.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/apic/nmi.c 2010-11-30 12:37:10.000000000 -0600
@@ -306,12 +306,12 @@ void acpi_nmi_disable(void)
*/
void cpu_nmi_set_wd_enabled(void)
{
- __get_cpu_var(wd_enabled) = 1;
+ __this_cpu_write(wd_enabled, 1);
}
void setup_apic_nmi_watchdog(void *unused)
{
- if (__get_cpu_var(wd_enabled))
+ if (__this_cpu_read(wd_enabled))
return;
/* cheap hack to support suspend/resume */
@@ -322,12 +322,12 @@ void setup_apic_nmi_watchdog(void *unuse
switch (nmi_watchdog) {
case NMI_LOCAL_APIC:
if (lapic_watchdog_init(nmi_hz) < 0) {
- __get_cpu_var(wd_enabled) = 0;
+ __this_cpu_write(wd_enabled, 0);
return;
}
/* FALL THROUGH */
case NMI_IO_APIC:
- __get_cpu_var(wd_enabled) = 1;
+ __this_cpu_write(wd_enabled, 1);
atomic_inc(&nmi_active);
}
}
@@ -337,13 +337,13 @@ void stop_apic_nmi_watchdog(void *unused
/* only support LOCAL and IO APICs for now */
if (!nmi_watchdog_active())
return;
- if (__get_cpu_var(wd_enabled) == 0)
+ if (__this_cpu_read(wd_enabled) == 0)
return;
if (nmi_watchdog == NMI_LOCAL_APIC)
lapic_watchdog_stop();
else
__acpi_nmi_disable(NULL);
- __get_cpu_var(wd_enabled) = 0;
+ __this_cpu_write(wd_enabled, 0);
atomic_dec(&nmi_active);
}
@@ -403,8 +403,8 @@ nmi_watchdog_tick(struct pt_regs *regs,
sum = get_timer_irqs(cpu);
- if (__get_cpu_var(nmi_touch)) {
- __get_cpu_var(nmi_touch) = 0;
+ if (__this_cpu_read(nmi_touch)) {
+ __this_cpu_write(nmi_touch, 0);
touched = 1;
}
@@ -427,7 +427,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
touched = 1;
/* if the none of the timers isn't firing, this cpu isn't doing much */
- if (!touched && __get_cpu_var(last_irq_sum) == sum) {
+ if (!touched && __this_cpu_read(last_irq_sum) == sum) {
/*
* Ayiee, looks like this CPU is stuck ...
* wait a few IRQs (5 seconds) before doing the oops ...
@@ -439,12 +439,12 @@ nmi_watchdog_tick(struct pt_regs *regs,
die_nmi("BUG: NMI Watchdog detected LOCKUP",
regs, panic_on_timeout);
} else {
- __get_cpu_var(last_irq_sum) = sum;
+ __this_cpu_write(last_irq_sum, sum);
__this_cpu_write(alert_counter, 0);
}
/* see if the nmi watchdog went off */
- if (!__get_cpu_var(wd_enabled))
+ if (!__this_cpu_read(wd_enabled))
return rc;
switch (nmi_watchdog) {
case NMI_LOCAL_APIC:
@@ -466,7 +466,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
static void enable_ioapic_nmi_watchdog_single(void *unused)
{
- __get_cpu_var(wd_enabled) = 1;
+ __this_cpu_write(wd_enabled, 1);
atomic_inc(&nmi_active);
__acpi_nmi_enable(NULL);
}
Index: linux-2.6/arch/x86/kernel/apic/x2apic_uv_x.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/x2apic_uv_x.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/apic/x2apic_uv_x.c 2010-11-30 12:37:10.000000000 -0600
@@ -118,8 +118,8 @@ static int __init uv_acpi_madt_oem_check
else if (!strcmp(oem_table_id, "UVX"))
uv_system_type = UV_X2APIC;
else if (!strcmp(oem_table_id, "UVH")) {
- __get_cpu_var(x2apic_extra_bits) =
- nodeid << (uvh_apicid.s.pnode_shift - 1);
+ __this_cpu_write(x2apic_extra_bits,
+ nodeid << (uvh_apicid.s.pnode_shift - 1));
uv_system_type = UV_NON_UNIQUE_APIC;
uv_set_apicid_hibit();
return 1;
@@ -284,7 +284,7 @@ static unsigned int x2apic_get_apic_id(u
unsigned int id;
WARN_ON(preemptible() && num_online_cpus() > 1);
- id = x | __get_cpu_var(x2apic_extra_bits);
+ id = x | __this_cpu_read(x2apic_extra_bits);
return id;
}
@@ -376,7 +376,7 @@ struct apic __refdata apic_x2apic_uv_x =
static __cpuinit void set_x2apic_extra_bits(int pnode)
{
- __get_cpu_var(x2apic_extra_bits) = (pnode << 6);
+ __this_cpu_write(x2apic_extra_bits, (pnode << 6));
}
/*
Index: linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2010-11-30 12:37:10.000000000 -0600
@@ -1377,7 +1377,7 @@ static int __devexit powernowk8_cpu_exit
static void query_values_on_cpu(void *_err)
{
int *err = _err;
- struct powernow_k8_data *data = __get_cpu_var(powernow_data);
+ struct powernow_k8_data *data = __this_cpu_read(powernow_data);
*err = query_current_values_with_pending_wait(data);
}
Index: linux-2.6/arch/x86/kernel/cpu/mcheck/mce.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/mcheck/mce.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/mcheck/mce.c 2010-11-30 12:37:10.000000000 -0600
@@ -326,7 +326,7 @@ static void mce_panic(char *msg, struct
static int msr_to_offset(u32 msr)
{
- unsigned bank = __get_cpu_var(injectm.bank);
+ unsigned bank = __this_cpu_read(injectm.bank);
if (msr == rip_msr)
return offsetof(struct mce, ip);
@@ -346,7 +346,7 @@ static u64 mce_rdmsrl(u32 msr)
{
u64 v;
- if (__get_cpu_var(injectm).finished) {
+ if (__this_cpu_read(injectm.finished)) {
int offset = msr_to_offset(msr);
if (offset < 0)
@@ -369,7 +369,7 @@ static u64 mce_rdmsrl(u32 msr)
static void mce_wrmsrl(u32 msr, u64 v)
{
- if (__get_cpu_var(injectm).finished) {
+ if (__this_cpu_read(injectm.finished)) {
int offset = msr_to_offset(msr);
if (offset >= 0)
Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/perf_event.c 2010-11-30 12:37:10.000000000 -0600
@@ -968,8 +968,7 @@ x86_perf_event_set_period(struct perf_ev
static void x86_pmu_enable_event(struct perf_event *event)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- if (cpuc->enabled)
+ if (__this_cpu_read(cpu_hw_events.enabled))
__x86_pmu_enable_event(&event->hw,
ARCH_PERFMON_EVENTSEL_ENABLE);
}
@@ -1108,12 +1107,11 @@ void perf_event_print_debug(void)
static void x86_pmu_stop(struct perf_event *event, int flags)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
+ if (__test_and_clear_bit(hwc->idx, __get_cpu_var(cpu_hw_events).active_mask)) {
x86_pmu.disable(event);
- cpuc->events[hwc->idx] = NULL;
+ __this_cpu_write(cpu_hw_events.events[hwc->idx], NULL);
WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
hwc->state |= PERF_HES_STOPPED;
}
@@ -1243,7 +1241,7 @@ perf_event_nmi_handler(struct notifier_b
break;
case DIE_NMIUNKNOWN:
this_nmi = percpu_read(irq_stat.__nmi_count);
- if (this_nmi != __get_cpu_var(pmu_nmi).marked)
+ if (this_nmi != __this_cpu_read(pmu_nmi.marked))
/* let the kernel handle the unknown nmi */
return NOTIFY_DONE;
/*
@@ -1267,8 +1265,8 @@ perf_event_nmi_handler(struct notifier_b
this_nmi = percpu_read(irq_stat.__nmi_count);
if ((handled > 1) ||
/* the next nmi could be a back-to-back nmi */
- ((__get_cpu_var(pmu_nmi).marked == this_nmi) &&
- (__get_cpu_var(pmu_nmi).handled > 1))) {
+ ((__this_cpu_read(pmu_nmi.marked) == this_nmi) &&
+ (__this_cpu_read(pmu_nmi.handled) > 1))) {
/*
* We could have two subsequent back-to-back nmis: The
* first handles more than one counter, the 2nd
@@ -1279,8 +1277,8 @@ perf_event_nmi_handler(struct notifier_b
* handling more than one counter. We will mark the
* next (3rd) and then drop it if unhandled.
*/
- __get_cpu_var(pmu_nmi).marked = this_nmi + 1;
- __get_cpu_var(pmu_nmi).handled = handled;
+ __this_cpu_write(pmu_nmi.marked, this_nmi + 1);
+ __this_cpu_write(pmu_nmi.handled, handled);
}
return NOTIFY_STOP;
@@ -1454,11 +1452,9 @@ static inline void x86_pmu_read(struct p
*/
static void x86_pmu_start_txn(struct pmu *pmu)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
perf_pmu_disable(pmu);
- cpuc->group_flag |= PERF_EVENT_TXN;
- cpuc->n_txn = 0;
+ __this_cpu_or(cpu_hw_events.group_flag, PERF_EVENT_TXN);
+ __this_cpu_write(cpu_hw_events.n_txn, 0);
}
/*
@@ -1468,14 +1464,12 @@ static void x86_pmu_start_txn(struct pmu
*/
static void x86_pmu_cancel_txn(struct pmu *pmu)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- cpuc->group_flag &= ~PERF_EVENT_TXN;
+ __this_cpu_and(cpu_hw_events.group_flag, ~PERF_EVENT_TXN);
/*
* Truncate the collected events.
*/
- cpuc->n_added -= cpuc->n_txn;
- cpuc->n_events -= cpuc->n_txn;
+ __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn));
+ __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn));
perf_pmu_enable(pmu);
}
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c 2010-11-30 12:37:10.000000000 -0600
@@ -649,7 +649,7 @@ static void intel_pmu_enable_event(struc
struct hw_perf_event *hwc = &event->hw;
if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
- if (!__get_cpu_var(cpu_hw_events).enabled)
+ if (!__this_cpu_read(cpu_hw_events.enabled))
return;
intel_pmu_enable_bts(hwc->config);
@@ -679,7 +679,7 @@ static int intel_pmu_save_and_restart(st
static void intel_pmu_reset(void)
{
- struct debug_store *ds = __get_cpu_var(cpu_hw_events).ds;
+ struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
unsigned long flags;
int idx;
Index: linux-2.6/arch/x86/kernel/ftrace.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/ftrace.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/ftrace.c 2010-11-30 12:37:10.000000000 -0600
@@ -167,9 +167,9 @@ static void ftrace_mod_code(void)
void ftrace_nmi_enter(void)
{
- __get_cpu_var(save_modifying_code) = modifying_code;
+ __this_cpu_write(save_modifying_code, modifying_code);
- if (!__get_cpu_var(save_modifying_code))
+ if (!__this_cpu_read(save_modifying_code))
return;
if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
@@ -183,7 +183,7 @@ void ftrace_nmi_enter(void)
void ftrace_nmi_exit(void)
{
- if (!__get_cpu_var(save_modifying_code))
+ if (!__this_cpu_read(save_modifying_code))
return;
/* Finish all executions before clearing nmi_running */
Index: linux-2.6/arch/x86/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/hw_breakpoint.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/hw_breakpoint.c 2010-11-30 12:37:10.000000000 -0600
@@ -122,7 +122,7 @@ int arch_install_hw_breakpoint(struct pe
return -EBUSY;
set_debugreg(info->address, i);
- __get_cpu_var(cpu_debugreg[i]) = info->address;
+ __this_cpu_write(cpu_debugreg[i], info->address);
dr7 = &__get_cpu_var(cpu_dr7);
*dr7 |= encode_dr7(i, info->len, info->type);
@@ -397,12 +397,12 @@ void flush_ptrace_hw_breakpoint(struct t
void hw_breakpoint_restore(void)
{
- set_debugreg(__get_cpu_var(cpu_debugreg[0]), 0);
- set_debugreg(__get_cpu_var(cpu_debugreg[1]), 1);
- set_debugreg(__get_cpu_var(cpu_debugreg[2]), 2);
- set_debugreg(__get_cpu_var(cpu_debugreg[3]), 3);
+ set_debugreg(__this_cpu_read(cpu_debugreg[0]), 0);
+ set_debugreg(__this_cpu_read(cpu_debugreg[1]), 1);
+ set_debugreg(__this_cpu_read(cpu_debugreg[2]), 2);
+ set_debugreg(__this_cpu_read(cpu_debugreg[3]), 3);
set_debugreg(current->thread.debugreg6, 6);
- set_debugreg(__get_cpu_var(cpu_dr7), 7);
+ set_debugreg(__this_cpu_read(cpu_dr7), 7);
}
EXPORT_SYMBOL_GPL(hw_breakpoint_restore);
Index: linux-2.6/arch/x86/kernel/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/irq.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/irq.c 2010-11-30 12:37:10.000000000 -0600
@@ -234,7 +234,7 @@ unsigned int __irq_entry do_IRQ(struct p
exit_idle();
irq_enter();
- irq = __get_cpu_var(vector_irq)[vector];
+ irq = __this_cpu_read(vector_irq[vector]);
if (!handle_irq(irq, regs)) {
ack_APIC_irq();
@@ -350,12 +350,12 @@ void fixup_irqs(void)
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
unsigned int irr;
- if (__get_cpu_var(vector_irq)[vector] < 0)
+ if (__this_cpu_read(vector_irq[vector]) < 0)
continue;
irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
if (irr & (1 << (vector % 32))) {
- irq = __get_cpu_var(vector_irq)[vector];
+ irq = __this_cpu_read(vector_irq[vector]);
data = irq_get_irq_data(irq);
raw_spin_lock(&desc->lock);
Index: linux-2.6/arch/x86/kernel/irq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/irq_32.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/irq_32.c 2010-11-30 12:37:10.000000000 -0600
@@ -79,7 +79,7 @@ execute_on_irq_stack(int overflow, struc
u32 *isp, arg1, arg2;
curctx = (union irq_ctx *) current_thread_info();
- irqctx = __get_cpu_var(hardirq_ctx);
+ irqctx = __this_cpu_read(hardirq_ctx);
/*
* this is where we switch to the IRQ stack. However, if we are
@@ -166,7 +166,7 @@ asmlinkage void do_softirq(void)
if (local_softirq_pending()) {
curctx = current_thread_info();
- irqctx = __get_cpu_var(softirq_ctx);
+ irqctx = __this_cpu_read(softirq_ctx);
irqctx->tinfo.task = curctx->task;
irqctx->tinfo.previous_esp = current_stack_pointer;
Index: linux-2.6/arch/x86/kernel/tsc.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/tsc.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kernel/tsc.c 2010-11-30 12:37:10.000000000 -0600
@@ -659,7 +659,7 @@ void restore_sched_clock_state(void)
local_irq_save(flags);
- __get_cpu_var(cyc2ns_offset) = 0;
+ __this_cpu_write(cyc2ns_offset, 0);
offset = cyc2ns_suspend - sched_clock();
for_each_possible_cpu(cpu)
Index: linux-2.6/arch/x86/kvm/x86.c
===================================================================
--- linux-2.6.orig/arch/x86/kvm/x86.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/kvm/x86.c 2010-11-30 12:37:10.000000000 -0600
@@ -981,7 +981,7 @@ static inline u64 nsec_to_cycles(u64 nse
if (kvm_tsc_changes_freq())
printk_once(KERN_WARNING
"kvm: unreliable cycle conversion on adjustable rate TSC\n");
- ret = nsec * __get_cpu_var(cpu_tsc_khz);
+ ret = nsec * __this_cpu_read(cpu_tsc_khz);
do_div(ret, USEC_PER_SEC);
return ret;
}
@@ -1066,7 +1066,7 @@ static int kvm_guest_time_update(struct
local_irq_save(flags);
kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp);
kernel_ns = get_kernel_ns();
- this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
+ this_tsc_khz = __this_cpu_read(cpu_tsc_khz);
if (unlikely(this_tsc_khz == 0)) {
local_irq_restore(flags);
@@ -4432,7 +4432,7 @@ EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
static void tsc_bad(void *info)
{
- __get_cpu_var(cpu_tsc_khz) = 0;
+ __this_cpu_write(cpu_tsc_khz, 0);
}
static void tsc_khz_changed(void *data)
@@ -4446,7 +4446,7 @@ static void tsc_khz_changed(void *data)
khz = cpufreq_quick_get(raw_smp_processor_id());
if (!khz)
khz = tsc_khz;
- __get_cpu_var(cpu_tsc_khz) = khz;
+ __this_cpu_write(cpu_tsc_khz, khz);
}
static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
Index: linux-2.6/arch/x86/oprofile/nmi_int.c
===================================================================
--- linux-2.6.orig/arch/x86/oprofile/nmi_int.c 2010-11-30 12:35:38.000000000 -0600
+++ linux-2.6/arch/x86/oprofile/nmi_int.c 2010-11-30 12:37:10.000000000 -0600
@@ -143,7 +143,7 @@ static inline int has_mux(void)
inline int op_x86_phys_to_virt(int phys)
{
- return __get_cpu_var(switch_index) + phys;
+ return __this_cpu_read(switch_index) + phys;
}
inline int op_x86_virt_to_phys(int virt)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 11/18] x86: Use this_cpu_ops for current_cpu_data accesses
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (9 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 10/18] x86: Use this_cpu_ops to optimize code Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 12/18] Core: Replace __get_cpu_var with __this_cpu_read if not used for an address Christoph Lameter
` (7 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Yinghai Lu, Ingo Molnar, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: x86_current_cpu_data --]
[-- Type: text/plain, Size: 3283 bytes --]
Current_cpu_data accesses are per cpu accesses. We can also use
this_cpu_ops if a scalar is retrieved.
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 2 +-
arch/x86/kernel/cpu/intel_cacheinfo.c | 4 ++--
arch/x86/kernel/smpboot.c | 10 +++++-----
3 files changed, 8 insertions(+), 8 deletions(-)
Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c 2010-11-30 11:53:03.000000000 -0600
+++ linux-2.6/arch/x86/kernel/smpboot.c 2010-11-30 11:57:02.000000000 -0600
@@ -430,7 +430,7 @@ void __cpuinit set_cpu_sibling_map(int c
cpumask_set_cpu(cpu, c->llc_shared_map);
- if (current_cpu_data.x86_max_cores == 1) {
+ if (__this_cpu_read(cpu_info.x86_max_cores) == 1) {
cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu));
c->booted_cores = 1;
return;
@@ -1377,7 +1377,7 @@ void play_dead_common(void)
mb();
/* Ack it */
- __get_cpu_var(cpu_state) = CPU_DEAD;
+ __this_cpu_write(cpu_state, CPU_DEAD);
/*
* With physical CPU hotplug, we should halt the cpu
@@ -1401,7 +1401,7 @@ static inline void mwait_play_dead(void)
return;
if (!cpu_has(¤t_cpu_data, X86_FEATURE_CLFLSH))
return;
- if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+ if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF)
return;
eax = CPUID_MWAIT_LEAF;
@@ -1452,7 +1452,7 @@ static inline void mwait_play_dead(void)
static inline void hlt_play_dead(void)
{
- if (current_cpu_data.x86 >= 4)
+ if (__this_cpu_read(cpu_info.x86) >= 4)
wbinvd();
while (1) {
Index: linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2010-11-30 11:53:03.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2010-11-30 11:53:33.000000000 -0600
@@ -521,7 +521,7 @@ static void check_supported_cpu(void *_r
*rc = -ENODEV;
- if (current_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
return;
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
Index: linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/intel_cacheinfo.c 2010-11-30 11:53:03.000000000 -0600
+++ linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c 2010-11-30 11:53:33.000000000 -0600
@@ -266,7 +266,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_
line_size = l2.line_size;
lines_per_tag = l2.lines_per_tag;
/* cpu_data has errata corrections for K7 applied */
- size_in_kb = current_cpu_data.x86_cache_size;
+ size_in_kb = __this_cpu_read(cpu_info.x86_cache_size);
break;
case 3:
if (!l3.val)
@@ -288,7 +288,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_
eax->split.type = types[leaf];
eax->split.level = levels[leaf];
eax->split.num_threads_sharing = 0;
- eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
+ eax->split.num_cores_on_die = __this_cpu_read(cpu_info.x86_max_cores) - 1;
if (assoc == 0xffff)
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 12/18] Core: Replace __get_cpu_var with __this_cpu_read if not used for an address.
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (10 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 11/18] x86: Use this_cpu_ops for current_cpu_data accesses Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 13/18] drivers: " Christoph Lameter
` (6 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Hugh Dickins, Thomas Gleixner, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_core --]
[-- Type: text/plain, Size: 17472 bytes --]
__get_cpu_var() can be replaced with this_cpu_read and will then use a single
read instruction with implied address calculation to access the correct per cpu
instance.
However, the address of a per cpu variable passed to __this_cpu_read() cannot be
determed (since its an implied address conversion through segment prefixes).
Therefore apply this only to uses of __get_cpu_var where the addres of the
variable is not used.
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Hugh Dickins <hughd@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/asm-generic/irq_regs.h | 8 +++----
include/linux/elevator.h | 12 ++---------
include/linux/kernel_stat.h | 2 -
kernel/exit.c | 2 -
kernel/fork.c | 2 -
kernel/hrtimer.c | 2 -
kernel/printk.c | 4 +--
kernel/rcutree.c | 4 +--
kernel/softirq.c | 44 ++++++++++++++++++++---------------------
kernel/time/tick-common.c | 2 -
kernel/time/tick-oneshot.c | 4 +--
kernel/watchdog.c | 36 ++++++++++++++++-----------------
mm/slab.c | 6 ++---
13 files changed, 61 insertions(+), 67 deletions(-)
Index: linux-2.6/mm/slab.c
===================================================================
--- linux-2.6.orig/mm/slab.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/mm/slab.c 2010-11-30 12:41:14.000000000 -0600
@@ -829,12 +829,12 @@ static void init_reap_node(int cpu)
static void next_reap_node(void)
{
- int node = __get_cpu_var(slab_reap_node);
+ int node = __this_cpu_read(slab_reap_node);
node = next_node(node, node_online_map);
if (unlikely(node >= MAX_NUMNODES))
node = first_node(node_online_map);
- __get_cpu_var(slab_reap_node) = node;
+ __this_cpu_write(slab_reap_node, node);
}
#else
@@ -1012,7 +1012,7 @@ static void __drain_alien_cache(struct k
*/
static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3)
{
- int node = __get_cpu_var(slab_reap_node);
+ int node = __this_cpu_read(slab_reap_node);
if (l3->alien) {
struct array_cache *ac = l3->alien[node];
Index: linux-2.6/kernel/rcutree.c
===================================================================
--- linux-2.6.orig/kernel/rcutree.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/rcutree.c 2010-11-30 12:41:14.000000000 -0600
@@ -367,8 +367,8 @@ void rcu_irq_exit(void)
WARN_ON_ONCE(rdtp->dynticks & 0x1);
/* If the interrupt queued a callback, get out of dyntick mode. */
- if (__get_cpu_var(rcu_sched_data).nxtlist ||
- __get_cpu_var(rcu_bh_data).nxtlist)
+ if (__this_cpu_read(rcu_sched_data.nxtlist) ||
+ __this_cpu_read(rcu_bh_data.nxtlist))
set_need_resched();
}
Index: linux-2.6/kernel/softirq.c
===================================================================
--- linux-2.6.orig/kernel/softirq.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/softirq.c 2010-11-30 12:41:14.000000000 -0600
@@ -70,7 +70,7 @@ char *softirq_to_name[NR_SOFTIRQS] = {
static void wakeup_softirqd(void)
{
/* Interrupts are disabled: no need to stop preemption */
- struct task_struct *tsk = __get_cpu_var(ksoftirqd);
+ struct task_struct *tsk = __this_cpu_read(ksoftirqd);
if (tsk && tsk->state != TASK_RUNNING)
wake_up_process(tsk);
@@ -388,8 +388,8 @@ void __tasklet_schedule(struct tasklet_s
local_irq_save(flags);
t->next = NULL;
- *__get_cpu_var(tasklet_vec).tail = t;
- __get_cpu_var(tasklet_vec).tail = &(t->next);
+ *__this_cpu_read(tasklet_vec.tail) = t;
+ __this_cpu_write(tasklet_vec.tail, &(t->next));
raise_softirq_irqoff(TASKLET_SOFTIRQ);
local_irq_restore(flags);
}
@@ -402,8 +402,8 @@ void __tasklet_hi_schedule(struct taskle
local_irq_save(flags);
t->next = NULL;
- *__get_cpu_var(tasklet_hi_vec).tail = t;
- __get_cpu_var(tasklet_hi_vec).tail = &(t->next);
+ *__this_cpu_read(tasklet_hi_vec.tail) = t;
+ __this_cpu_write(tasklet_hi_vec.tail, &(t->next));
raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_restore(flags);
}
@@ -414,8 +414,8 @@ void __tasklet_hi_schedule_first(struct
{
BUG_ON(!irqs_disabled());
- t->next = __get_cpu_var(tasklet_hi_vec).head;
- __get_cpu_var(tasklet_hi_vec).head = t;
+ t->next = __this_cpu_read(tasklet_hi_vec.head);
+ __this_cpu_write(tasklet_hi_vec.head, t);
__raise_softirq_irqoff(HI_SOFTIRQ);
}
@@ -426,9 +426,9 @@ static void tasklet_action(struct softir
struct tasklet_struct *list;
local_irq_disable();
- list = __get_cpu_var(tasklet_vec).head;
- __get_cpu_var(tasklet_vec).head = NULL;
- __get_cpu_var(tasklet_vec).tail = &__get_cpu_var(tasklet_vec).head;
+ list = __this_cpu_read(tasklet_vec.head);
+ __this_cpu_write(tasklet_vec.head, NULL);
+ __this_cpu_write(tasklet_vec.tail, &__get_cpu_var(tasklet_vec).head);
local_irq_enable();
while (list) {
@@ -449,8 +449,8 @@ static void tasklet_action(struct softir
local_irq_disable();
t->next = NULL;
- *__get_cpu_var(tasklet_vec).tail = t;
- __get_cpu_var(tasklet_vec).tail = &(t->next);
+ *__this_cpu_read(tasklet_vec.tail) = t;
+ __this_cpu_write(tasklet_vec.tail, &(t->next));
__raise_softirq_irqoff(TASKLET_SOFTIRQ);
local_irq_enable();
}
@@ -461,9 +461,9 @@ static void tasklet_hi_action(struct sof
struct tasklet_struct *list;
local_irq_disable();
- list = __get_cpu_var(tasklet_hi_vec).head;
- __get_cpu_var(tasklet_hi_vec).head = NULL;
- __get_cpu_var(tasklet_hi_vec).tail = &__get_cpu_var(tasklet_hi_vec).head;
+ list = __this_cpu_read(tasklet_hi_vec.head);
+ __this_cpu_write(tasklet_hi_vec.head, NULL);
+ __this_cpu_write(tasklet_hi_vec.tail, &__get_cpu_var(tasklet_hi_vec).head);
local_irq_enable();
while (list) {
@@ -484,8 +484,8 @@ static void tasklet_hi_action(struct sof
local_irq_disable();
t->next = NULL;
- *__get_cpu_var(tasklet_hi_vec).tail = t;
- __get_cpu_var(tasklet_hi_vec).tail = &(t->next);
+ *__this_cpu_read(tasklet_hi_vec.tail) = t;
+ __this_cpu_write(tasklet_hi_vec.tail, &(t->next));
__raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_enable();
}
@@ -802,18 +802,18 @@ static void takeover_tasklets(unsigned i
/* Find end, append list for that CPU. */
if (&per_cpu(tasklet_vec, cpu).head != per_cpu(tasklet_vec, cpu).tail) {
- *(__get_cpu_var(tasklet_vec).tail) = per_cpu(tasklet_vec, cpu).head;
- __get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).tail;
+ *__this_cpu_read(tasklet_vec.tail) = per_cpu(tasklet_vec, cpu).head;
+ this_cpu_write(tasklet_vec.tail, per_cpu(tasklet_vec, cpu).tail);
per_cpu(tasklet_vec, cpu).head = NULL;
per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head;
}
raise_softirq_irqoff(TASKLET_SOFTIRQ);
if (&per_cpu(tasklet_hi_vec, cpu).head != per_cpu(tasklet_hi_vec, cpu).tail) {
- *__get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).head;
- __get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).tail;
+ *__this_cpuo_read(tasklet_hi_vec.tail) = per_cpu(tasklet_hi_vec, cpu).head;
+ __this_cpu_write(tasklet_hi_vec.tail, per_cpu(tasklet_hi_vec, cpu).tail;
per_cpu(tasklet_hi_vec, cpu).head = NULL;
- per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head;
+ per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head);
}
raise_softirq_irqoff(HI_SOFTIRQ);
Index: linux-2.6/kernel/time/tick-common.c
===================================================================
--- linux-2.6.orig/kernel/time/tick-common.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/time/tick-common.c 2010-11-30 12:41:14.000000000 -0600
@@ -49,7 +49,7 @@ struct tick_device *tick_get_device(int
*/
int tick_is_oneshot_available(void)
{
- struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
+ struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
return dev && (dev->features & CLOCK_EVT_FEAT_ONESHOT);
}
Index: linux-2.6/kernel/time/tick-oneshot.c
===================================================================
--- linux-2.6.orig/kernel/time/tick-oneshot.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/time/tick-oneshot.c 2010-11-30 12:41:14.000000000 -0600
@@ -95,7 +95,7 @@ int tick_dev_program_event(struct clock_
*/
int tick_program_event(ktime_t expires, int force)
{
- struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
+ struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
return tick_dev_program_event(dev, expires, force);
}
@@ -167,7 +167,7 @@ int tick_oneshot_mode_active(void)
int ret;
local_irq_save(flags);
- ret = __get_cpu_var(tick_cpu_device).mode == TICKDEV_MODE_ONESHOT;
+ ret = __this_cpu_read(tick_cpu_device.mode) == TICKDEV_MODE_ONESHOT;
local_irq_restore(flags);
return ret;
Index: linux-2.6/kernel/watchdog.c
===================================================================
--- linux-2.6.orig/kernel/watchdog.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/watchdog.c 2010-11-30 12:41:14.000000000 -0600
@@ -116,12 +116,12 @@ static void __touch_watchdog(void)
{
int this_cpu = smp_processor_id();
- __get_cpu_var(watchdog_touch_ts) = get_timestamp(this_cpu);
+ __this_cpu_write(watchdog_touch_ts, get_timestamp(this_cpu));
}
void touch_softlockup_watchdog(void)
{
- __raw_get_cpu_var(watchdog_touch_ts) = 0;
+ __this_cpu_write(watchdog_touch_ts, 0);
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
@@ -165,12 +165,12 @@ void touch_softlockup_watchdog_sync(void
/* watchdog detector functions */
static int is_hardlockup(void)
{
- unsigned long hrint = __get_cpu_var(hrtimer_interrupts);
+ unsigned long hrint = __this_cpu_read(hrtimer_interrupts);
- if (__get_cpu_var(hrtimer_interrupts_saved) == hrint)
+ if (__this_cpu_read(hrtimer_interrupts_saved) == hrint)
return 1;
- __get_cpu_var(hrtimer_interrupts_saved) = hrint;
+ __this_cpu_write(hrtimer_interrupts_saved, hrint);
return 0;
}
#endif
@@ -203,8 +203,8 @@ static void watchdog_overflow_callback(s
/* Ensure the watchdog never gets throttled */
event->hw.interrupts = 0;
- if (__get_cpu_var(watchdog_nmi_touch) == true) {
- __get_cpu_var(watchdog_nmi_touch) = false;
+ if (__this_cpu_read(watchdog_nmi_touch) == true) {
+ __this_cpu_write(watchdog_nmi_touch, false);
return;
}
@@ -218,7 +218,7 @@ static void watchdog_overflow_callback(s
int this_cpu = smp_processor_id();
/* only print hardlockups once */
- if (__get_cpu_var(hard_watchdog_warn) == true)
+ if (__this_cpu_read(hard_watchdog_warn) == true)
return;
if (hardlockup_panic)
@@ -226,16 +226,16 @@ static void watchdog_overflow_callback(s
else
WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu);
- __get_cpu_var(hard_watchdog_warn) = true;
+ __this_cpu_write(hard_watchdog_warn, true);
return;
}
- __get_cpu_var(hard_watchdog_warn) = false;
+ __this_cpu_write(hard_watchdog_warn, false);
return;
}
static void watchdog_interrupt_count(void)
{
- __get_cpu_var(hrtimer_interrupts)++;
+ __this_cpu_inc(hrtimer_interrupts);
}
#else
static inline void watchdog_interrupt_count(void) { return; }
@@ -244,7 +244,7 @@ static inline void watchdog_interrupt_co
/* watchdog kicker functions */
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
{
- unsigned long touch_ts = __get_cpu_var(watchdog_touch_ts);
+ unsigned long touch_ts = __this_cpu_read(watchdog_touch_ts);
struct pt_regs *regs = get_irq_regs();
int duration;
@@ -252,18 +252,18 @@ static enum hrtimer_restart watchdog_tim
watchdog_interrupt_count();
/* kick the softlockup detector */
- wake_up_process(__get_cpu_var(softlockup_watchdog));
+ wake_up_process(__this_cpu_read(softlockup_watchdog));
/* .. and repeat */
hrtimer_forward_now(hrtimer, ns_to_ktime(get_sample_period()));
if (touch_ts == 0) {
- if (unlikely(__get_cpu_var(softlockup_touch_sync))) {
+ if (unlikely(__this_cpu_read(softlockup_touch_sync))) {
/*
* If the time stamp was touched atomically
* make sure the scheduler tick is up to date.
*/
- __get_cpu_var(softlockup_touch_sync) = false;
+ __this_cpu_write(softlockup_touch_sync, false);
sched_clock_tick();
}
__touch_watchdog();
@@ -279,7 +279,7 @@ static enum hrtimer_restart watchdog_tim
duration = is_softlockup(touch_ts);
if (unlikely(duration)) {
/* only warn once */
- if (__get_cpu_var(soft_watchdog_warn) == true)
+ if (__this_cpu_read(soft_watchdog_warn) == true)
return HRTIMER_RESTART;
printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
@@ -294,9 +294,9 @@ static enum hrtimer_restart watchdog_tim
if (softlockup_panic)
panic("softlockup: hung tasks");
- __get_cpu_var(soft_watchdog_warn) = true;
+ __this_cpu_write(soft_watchdog_warn, true);
} else
- __get_cpu_var(soft_watchdog_warn) = false;
+ __this_cpu_write(soft_watchdog_warn, false);
return HRTIMER_RESTART;
}
Index: linux-2.6/kernel/printk.c
===================================================================
--- linux-2.6.orig/kernel/printk.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/printk.c 2010-11-30 12:41:14.000000000 -0600
@@ -1074,8 +1074,8 @@ static DEFINE_PER_CPU(int, printk_pendin
void printk_tick(void)
{
- if (__get_cpu_var(printk_pending)) {
- __get_cpu_var(printk_pending) = 0;
+ if (__this_cpu_read(printk_pending)) {
+ __this_cpu_write(printk_pending, 0);
wake_up_interruptible(&log_wait);
}
}
Index: linux-2.6/include/asm-generic/irq_regs.h
===================================================================
--- linux-2.6.orig/include/asm-generic/irq_regs.h 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/include/asm-generic/irq_regs.h 2010-11-30 12:41:14.000000000 -0600
@@ -22,15 +22,15 @@ DECLARE_PER_CPU(struct pt_regs *, __irq_
static inline struct pt_regs *get_irq_regs(void)
{
- return __get_cpu_var(__irq_regs);
+ return __this_cpu_read(__irq_regs);
}
static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
{
- struct pt_regs *old_regs, **pp_regs = &__get_cpu_var(__irq_regs);
+ struct pt_regs *old_regs;
- old_regs = *pp_regs;
- *pp_regs = new_regs;
+ old_regs = __this_cpu_read(__irq_regs);
+ __this_cpu_write(__irq_regs, new_regs);
return old_regs;
}
Index: linux-2.6/include/linux/elevator.h
===================================================================
--- linux-2.6.orig/include/linux/elevator.h 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/include/linux/elevator.h 2010-11-30 12:41:14.000000000 -0600
@@ -195,15 +195,9 @@ enum {
/*
* io context count accounting
*/
-#define elv_ioc_count_mod(name, __val) \
- do { \
- preempt_disable(); \
- __get_cpu_var(name) += (__val); \
- preempt_enable(); \
- } while (0)
-
-#define elv_ioc_count_inc(name) elv_ioc_count_mod(name, 1)
-#define elv_ioc_count_dec(name) elv_ioc_count_mod(name, -1)
+#define elv_ioc_count_mod(name, __val) this_cpu_add(name, __val)
+#define elv_ioc_count_inc(name) this_cpu_inc(name)
+#define elv_ioc_count_dec(name) this_cpu_dec(name)
#define elv_ioc_count_read(name) \
({ \
Index: linux-2.6/include/linux/kernel_stat.h
===================================================================
--- linux-2.6.orig/include/linux/kernel_stat.h 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/include/linux/kernel_stat.h 2010-11-30 12:41:14.000000000 -0600
@@ -47,7 +47,7 @@ extern unsigned long long nr_context_swi
#ifndef CONFIG_GENERIC_HARDIRQS
#define kstat_irqs_this_cpu(irq) \
- (kstat_this_cpu.irqs[irq])
+ (this_cpu_read(kstat.irqs[irq])
struct irq_desc;
Index: linux-2.6/kernel/exit.c
===================================================================
--- linux-2.6.orig/kernel/exit.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/exit.c 2010-11-30 12:41:14.000000000 -0600
@@ -69,7 +69,7 @@ static void __unhash_process(struct task
list_del_rcu(&p->tasks);
list_del_init(&p->sibling);
- __get_cpu_var(process_counts)--;
+ __this_cpu_dec(process_counts);
}
list_del_rcu(&p->thread_group);
}
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/fork.c 2010-11-30 12:41:14.000000000 -0600
@@ -1282,7 +1282,7 @@ static struct task_struct *copy_process(
attach_pid(p, PIDTYPE_SID, task_session(current));
list_add_tail(&p->sibling, &p->real_parent->children);
list_add_tail_rcu(&p->tasks, &init_task.tasks);
- __get_cpu_var(process_counts)++;
+ __this_cpu_inc(process_counts);
}
attach_pid(p, PIDTYPE_PID, pid);
nr_threads++;
Index: linux-2.6/kernel/hrtimer.c
===================================================================
--- linux-2.6.orig/kernel/hrtimer.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/kernel/hrtimer.c 2010-11-30 12:41:14.000000000 -0600
@@ -497,7 +497,7 @@ static inline int hrtimer_is_hres_enable
*/
static inline int hrtimer_hres_active(void)
{
- return __get_cpu_var(hrtimer_bases).hres_active;
+ return __this_cpu_read(hrtimer_bases.hres_active);
}
/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 13/18] drivers: Replace __get_cpu_var with __this_cpu_read if not used for an address.
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (11 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 12/18] Core: Replace __get_cpu_var with __this_cpu_read if not used for an address Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 14/18] lguest: Use this_cpu_ops Christoph Lameter
` (5 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Neil Horman, Martin Schwidefsky, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_drivers --]
[-- Type: text/plain, Size: 4616 bytes --]
__get_cpu_var() can be replaced with this_cpu_read and will then use a single
read instruction with implied address calculation to access the correct per cpu
instance.
However, the address of a per cpu variable passed to __this_cpu_read() cannot be
determed (since its an implied address conversion through segment prefixes).
Therefore apply this only to uses of __get_cpu_var where the addres of the
variable is not used.
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
drivers/acpi/processor_idle.c | 6 +++---
drivers/char/random.c | 2 +-
drivers/cpuidle/cpuidle.c | 2 +-
drivers/s390/cio/cio.c | 2 +-
drivers/staging/speakup/fakekey.c | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
Index: linux-2.6/drivers/acpi/processor_idle.c
===================================================================
--- linux-2.6.orig/drivers/acpi/processor_idle.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/drivers/acpi/processor_idle.c 2010-11-30 12:40:47.000000000 -0600
@@ -746,7 +746,7 @@ static int acpi_idle_enter_c1(struct cpu
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- pr = __get_cpu_var(processors);
+ pr = __this_cpu_read(processors);
if (unlikely(!pr))
return 0;
@@ -787,7 +787,7 @@ static int acpi_idle_enter_simple(struct
s64 idle_time_ns;
s64 idle_time;
- pr = __get_cpu_var(processors);
+ pr = __this_cpu_read(processors);
if (unlikely(!pr))
return 0;
@@ -864,7 +864,7 @@ static int acpi_idle_enter_bm(struct cpu
s64 idle_time;
- pr = __get_cpu_var(processors);
+ pr = __this_cpu_read(processors);
if (unlikely(!pr))
return 0;
Index: linux-2.6/drivers/char/random.c
===================================================================
--- linux-2.6.orig/drivers/char/random.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/drivers/char/random.c 2010-11-30 12:40:47.000000000 -0600
@@ -626,7 +626,7 @@ static void add_timer_randomness(struct
preempt_disable();
/* if over the trickle threshold, use only 1 in 4096 samples */
if (input_pool.entropy_count > trickle_thresh &&
- (__get_cpu_var(trickle_count)++ & 0xfff))
+ (__this_cpu_inc_return(trickle_count) & 0xfff))
goto out;
sample.jiffies = jiffies;
Index: linux-2.6/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-2.6.orig/drivers/cpuidle/cpuidle.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/drivers/cpuidle/cpuidle.c 2010-11-30 12:40:47.000000000 -0600
@@ -49,7 +49,7 @@ static int __cpuidle_register_device(str
*/
static void cpuidle_idle_call(void)
{
- struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices);
+ struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_state *target_state;
int next_state;
Index: linux-2.6/drivers/s390/cio/cio.c
===================================================================
--- linux-2.6.orig/drivers/s390/cio/cio.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/drivers/s390/cio/cio.c 2010-11-30 12:40:47.000000000 -0600
@@ -619,7 +619,7 @@ void __irq_entry do_IRQ(struct pt_regs *
s390_idle_check(regs, S390_lowcore.int_clock,
S390_lowcore.async_enter_timer);
irq_enter();
- __get_cpu_var(s390_idle).nohz_delay = 1;
+ __this_cpu_write(s390_idle.nohz_delay, 1);
if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
/* Serve timer interrupts first. */
clock_comparator_work();
Index: linux-2.6/drivers/staging/speakup/fakekey.c
===================================================================
--- linux-2.6.orig/drivers/staging/speakup/fakekey.c 2010-11-30 12:40:22.000000000 -0600
+++ linux-2.6/drivers/staging/speakup/fakekey.c 2010-11-30 12:40:47.000000000 -0600
@@ -79,10 +79,10 @@ void speakup_fake_down_arrow(void)
/* don't change CPU */
preempt_disable();
- __get_cpu_var(reporting_keystroke) = true;
+ __this_cpu_write(reporting_keystroke), true);
input_report_key(virt_keyboard, KEY_DOWN, PRESSED);
input_report_key(virt_keyboard, KEY_DOWN, RELEASED);
- __get_cpu_var(reporting_keystroke) = false;
+ __this_cpu_write(reporting_keystroke, false);
/* reenable preemption */
preempt_enable();
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 14/18] lguest: Use this_cpu_ops
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (12 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 13/18] drivers: " Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-12-06 7:46 ` Rusty Russell
2010-11-30 19:07 ` [thisops uV3 15/18] Xen: " Christoph Lameter
` (4 subsequent siblings)
18 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Rusty Russell, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_lguest --]
[-- Type: text/plain, Size: 2587 bytes --]
Use this_cpu_ops in a couple of places in lguest.
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/lguest/boot.c | 2 +-
drivers/lguest/page_tables.c | 2 +-
drivers/lguest/x86/core.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c 2010-11-30 12:22:34.000000000 -0600
+++ linux-2.6/arch/x86/lguest/boot.c 2010-11-30 12:24:08.000000000 -0600
@@ -821,7 +821,7 @@ static void __init lguest_init_IRQ(void)
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
/* Some systems map "vectors" to interrupts weirdly. Not us! */
- __get_cpu_var(vector_irq)[i] = i - FIRST_EXTERNAL_VECTOR;
+ __this_cpu_write(vector_irq[i]) = i - FIRST_EXTERNAL_VECTOR;
if (i != SYSCALL_VECTOR)
set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
Index: linux-2.6/drivers/lguest/page_tables.c
===================================================================
--- linux-2.6.orig/drivers/lguest/page_tables.c 2010-11-30 12:22:34.000000000 -0600
+++ linux-2.6/drivers/lguest/page_tables.c 2010-11-30 12:24:08.000000000 -0600
@@ -1137,7 +1137,7 @@ void free_guest_pagetable(struct lguest
*/
void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
{
- pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
+ pte_t *switcher_pte_page = __this_cpu_read(switcher_pte_pages);
pte_t regs_pte;
#ifdef CONFIG_X86_PAE
Index: linux-2.6/drivers/lguest/x86/core.c
===================================================================
--- linux-2.6.orig/drivers/lguest/x86/core.c 2010-11-30 12:22:34.000000000 -0600
+++ linux-2.6/drivers/lguest/x86/core.c 2010-11-30 12:24:08.000000000 -0600
@@ -90,8 +90,8 @@ static void copy_in_guest_info(struct lg
* meanwhile). If that's not the case, we pretend everything in the
* Guest has changed.
*/
- if (__get_cpu_var(lg_last_cpu) != cpu || cpu->last_pages != pages) {
- __get_cpu_var(lg_last_cpu) = cpu;
+ if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) {
+ __this_cpu_read(lg_last_cpu) = cpu;
cpu->last_pages = pages;
cpu->changed = CHANGED_ALL;
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 14/18] lguest: Use this_cpu_ops
2010-11-30 19:07 ` [thisops uV3 14/18] lguest: Use this_cpu_ops Christoph Lameter
@ 2010-12-06 7:46 ` Rusty Russell
2010-12-06 15:54 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Rusty Russell @ 2010-12-06 7:46 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
On Wed, 1 Dec 2010 05:37:21 am Christoph Lameter wrote:
> Use this_cpu_ops in a couple of places in lguest.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Signed-off-by: Christoph Lameter <cl@linux.com>
This doesn't even compile :(
I've applied it, and applied the following fixes, too:
lguest: compile fixes
arch/x86/lguest/boot.c: In function ‘lguest_init_IRQ’:
arch/x86/lguest/boot.c:824: error: macro "__this_cpu_write" requires 2 arguments, but only 1 given
arch/x86/lguest/boot.c:824: error: ‘__this_cpu_write’ undeclared (first use in this function)
arch/x86/lguest/boot.c:824: error: (Each undeclared identifier is reported only once
arch/x86/lguest/boot.c:824: error: for each function it appears in.)
drivers/lguest/x86/core.c: In function ‘copy_in_guest_info’:
drivers/lguest/x86/core.c:94: error: lvalue required as left operand of assignment
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -821,7 +821,7 @@ static void __init lguest_init_IRQ(void)
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
/* Some systems map "vectors" to interrupts weirdly. Not us! */
- __this_cpu_write(vector_irq[i]) = i - FIRST_EXTERNAL_VECTOR;
+ __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
if (i != SYSCALL_VECTOR)
set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -91,7 +91,7 @@ static void copy_in_guest_info(struct lg
* Guest has changed.
*/
if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) {
- __this_cpu_read(lg_last_cpu) = cpu;
+ __this_cpu_write(lg_last_cpu, cpu);
cpu->last_pages = pages;
cpu->changed = CHANGED_ALL;
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 14/18] lguest: Use this_cpu_ops
2010-12-06 7:46 ` Rusty Russell
@ 2010-12-06 15:54 ` Christoph Lameter
2010-12-06 16:27 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-12-06 15:54 UTC (permalink / raw)
To: Rusty Russell
Cc: akpm, Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm
On Mon, 6 Dec 2010, Rusty Russell wrote:
> This doesn't even compile :(
Yeah. I had to go through a lot of code and the build process did not
build all subsystem. Sorry.
> I've applied it, and applied the following fixes, too:
Great. Thanks.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 15/18] Xen: Use this_cpu_ops
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (13 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 14/18] lguest: Use this_cpu_ops Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 20:53 ` Jeremy Fitzhardinge
2010-11-30 19:07 ` [thisops uV3 16/18] kprobes: " Christoph Lameter
` (3 subsequent siblings)
18 siblings, 1 reply; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Jeremy Fitzhardinge, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_ops_xen --]
[-- Type: text/plain, Size: 6220 bytes --]
Use this_cpu_ops to reduce code size and simplify things in various places.
Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc:
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/xen/enlighten.c | 4 ++--
arch/x86/xen/multicalls.h | 2 +-
arch/x86/xen/spinlock.c | 8 ++++----
arch/x86/xen/time.c | 13 ++++++-------
drivers/xen/events.c | 10 +++++-----
5 files changed, 18 insertions(+), 19 deletions(-)
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c 2010-11-30 12:31:39.000000000 -0600
+++ linux-2.6/arch/x86/xen/enlighten.c 2010-11-30 12:31:42.000000000 -0600
@@ -574,8 +574,8 @@ static void xen_write_idt_entry(gate_des
preempt_disable();
- start = __get_cpu_var(idt_desc).address;
- end = start + __get_cpu_var(idt_desc).size + 1;
+ start = __this_cpu_read(idt_desc.address);
+ end = start + __this_cpu_read(idt_desc.size) + 1;
xen_mc_flush();
Index: linux-2.6/arch/x86/xen/multicalls.h
===================================================================
--- linux-2.6.orig/arch/x86/xen/multicalls.h 2010-11-30 12:31:39.000000000 -0600
+++ linux-2.6/arch/x86/xen/multicalls.h 2010-11-30 12:31:42.000000000 -0600
@@ -22,7 +22,7 @@ static inline void xen_mc_batch(void)
unsigned long flags;
/* need to disable interrupts until this entry is complete */
local_irq_save(flags);
- __get_cpu_var(xen_mc_irq_flags) = flags;
+ __this_cpu_write(xen_mc_irq_flags, flags);
}
static inline struct multicall_space xen_mc_entry(size_t args)
Index: linux-2.6/arch/x86/xen/spinlock.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/spinlock.c 2010-11-30 12:31:39.000000000 -0600
+++ linux-2.6/arch/x86/xen/spinlock.c 2010-11-30 12:31:42.000000000 -0600
@@ -159,8 +159,8 @@ static inline struct xen_spinlock *spinn
{
struct xen_spinlock *prev;
- prev = __get_cpu_var(lock_spinners);
- __get_cpu_var(lock_spinners) = xl;
+ prev = __this_cpu_read(lock_spinners);
+ __this_cpu_write(lock_spinners, xl);
wmb(); /* set lock of interest before count */
@@ -179,14 +179,14 @@ static inline void unspinning_lock(struc
asm(LOCK_PREFIX " decw %0"
: "+m" (xl->spinners) : : "memory");
wmb(); /* decrement count before restoring lock */
- __get_cpu_var(lock_spinners) = prev;
+ __this_cpu_write(lock_spinners, prev);
}
static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enable)
{
struct xen_spinlock *xl = (struct xen_spinlock *)lock;
struct xen_spinlock *prev;
- int irq = __get_cpu_var(lock_kicker_irq);
+ int irq = __this_cpu_read(lock_kicker_irq);
int ret;
u64 start;
Index: linux-2.6/arch/x86/xen/time.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/time.c 2010-11-30 12:31:39.000000000 -0600
+++ linux-2.6/arch/x86/xen/time.c 2010-11-30 12:31:42.000000000 -0600
@@ -135,24 +135,24 @@ static void do_stolen_accounting(void)
/* Add the appropriate number of ticks of stolen time,
including any left-overs from last time. */
- stolen = runnable + offline + __get_cpu_var(xen_residual_stolen);
+ stolen = runnable + offline + __this_cpu_read(xen_residual_stolen);
if (stolen < 0)
stolen = 0;
ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen);
- __get_cpu_var(xen_residual_stolen) = stolen;
+ __this_cpu_write(xen_residual_stolen, stolen);
account_steal_ticks(ticks);
/* Add the appropriate number of ticks of blocked time,
including any left-overs from last time. */
- blocked += __get_cpu_var(xen_residual_blocked);
+ blocked += __this_cpu_read(xen_residual_blocked);
if (blocked < 0)
blocked = 0;
ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
- __get_cpu_var(xen_residual_blocked) = blocked;
+ __this_cpu_write(xen_residual_blocked, blocked);
account_idle_ticks(ticks);
}
@@ -370,12 +370,11 @@ static DEFINE_PER_CPU(struct clock_event
static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = &__get_cpu_var(xen_clock_events);
irqreturn_t ret;
ret = IRQ_NONE;
- if (evt->event_handler) {
- evt->event_handler(evt);
+ if (__this_cpu_read(xen_clock_events.event_handler)) {
+ __this_cpu_read(xen_clock_events.event_handler)(evt);
ret = IRQ_HANDLED;
}
Index: linux-2.6/drivers/xen/events.c
===================================================================
--- linux-2.6.orig/drivers/xen/events.c 2010-11-30 12:31:39.000000000 -0600
+++ linux-2.6/drivers/xen/events.c 2010-11-30 12:31:42.000000000 -0600
@@ -356,7 +356,7 @@ static void unmask_evtchn(int port)
struct evtchn_unmask unmask = { .port = port };
(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
} else {
- struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
+ struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
sync_clear_bit(port, &s->evtchn_mask[0]);
@@ -1087,7 +1087,7 @@ static void __xen_evtchn_do_upcall(void)
{
int cpu = get_cpu();
struct shared_info *s = HYPERVISOR_shared_info;
- struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
+ struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
unsigned count;
do {
@@ -1095,7 +1095,7 @@ static void __xen_evtchn_do_upcall(void)
vcpu_info->evtchn_upcall_pending = 0;
- if (__get_cpu_var(xed_nesting_count)++)
+ if (__this_cpu_inc_return(xed_nesting_count))
goto out;
#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
@@ -1127,8 +1127,8 @@ static void __xen_evtchn_do_upcall(void)
BUG_ON(!irqs_disabled());
- count = __get_cpu_var(xed_nesting_count);
- __get_cpu_var(xed_nesting_count) = 0;
+ count = __this_cpu_read(xed_nesting_count);
+ __this_cpu_write(xed_nesting_count, 0);
} while (count != 1 || vcpu_info->evtchn_upcall_pending);
out:
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 15/18] Xen: Use this_cpu_ops
2010-11-30 19:07 ` [thisops uV3 15/18] Xen: " Christoph Lameter
@ 2010-11-30 20:53 ` Jeremy Fitzhardinge
2010-11-30 21:03 ` Christoph Lameter
0 siblings, 1 reply; 35+ messages in thread
From: Jeremy Fitzhardinge @ 2010-11-30 20:53 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, Pekka Enberg, Jeremy Fitzhardinge, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
On 11/30/2010 11:07 AM, Christoph Lameter wrote:
> static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
> {
> - struct clock_event_device *evt = &__get_cpu_var(xen_clock_events);
> irqreturn_t ret;
>
> ret = IRQ_NONE;
> - if (evt->event_handler) {
> - evt->event_handler(evt);
> + if (__this_cpu_read(xen_clock_events.event_handler)) {
> + __this_cpu_read(xen_clock_events.event_handler)(evt);
Really? What code does this generate? If this is generating two
segment-prefixed reads rather than getting the address and doing normal
reads on it, then I don't think it is an improvement.
The rest looks OK, I guess. How does it change the generated code?
J
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [thisops uV3 15/18] Xen: Use this_cpu_ops
2010-11-30 20:53 ` Jeremy Fitzhardinge
@ 2010-11-30 21:03 ` Christoph Lameter
0 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 21:03 UTC (permalink / raw)
To: Jeremy Fitzhardinge
Cc: akpm, Pekka Enberg, Jeremy Fitzhardinge, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
On Tue, 30 Nov 2010, Jeremy Fitzhardinge wrote:
> On 11/30/2010 11:07 AM, Christoph Lameter wrote:
> > static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
> > {
> > - struct clock_event_device *evt = &__get_cpu_var(xen_clock_events);
> > irqreturn_t ret;
> >
> > ret = IRQ_NONE;
> > - if (evt->event_handler) {
> > - evt->event_handler(evt);
> > + if (__this_cpu_read(xen_clock_events.event_handler)) {
> > + __this_cpu_read(xen_clock_events.event_handler)(evt);
>
> Really? What code does this generate? If this is generating two
> segment-prefixed reads rather than getting the address and doing normal
> reads on it, then I don't think it is an improvement.
Lets drop that hunk. No point to do optimizations at that location then.
evt is also not defined then. Without the evt address determination via
__get_cpu_var we have at least 2 prefixed load and one address
calculation to figure out the parameter to pass. No win.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 16/18] kprobes: Use this_cpu_ops
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (14 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 15/18] Xen: " Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 17/18] Connector: Use this_cpu operations Christoph Lameter
` (2 subsequent siblings)
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Jason Baron, Namhyung Kim, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_ops_kprobes --]
[-- Type: text/plain, Size: 5082 bytes --]
Use this_cpu ops in various places to optimize per cpu data access.
Cc: Jason Baron <jbaron@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
arch/x86/kernel/kprobes.c | 14 +++++++-------
include/linux/kprobes.h | 4 ++--
kernel/kprobes.c | 8 ++++----
3 files changed, 13 insertions(+), 13 deletions(-)
Index: linux-2.6/arch/x86/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/kprobes.c 2010-11-30 12:31:51.000000000 -0600
+++ linux-2.6/arch/x86/kernel/kprobes.c 2010-11-30 12:32:15.000000000 -0600
@@ -403,7 +403,7 @@ static void __kprobes save_previous_kpro
static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
kcb->kprobe_status = kcb->prev_kprobe.status;
kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags;
kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags;
@@ -412,7 +412,7 @@ static void __kprobes restore_previous_k
static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb)
{
- __get_cpu_var(current_kprobe) = p;
+ __this_cpu_write(current_kprobe, p);
kcb->kprobe_saved_flags = kcb->kprobe_old_flags
= (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
if (is_IF_modifier(p->ainsn.insn))
@@ -586,7 +586,7 @@ static int __kprobes kprobe_handler(stru
preempt_enable_no_resched();
return 1;
} else if (kprobe_running()) {
- p = __get_cpu_var(current_kprobe);
+ p = __this_cpu_read(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
setup_singlestep(p, regs, kcb, 0);
return 1;
@@ -759,11 +759,11 @@ static __used __kprobes void *trampoline
orig_ret_address = (unsigned long)ri->ret_addr;
if (ri->rp && ri->rp->handler) {
- __get_cpu_var(current_kprobe) = &ri->rp->kp;
+ __this_cpu_write(current_kprobe, &ri->rp->kp);
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
ri->ret_addr = correct_ret_addr;
ri->rp->handler(ri, regs);
- __get_cpu_var(current_kprobe) = NULL;
+ __this_cpu_write(current_kprobe, NULL);
}
recycle_rp_inst(ri, &empty_rp);
@@ -1198,10 +1198,10 @@ static void __kprobes optimized_callback
regs->ip = (unsigned long)op->kp.addr + INT3_SIZE;
regs->orig_ax = ~0UL;
- __get_cpu_var(current_kprobe) = &op->kp;
+ __this_cpu_write(current_kprobe, &op->kp);
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
opt_pre_handler(&op->kp, regs);
- __get_cpu_var(current_kprobe) = NULL;
+ __this_cpu_write(current_kprobe, NULL);
}
preempt_enable_no_resched();
}
Index: linux-2.6/include/linux/kprobes.h
===================================================================
--- linux-2.6.orig/include/linux/kprobes.h 2010-11-30 12:31:51.000000000 -0600
+++ linux-2.6/include/linux/kprobes.h 2010-11-30 12:32:15.000000000 -0600
@@ -303,12 +303,12 @@ struct hlist_head * kretprobe_inst_table
/* kprobe_running() will just return the current_kprobe on this CPU */
static inline struct kprobe *kprobe_running(void)
{
- return (__get_cpu_var(current_kprobe));
+ return (__this_cpu_read(current_kprobe));
}
static inline void reset_current_kprobe(void)
{
- __get_cpu_var(current_kprobe) = NULL;
+ __this_cpu_write(current_kprobe, NULL);
}
static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
Index: linux-2.6/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/kernel/kprobes.c 2010-11-30 12:31:51.000000000 -0600
+++ linux-2.6/kernel/kprobes.c 2010-11-30 12:32:15.000000000 -0600
@@ -317,12 +317,12 @@ void __kprobes free_optinsn_slot(kprobe_
/* We have preemption disabled.. so it is safe to use __ versions */
static inline void set_kprobe_instance(struct kprobe *kp)
{
- __get_cpu_var(kprobe_instance) = kp;
+ __this_cpu_write(kprobe_instance, kp);
}
static inline void reset_kprobe_instance(void)
{
- __get_cpu_var(kprobe_instance) = NULL;
+ __this_cpu_write(kprobe_instance, NULL);
}
/*
@@ -775,7 +775,7 @@ static void __kprobes aggr_post_handler(
static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
int trapnr)
{
- struct kprobe *cur = __get_cpu_var(kprobe_instance);
+ struct kprobe *cur = __this_cpu_read(kprobe_instance);
/*
* if we faulted "during" the execution of a user specified
@@ -790,7 +790,7 @@ static int __kprobes aggr_fault_handler(
static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
{
- struct kprobe *cur = __get_cpu_var(kprobe_instance);
+ struct kprobe *cur = __this_cpu_read(kprobe_instance);
int ret = 0;
if (cur && cur->break_handler) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 17/18] Connector: Use this_cpu operations
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (15 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 16/18] kprobes: " Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 19:07 ` [thisops uV3 18/18] Fakekey: Simplify speakup_fake_key_pressed through this_cpu_ops Christoph Lameter
2010-11-30 20:05 ` [extra] timers: Use this_cpu_read Christoph Lameter
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, Scott James Remnant, Mike Frysinger, linux-kernel,
Eric Dumazet, Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_cn_proc --]
[-- Type: text/plain, Size: 1277 bytes --]
get_seq can benefit from this_cpu_operations. Address calculation is avoided
and the increment is done using an xadd.
Cc: Scott James Remnant <scott@ubuntu.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
drivers/connector/cn_proc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Index: linux-2.6/drivers/connector/cn_proc.c
===================================================================
--- linux-2.6.orig/drivers/connector/cn_proc.c 2010-11-30 09:38:33.000000000 -0600
+++ linux-2.6/drivers/connector/cn_proc.c 2010-11-30 09:39:38.000000000 -0600
@@ -43,9 +43,10 @@ static DEFINE_PER_CPU(__u32, proc_event_
static inline void get_seq(__u32 *ts, int *cpu)
{
- *ts = get_cpu_var(proc_event_counts)++;
+ preempt_disable();
+ *ts = __this_cpu_inc(proc_event_counts);
*cpu = smp_processor_id();
- put_cpu_var(proc_event_counts);
+ preempt_enable();
}
void proc_fork_connector(struct task_struct *task)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [thisops uV3 18/18] Fakekey: Simplify speakup_fake_key_pressed through this_cpu_ops
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (16 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 17/18] Connector: Use this_cpu operations Christoph Lameter
@ 2010-11-30 19:07 ` Christoph Lameter
2010-11-30 20:05 ` [extra] timers: Use this_cpu_read Christoph Lameter
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 19:07 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, William Hubbs, linux-kernel, Eric Dumazet,
Mathieu Desnoyers, Tejun Heo, linux-mm
[-- Attachment #1: this_cpu_fake_key --]
[-- Type: text/plain, Size: 943 bytes --]
The whole function can be expressed as a simple this_cpu_read() operation.
The function overhead is now likely multiple times that of the single
instruction that is executed in it.
Cc: William Hubbs <w.d.hubbs@gmail.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
---
drivers/staging/speakup/fakekey.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
Index: linux-2.6/drivers/staging/speakup/fakekey.c
===================================================================
--- linux-2.6.orig/drivers/staging/speakup/fakekey.c 2010-11-30 12:10:12.000000000 -0600
+++ linux-2.6/drivers/staging/speakup/fakekey.c 2010-11-30 12:14:12.000000000 -0600
@@ -96,10 +96,5 @@ void speakup_fake_down_arrow(void)
*/
bool speakup_fake_key_pressed(void)
{
- bool is_pressed;
-
- is_pressed = get_cpu_var(reporting_keystroke);
- put_cpu_var(reporting_keystroke);
-
- return is_pressed;
+ return this_cpu_read(reporting_keystroke);
}
^ permalink raw reply [flat|nested] 35+ messages in thread
* [extra] timers: Use this_cpu_read
2010-11-30 19:07 [thisops uV3 00/18] Upgrade of this_cpu_ops V3 Christoph Lameter
` (17 preceding siblings ...)
2010-11-30 19:07 ` [thisops uV3 18/18] Fakekey: Simplify speakup_fake_key_pressed through this_cpu_ops Christoph Lameter
@ 2010-11-30 20:05 ` Christoph Lameter
18 siblings, 0 replies; 35+ messages in thread
From: Christoph Lameter @ 2010-11-30 20:05 UTC (permalink / raw)
To: akpm
Cc: Pekka Enberg, linux-kernel, Eric Dumazet, Mathieu Desnoyers,
Tejun Heo, linux-mm, Thomas Gleixner
Subject: timers: Use this_cpu_read
Eric asked for this.
Signed-off-by: Christoph Lameter <cl@linux.com>
---
kernel/timer.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: linux-2.6/kernel/timer.c
===================================================================
--- linux-2.6.orig/kernel/timer.c 2010-11-30 14:01:41.000000000 -0600
+++ linux-2.6/kernel/timer.c 2010-11-30 14:02:05.000000000 -0600
@@ -1249,7 +1249,7 @@ static unsigned long cmp_next_hrtimer_ev
*/
unsigned long get_next_timer_interrupt(unsigned long now)
{
- struct tvec_base *base = __get_cpu_var(tvec_bases);
+ struct tvec_base *base = __this_cpu_read(tvec_bases);
unsigned long expires;
spin_lock(&base->lock);
@@ -1292,7 +1292,7 @@ void update_process_times(int user_tick)
*/
static void run_timer_softirq(struct softirq_action *h)
{
- struct tvec_base *base = __get_cpu_var(tvec_bases);
+ struct tvec_base *base = __this_cpu_read(tvec_bases);
hrtimer_run_pending();
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 35+ messages in thread