* [PATCH] fix vmstat per cpu usage
@ 2006-08-01 17:36 Jan Blunck
2006-08-01 21:07 ` Andrew Morton
2006-08-02 16:54 ` Steve Fox
0 siblings, 2 replies; 8+ messages in thread
From: Jan Blunck @ 2006-08-01 17:36 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel
[-- Attachment #1: vmstat-fix.diff --]
[-- Type: text/x-patch, Size: 1271 bytes --]
From: Jan Blunck <jblunck@suse.de>
Subject: fix vmstat per cpu usage
The per cpu variables are used incorrectly in vmstat.h.
Signed-off-by: Jan Blunck <jblunck@suse.de>
---
include/linux/vmstat.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: linux-v2.6.18-rc3/include/linux/vmstat.h
===================================================================
--- linux-v2.6.18-rc3.orig/include/linux/vmstat.h
+++ linux-v2.6.18-rc3/include/linux/vmstat.h
@@ -41,23 +41,23 @@ DECLARE_PER_CPU(struct vm_event_state, v
static inline void __count_vm_event(enum vm_event_item item)
{
- __get_cpu_var(vm_event_states.event[item])++;
+ __get_cpu_var(vm_event_states).event[item]++;
}
static inline void count_vm_event(enum vm_event_item item)
{
- get_cpu_var(vm_event_states.event[item])++;
+ get_cpu_var(vm_event_states).event[item]++;
put_cpu();
}
static inline void __count_vm_events(enum vm_event_item item, long delta)
{
- __get_cpu_var(vm_event_states.event[item]) += delta;
+ __get_cpu_var(vm_event_states).event[item] += delta;
}
static inline void count_vm_events(enum vm_event_item item, long delta)
{
- get_cpu_var(vm_event_states.event[item]) += delta;
+ get_cpu_var(vm_event_states).event[item] += delta;
put_cpu();
}
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] fix vmstat per cpu usage 2006-08-01 17:36 [PATCH] fix vmstat per cpu usage Jan Blunck @ 2006-08-01 21:07 ` Andrew Morton 2006-08-01 22:44 ` Paul Mackerras ` (2 more replies) 2006-08-02 16:54 ` Steve Fox 1 sibling, 3 replies; 8+ messages in thread From: Andrew Morton @ 2006-08-01 21:07 UTC (permalink / raw) To: Jan Blunck; +Cc: linux-kernel On Tue, 1 Aug 2006 19:36:21 +0200 Jan Blunck <jblunck@suse.de> wrote: > The per cpu variables are used incorrectly in vmstat.h. > > Signed-off-by: Jan Blunck <jblunck@suse.de> > --- > include/linux/vmstat.h | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > Index: linux-v2.6.18-rc3/include/linux/vmstat.h > =================================================================== > --- linux-v2.6.18-rc3.orig/include/linux/vmstat.h > +++ linux-v2.6.18-rc3/include/linux/vmstat.h > @@ -41,23 +41,23 @@ DECLARE_PER_CPU(struct vm_event_state, v > > static inline void __count_vm_event(enum vm_event_item item) > { > - __get_cpu_var(vm_event_states.event[item])++; > + __get_cpu_var(vm_event_states).event[item]++; > } How odd. Are there any negative consequences to the existing code? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-01 21:07 ` Andrew Morton @ 2006-08-01 22:44 ` Paul Mackerras 2006-08-02 9:01 ` Jan Blunck 2006-08-02 13:30 ` Jan Blunck 2 siblings, 0 replies; 8+ messages in thread From: Paul Mackerras @ 2006-08-01 22:44 UTC (permalink / raw) To: Andrew Morton; +Cc: Jan Blunck, linux-kernel Andrew Morton writes: > On Tue, 1 Aug 2006 19:36:21 +0200 > Jan Blunck <jblunck@suse.de> wrote: > > > The per cpu variables are used incorrectly in vmstat.h. [snip] > > - __get_cpu_var(vm_event_states.event[item])++; > > + __get_cpu_var(vm_event_states).event[item]++; > > } > > How odd. Are there any negative consequences to the existing code? That sort of thing - i.e. using __get_cpu_var on something which isn't just a simple variable name - works with the current per-cpu macro definitions, because they are pretty simple, but one can imagine other reasonable implementations of __get_cpu_var which need the argument to be a simple variable name. I struck this when I was experimenting with using __thread variables for per-cpu data. Paul. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-01 21:07 ` Andrew Morton 2006-08-01 22:44 ` Paul Mackerras @ 2006-08-02 9:01 ` Jan Blunck 2006-08-02 13:30 ` Jan Blunck 2 siblings, 0 replies; 8+ messages in thread From: Jan Blunck @ 2006-08-02 9:01 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel, Paul Mackerras On Tue, Aug 01, Andrew Morton wrote: > > > > static inline void __count_vm_event(enum vm_event_item item) > > { > > - __get_cpu_var(vm_event_states.event[item])++; > > + __get_cpu_var(vm_event_states).event[item]++; > > } > > How odd. Are there any negative consequences to the existing code? In asm-s390/percpu.h we use #define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset) and for modules on s390x __reloc_hide() is defined as #define __reloc_hide(var,offset) \ (*({ unsigned long *__ptr; \ asm ( "larl %0,per_cpu__"#var"@GOTENT" \ : "=a" (__ptr) : "X" (per_cpu__##var) ); \ (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) which leads in this case to larl %0, per_cpu__vm_event_states.event[item]@GOTENT which is invalid asm. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-01 21:07 ` Andrew Morton 2006-08-01 22:44 ` Paul Mackerras 2006-08-02 9:01 ` Jan Blunck @ 2006-08-02 13:30 ` Jan Blunck 2006-08-02 14:43 ` Andrew Morton 2 siblings, 1 reply; 8+ messages in thread From: Jan Blunck @ 2006-08-02 13:30 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel, Paul Mackerras [-- Attachment #1: Type: text/plain, Size: 200 bytes --] Here comes another idea. To find further wrong usage of percpu variables I wrote the following patch. It still needs some work for the other archs but I'm interested in your feedback about that. Jan [-- Attachment #2: percpu_var-error.diff --] [-- Type: text/x-patch, Size: 2369 bytes --] --- include/asm-generic/percpu.h | 4 +++- include/asm-s390/percpu.h | 6 ++++-- include/linux/percpu.h | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) Index: linux-2.6/include/asm-generic/percpu.h =================================================================== --- linux-2.6.orig/include/asm-generic/percpu.h +++ linux-2.6/include/asm-generic/percpu.h @@ -14,7 +14,9 @@ extern unsigned long __per_cpu_offset[NR __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name /* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu])) +#define per_cpu(var, cpu) (*({ \ + int user_error_##var __attribute__ ((unused)); \ + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) #define __get_cpu_var(var) per_cpu(var, smp_processor_id()) #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) Index: linux-2.6/include/asm-s390/percpu.h =================================================================== --- linux-2.6.orig/include/asm-s390/percpu.h +++ linux-2.6/include/asm-s390/percpu.h @@ -16,7 +16,8 @@ #if defined(__s390x__) && defined(MODULE) #define __reloc_hide(var,offset) \ - (*({ unsigned long *__ptr; \ + (*({ int user_error_##var __attribute__ ((unused)); \ + unsigned long *__ptr; \ asm ( "larl %0,per_cpu__"#var"@GOTENT" \ : "=a" (__ptr) : "X" (per_cpu__##var) ); \ (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) @@ -24,7 +25,8 @@ #else #define __reloc_hide(var, offset) \ - (*({ unsigned long __ptr; \ + (*({ int user_error_##var __attribute__ ((unused)); \ + unsigned long __ptr; \ asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ (typeof(&per_cpu__##var)) (__ptr + (offset)); })) Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h +++ linux-2.6/include/linux/percpu.h @@ -12,7 +12,10 @@ #endif /* Must be an lvalue. */ -#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); })) +#define get_cpu_var(var) (*({ \ + int user_error_##var __attribute__ ((unused)); \ + preempt_disable(); \ + &__get_cpu_var(var); })) #define put_cpu_var(var) preempt_enable() #ifdef CONFIG_SMP ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-02 13:30 ` Jan Blunck @ 2006-08-02 14:43 ` Andrew Morton 2006-08-07 12:42 ` Jan Blunck 0 siblings, 1 reply; 8+ messages in thread From: Andrew Morton @ 2006-08-02 14:43 UTC (permalink / raw) To: Jan Blunck; +Cc: linux-kernel, paulus On Wed, 2 Aug 2006 15:30:06 +0200 Jan Blunck <jblunck@suse.de> wrote: > Here comes another idea. To find further wrong usage of percpu variables I > wrote the following patch. It still needs some work for the other archs but > I'm interested in your feedback about that. > > ... > > Index: linux-2.6/include/asm-generic/percpu.h > =================================================================== > --- linux-2.6.orig/include/asm-generic/percpu.h > +++ linux-2.6/include/asm-generic/percpu.h > @@ -14,7 +14,9 @@ extern unsigned long __per_cpu_offset[NR > __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name > > /* var is in discarded region: offset to particular copy we want */ > -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu])) > +#define per_cpu(var, cpu) (*({ \ > + int user_error_##var __attribute__ ((unused)); \ > + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) What's it do? Forces a syntax error if `var' isn't a simple identifier? Seems sane, although I'd check that the compiler doesn't accidentally waste a stack slot for that local. Perhaps it's be safer to make it a non-existing function: extern int user_error#var(void); ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-02 14:43 ` Andrew Morton @ 2006-08-07 12:42 ` Jan Blunck 0 siblings, 0 replies; 8+ messages in thread From: Jan Blunck @ 2006-08-07 12:42 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel, paulus [-- Attachment #1: Type: text/plain, Size: 732 bytes --] On Wed, Aug 02, Andrew Morton wrote: > > +#define per_cpu(var, cpu) (*({ \ > > + int user_error_##var __attribute__ ((unused)); \ > > + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) > > What's it do? Forces a syntax error if `var' isn't a simple identifier? > > Seems sane, although I'd check that the compiler doesn't accidentally > waste a stack slot for that local. Perhaps it's be safer to make > it a non-existing function: > > extern int user_error#var(void); > Yes, that is even better. See attached patch with the modifications for my major archs (s390, x86-64, generic). I did a run of 'make allmodconfig' with the attached patch and it produced some errors. I'll send the patches in a seperate mail. [-- Attachment #2: percpu-simple-identifier-error.diff --] [-- Type: text/x-patch, Size: 4443 bytes --] From: Jan Blunck <jblunck@suse.de> Subject: trigger a syntax error if percpu macros are incorrectly used get_cpu_var()/per_cpu()/__get_cpu_var() arguments must be simple identifiers. Otherwise the arch dependant implementations might break. This patch enforces the correct usage of the macros by producing a syntax error if the variable is not a simple identifier. Signed-off-by: Jan Blunck <jblunck@suse.de> --- include/asm-generic/percpu.h | 4 +++- include/asm-s390/percpu.h | 20 +++++++++++--------- include/asm-x86_64/percpu.h | 12 +++++++++--- include/linux/percpu.h | 10 ++++++++-- 4 files changed, 31 insertions(+), 15 deletions(-) Index: linux-2.6/include/asm-generic/percpu.h =================================================================== --- linux-2.6.orig/include/asm-generic/percpu.h +++ linux-2.6/include/asm-generic/percpu.h @@ -14,7 +14,9 @@ extern unsigned long __per_cpu_offset[NR __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name /* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu])) +#define per_cpu(var, cpu) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) #define __get_cpu_var(var) per_cpu(var, smp_processor_id()) #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) Index: linux-2.6/include/asm-s390/percpu.h =================================================================== --- linux-2.6.orig/include/asm-s390/percpu.h +++ linux-2.6/include/asm-s390/percpu.h @@ -15,18 +15,20 @@ */ #if defined(__s390x__) && defined(MODULE) -#define __reloc_hide(var,offset) \ - (*({ unsigned long *__ptr; \ - asm ( "larl %0,per_cpu__"#var"@GOTENT" \ - : "=a" (__ptr) : "X" (per_cpu__##var) ); \ - (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) +#define __reloc_hide(var,offset) (*({ \ + extern int simple_indentifier_##var(void); \ + unsigned long *__ptr; \ + asm ( "larl %0,per_cpu__"#var"@GOTENT" \ + : "=a" (__ptr) : "X" (per_cpu__##var) ); \ + (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) #else -#define __reloc_hide(var, offset) \ - (*({ unsigned long __ptr; \ - asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ - (typeof(&per_cpu__##var)) (__ptr + (offset)); })) +#define __reloc_hide(var, offset) (*({ \ + extern int simple_indentifier_##var(void); \ + unsigned long __ptr; \ + asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ + (typeof(&per_cpu__##var)) (__ptr + (offset)); })) #endif Index: linux-2.6/include/asm-x86_64/percpu.h =================================================================== --- linux-2.6.orig/include/asm-x86_64/percpu.h +++ linux-2.6/include/asm-x86_64/percpu.h @@ -21,9 +21,15 @@ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name /* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) -#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) -#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) +#define per_cpu(var, cpu) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); })) +#define __get_cpu_var(var) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) +#define __raw_get_cpu_var(var) (*({ \ + extern int simple_indentifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) /* A macro to avoid #include hell... */ #define percpu_modcopy(pcpudst, src, size) \ Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h +++ linux-2.6/include/linux/percpu.h @@ -11,8 +11,14 @@ #define PERCPU_ENOUGH_ROOM 32768 #endif -/* Must be an lvalue. */ -#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); })) +/* + * Must be an lvalue. Since @var must be a simple identifier, + * we force a syntax error here if it isn't. + */ +#define get_cpu_var(var) (*({ \ + extern int simple_indentifier_##var(void); \ + preempt_disable(); \ + &__get_cpu_var(var); })) #define put_cpu_var(var) preempt_enable() #ifdef CONFIG_SMP ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] fix vmstat per cpu usage 2006-08-01 17:36 [PATCH] fix vmstat per cpu usage Jan Blunck 2006-08-01 21:07 ` Andrew Morton @ 2006-08-02 16:54 ` Steve Fox 1 sibling, 0 replies; 8+ messages in thread From: Steve Fox @ 2006-08-02 16:54 UTC (permalink / raw) To: linux-kernel On Tue, 01 Aug 2006 19:36:21 +0200, Jan Blunck wrote: > From: Jan Blunck <jblunck@suse.de> > Subject: fix vmstat per cpu usage > > The per cpu variables are used incorrectly in vmstat.h. > > Signed-off-by: Jan Blunck <jblunck@suse.de> This patch has allowed the first 2.6.18-rc* successful compilation on s390. Andrew, please pull this into your tree too. Thanks. Acked-by: Steve Fox <drfickle@us.ibm.com> -- Steve Fox IBM Linux Technology Center ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-08-07 12:42 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-08-01 17:36 [PATCH] fix vmstat per cpu usage Jan Blunck 2006-08-01 21:07 ` Andrew Morton 2006-08-01 22:44 ` Paul Mackerras 2006-08-02 9:01 ` Jan Blunck 2006-08-02 13:30 ` Jan Blunck 2006-08-02 14:43 ` Andrew Morton 2006-08-07 12:42 ` Jan Blunck 2006-08-02 16:54 ` Steve Fox
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox