* [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-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
* 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
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