percpu: add __percpu sparse annotations
Subsystems (27)
Tejun Heo
maintainerPATCH 1/1 percpu: add __percpu sparse annotations
This patchset adds __percpu sparse annotations to all percpu users covered by x86_64 allmodconfig. __percpu annotation teaches sparse that percpu variables live in a separate address space and can't be accessed directly without going through percpu accessors. This allows detection of most percpu access mistakes involving both static and dyanmic percpu variables.
This patchset contains the following eight patches.
0001-percpu-add-__percpu-sparse-annotations-to-core-kerne.patch 0002-percpu-add-__percpu-sparse-annotations-to-fs.patch 0003-percpu-add-__percpu-sparse-annotations-to-net.patch 0004-percpu-add-__percpu-sparse-annotations-to-net-driver.patch 0005-percpu-add-__percpu-sparse-annotations-to-x86.patch 0006-percpu-add-__percpu-sparse-annotations-to-trace.patch 0007-percpu-add-__percpu-sparse-annotations-to-hw_breakpo.patch 0008-percpu-add-__percpu-sparse-annotations-to-what-s-lef.patch
As these annotations are for sparse, none of the above patches affects normal kernel build and most of the conversions are straight-forward and trivial. There are a few places where the conversion isn't completely straight-forward (but still fairly trivial). Those are mentioned in each patch description.
I can route the patch through percpu and conflict resolution, if necessary, wouldn't be difficult at all for these changes. If anyone wants to route one of these patches through a different tree, please let me know. All that's necessary would be adding dummy __percpu definition to the patch.
If nobody objects, I'll push these into percpu tree in three or four days.
Thanks.
arch/x86/include/asm/msr.h | 12 ++++--- arch/x86/kernel/acpi/cstate.c | 2 - arch/x86/kernel/cpu/common.c | 2 - arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 - arch/x86/lib/msr-smp.c | 8 +++-- arch/x86/lib/msr.c | 6 +-- crypto/cryptd.c | 2 - drivers/acpi/processor_perflib.c | 2 - drivers/dma/dmaengine.c | 2 - drivers/edac/amd64_edac.c | 2 - drivers/md/raid5.c | 2 - drivers/md/raid5.h | 2 - drivers/net/chelsio/sge.c | 2 - drivers/net/loopback.c | 16 +++++----- drivers/net/macvlan.c | 2 - drivers/net/veth.c | 4 +- fs/ext4/ext4.h | 2 - fs/nfs/iostat.h | 4 +- fs/xfs/xfs_mount.h | 2 - include/acpi/processor.h | 2 - include/linux/blktrace_api.h | 4 +- include/linux/dmaengine.h | 2 - include/linux/ftrace_event.h | 4 +- include/linux/genhd.h | 2 - include/linux/hw_breakpoint.h | 8 ++--- include/linux/kexec.h | 2 - include/linux/mmzone.h | 2 - include/linux/module.h | 2 - include/linux/mount.h | 2 - include/linux/nfs_fs_sb.h | 2 - include/linux/percpu_counter.h | 2 - include/linux/srcu.h | 2 - include/net/ip.h | 6 +-- include/net/ipcomp.h | 2 - include/net/neighbour.h | 2 - include/net/netns/conntrack.h | 2 - include/net/netns/core.h | 2 - include/net/route.h | 2 - include/net/snmp.h | 12 +++++-- include/net/tcp.h | 2 - include/trace/ftrace.h | 4 +- kernel/hw_breakpoint.c | 14 ++++---- kernel/kexec.c | 2 - kernel/sched.c | 4 +- kernel/stop_machine.c | 2 - kernel/trace/trace_event_profile.c | 16 +++++----- kernel/trace/trace_functions_graph.c | 2 - kernel/trace/trace_kprobe.c | 4 +- kernel/trace/trace_ksym.c | 10 +++--- kernel/trace/trace_syscalls.c | 4 +- mm/percpu.c | 18 ++++++----- net/8021q/vlan.h | 2 - net/dccp/proto.c | 5 +-- net/ipv4/af_inet.c | 46 ++++++++++++++--------------- net/ipv4/proc.c | 28 ++++++++--------- net/ipv4/route.c | 2 - net/ipv4/tcp.c | 21 +++++++------ net/ipv6/addrconf.c | 24 +++++++-------- net/ipv6/af_inet6.c | 28 ++++++++--------- net/ipv6/proc.c | 24 ++++++++------- net/sctp/proc.c | 2 - net/sctp/protocol.c | 5 +-- net/xfrm/xfrm_ipcomp.c | 16 +++++----- net/xfrm/xfrm_policy.c | 6 +-- net/xfrm/xfrm_proc.c | 3 + samples/hw_breakpoint/data_breakpoint.c | 6 +-- 66 files changed, 231 insertions(+), 209 deletions(-)
--
tejun
Tejun Heo
maintainerPATCH 1/8 percpu: add __percpu sparse annotations to core kernel subsystems
Add __percpu sparse annotations to core subsystems.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- include/linux/blktrace_api.h | 4 ++-- include/linux/genhd.h | 2 +- include/linux/kexec.h | 2 +- include/linux/mmzone.h | 2 +- include/linux/module.h | 2 +- include/linux/percpu_counter.h | 2 +- include/linux/srcu.h | 2 +- kernel/kexec.c | 2 +- kernel/sched.c | 4 ++-- kernel/stop_machine.c | 2 +- mm/percpu.c | 18 ++++++++++-------- 11 files changed, 22 insertions(+), 20 deletions(-)
include/linux/blktrace_api.h +2 -2
@@ -150,8 +150,8 @@ struct blk_user_trace_setup {struct blk_trace {int trace_state;struct rchan *rchan; -unsigned long *sequence; -unsigned char *msg_data; +unsigned long __percpu *sequence; +unsigned char __percpu *msg_data;u16 act_mask;u64 start_lba;u64 end_lba;
include/linux/genhd.h +1 -1
@@ -101,7 +101,7 @@ struct hd_struct {unsigned long stamp;int in_flight[2 ];#ifdef CONFIG_SMP -struct disk_stats *dkstats; +struct disk_stats __percpu *dkstats;#else struct disk_stats dkstats;#endif
include/linux/kexec.h +1 -1
@@ -199,7 +199,7 @@ extern struct kimage *kexec_crash_image;*/ extern struct resource crashk_res;typedef u32 note_buf_t [KEXEC_NOTE_BYTES /4 ]; -extern note_buf_t *crash_notes; +extern note_buf_t __percpu *crash_notes;extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE /4 ];extern size_t vmcoreinfo_size;extern size_t vmcoreinfo_max_size;
include/linux/mmzone.h +1 -1
@@ -301,7 +301,7 @@ struct zone {unsigned long min_unmapped_pages;unsigned long min_slab_pages;#endif -struct per_cpu_pageset *pageset; +struct per_cpu_pageset __percpu *pageset;/* * free areas of different sizes */
include/linux/module.h +1 -1
@@ -365,7 +365,7 @@ struct modulestruct module_ref {int count; - } *refptr; + }__percpu *refptr;#endif #ifdef CONFIG_CONSTRUCTORS
include/linux/percpu_counter.h +1 -1
@@ -21,7 +21,7 @@ struct percpu_counter {#ifdef CONFIG_HOTPLUG_CPU struct list_head list;/* All percpu_counters are on a list */ #endif -s32 *counters; +s32 __percpu *counters; };extern int percpu_counter_batch;
include/linux/srcu.h +1 -1
@@ -33,7 +33,7 @@ struct srcu_struct_array {struct srcu_struct {int completed; -struct srcu_struct_array *per_cpu_ref; +struct srcu_struct_array __percpu *per_cpu_ref;struct mutex mutex; };
kernel/kexec.c +1 -1
@@ -40,7 +40,7 @@#include <asm/sections.h> /* Per cpu memory for storing cpu states in case of system crash. */ -note_buf_t * crash_notes; +note_buf_t __percpu *crash_notes;/* vmcoreinfo stuff */ static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES ];
kernel/sched.c +2 -2
@@ -1566,7 +1566,7 @@ static unsigned long cpu_avg_load_per_task(int cpu)#ifdef CONFIG_FAIR_GROUP_SCHED -static __read_mostly unsigned long *update_shares_data; +static __read_mostly unsigned long __percpu *update_shares_data;static void __set_se_shares (struct sched_entity *se,unsigned long shares);
@@ -10668,7 +10668,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {struct cpuacct {struct cgroup_subsys_state css;/* cpuusage holds pointer to a u64-type object on every cpu */ -u64 *cpuusage; +u64 __percpu *cpuusage;struct percpu_counter cpustat[CPUACCT_STAT_NSTATS ];struct cpuacct *parent; };
kernel/stop_machine.c +1 -1
@@ -45,7 +45,7 @@ static int refcount;static struct workqueue_struct *stop_machine_wq;static struct stop_machine_data active, idle;static const struct cpumask *active_cpus; -static void *stop_machine_work; +static void __percpu *stop_machine_work;static void set_state (enum stopmachine_state newstate) {
mm/percpu.c +10 -8
@@ -80,13 +80,15 @@/* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */ #ifndef __addr_to_pcpu_ptr#define __addr_to_pcpu_ptr (addr) \ - (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \ - + (unsigned long)__per_cpu_start) + (void __percpu *)((unsigned long)(addr) - \ + (unsigned long)pcpu_base_addr + \ + (unsigned long)__per_cpu_start)#endif #ifndef __pcpu_ptr_to_addr#define __pcpu_ptr_to_addr (ptr) \ - (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \ - - (unsigned long)__per_cpu_start) + (void __force *)((unsigned long)(ptr) + \ + (unsigned long)pcpu_base_addr - \ + (unsigned long)__per_cpu_start)#endif struct pcpu_chunk {
@@ -1065,7 +1067,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -static void *pcpu_alloc (size_t size,size_t align,bool reserved) +static void __percpu *pcpu_alloc (size_t size,size_t align,bool reserved) {static int warn_limit =10 ;struct pcpu_chunk *chunk;
@@ -1194,7 +1196,7 @@ fail_unlock_mutex:* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_percpu (size_t size,size_t align) +void __percpu *__alloc_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, false); }
@@ -1215,7 +1217,7 @@ EXPORT_SYMBOL_GPL(__alloc_percpu);* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_reserved_percpu (size_t size,size_t align) +void __percpu *__alloc_reserved_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, true); }
@@ -1267,7 +1269,7 @@ static void pcpu_reclaim(struct work_struct *work)* CONTEXT: * Can be called from atomic context. */ -void free_percpu (void *ptr) +void free_percpu (void __percpu *ptr) {void *addr;struct pcpu_chunk *chunk;
Signature · 7 lines
1.6.4.2 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/8] percpu: add __percpu sparse annotations to core kernel subsystems
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/8] percpu: add __percpu sparse annotations to core kernel subsystems
In reply to Tejun HeoQuoted 5 lines · Tejun Heo
Add
__percpusparse annotations to core subsystems.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
The RCU pieces look fine to me.
Quoted 227 lines
Signed-off-by Tejun Heo <[email protected]>Cc Jens Axboe <[email protected]>Cc Rusty Russell <[email protected]>Cc Dipankar Sarma <[email protected]>Cc "Paul E. McKenney" <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Andrew Morton <[email protected]>Cc Eric Biederman <[email protected]>--- include/linux/blktrace_api.h | 4 ++-- include/linux/genhd.h | 2 +- include/linux/kexec.h | 2 +- include/linux/mmzone.h | 2 +- include/linux/module.h | 2 +- include/linux/percpu_counter.h | 2 +- include/linux/srcu.h | 2 +- kernel/kexec.c | 2 +- kernel/sched.c | 4 ++-- kernel/stop_machine.c | 2 +- mm/percpu.c | 18 ++++++++++-------- 11 files changed, 22 insertions(+), 20 deletions(-)include/linux/blktrace_api.h +2
-2@@ -150,8 +150,8 @@ struct blk_user_trace_setup {struct blk_trace {int trace_state;struct rchan *rchan; -unsigned long *sequence; -unsigned char *msg_data; +unsigned long __percpu *sequence; +unsigned char __percpu *msg_data;u16 act_mask;u64 start_lba;u64 end_lba;include/linux/genhd.h +1
-1@@ -101,7 +101,7 @@ struct hd_struct {unsigned long stamp;int in_flight[2 ];#ifdef CONFIG_SMP -struct disk_stats *dkstats; +struct disk_stats __percpu *dkstats;#else struct disk_stats dkstats;#endif include/linux/kexec.h +1
-1@@ -199,7 +199,7 @@ extern struct kimage *kexec_crash_image;*/ extern struct resource crashk_res;typedef u32 note_buf_t [KEXEC_NOTE_BYTES /4 ]; -extern note_buf_t *crash_notes; +extern note_buf_t __percpu *crash_notes;extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE /4 ];extern size_t vmcoreinfo_size;extern size_t vmcoreinfo_max_size;include/linux/mmzone.h +1
-1@@ -301,7 +301,7 @@ struct zone {unsigned long min_unmapped_pages;unsigned long min_slab_pages;#endif -struct per_cpu_pageset *pageset; +struct per_cpu_pageset __percpu *pageset;/* * free areas of different sizes */ include/linux/module.h +1
-1@@ -365,7 +365,7 @@ struct modulestruct module_ref {int count; - } *refptr; + }__percpu *refptr;#endif #ifdef CONFIG_CONSTRUCTORS include/linux/percpu_counter.h +1
-1@@ -21,7 +21,7 @@ struct percpu_counter {#ifdef CONFIG_HOTPLUG_CPU struct list_head list;/* All percpu_counters are on a list */ #endif -s32 *counters; +s32 __percpu *counters; };extern int percpu_counter_batch;include/linux/srcu.h +1
-1@@ -33,7 +33,7 @@ struct srcu_struct_array {struct srcu_struct {int completed; -struct srcu_struct_array *per_cpu_ref; +struct srcu_struct_array __percpu *per_cpu_ref;struct mutex mutex; };kernel/kexec.c +1
-1@@ -40,7 +40,7 @@#include <asm/sections.h> /* Per cpu memory for storing cpu states in case of system crash. */ -note_buf_t * crash_notes; +note_buf_t __percpu *crash_notes;/* vmcoreinfo stuff */ static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES ];kernel/sched.c +2
-2@@ -1566,7 +1566,7 @@ static unsigned long cpu_avg_load_per_task(int cpu)#ifdef CONFIG_FAIR_GROUP_SCHED -static __read_mostly unsigned long *update_shares_data; +static __read_mostly unsigned long __percpu *update_shares_data;static void __set_se_shares (struct sched_entity *se,unsigned long shares);@@ -10668,7 +10668,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {struct cpuacct {struct cgroup_subsys_state css;/* cpuusage holds pointer to a u64-type object on every cpu */ -u64 *cpuusage; +u64 __percpu *cpuusage;struct percpu_counter cpustat[CPUACCT_STAT_NSTATS ];struct cpuacct *parent; };kernel/stop_machine.c +1
-1@@ -45,7 +45,7 @@ static int refcount;static struct workqueue_struct *stop_machine_wq;static struct stop_machine_data active, idle;static const struct cpumask *active_cpus; -static void *stop_machine_work; +static void __percpu *stop_machine_work;static void set_state (enum stopmachine_state newstate) {mm/percpu.c +10
-8@@ -80,13 +80,15 @@/* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */ #ifndef __addr_to_pcpu_ptr#define __addr_to_pcpu_ptr (addr) \ - (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \ - + (unsigned long)__per_cpu_start) + (void __percpu *)((unsigned long)(addr) - \ + (unsigned long)pcpu_base_addr + \ + (unsigned long)__per_cpu_start)#endif #ifndef __pcpu_ptr_to_addr#define __pcpu_ptr_to_addr (ptr) \ - (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \ - - (unsigned long)__per_cpu_start) + (void __force *)((unsigned long)(ptr) + \ + (unsigned long)pcpu_base_addr - \ + (unsigned long)__per_cpu_start)#endif struct pcpu_chunk {@@ -1065,7 +1067,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -static void *pcpu_alloc (size_t size,size_t align,bool reserved) +static void __percpu *pcpu_alloc (size_t size,size_t align,bool reserved) {static int warn_limit =10 ;struct pcpu_chunk *chunk;@@ -1194,7 +1196,7 @@ fail_unlock_mutex:* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_percpu (size_t size,size_t align) +void __percpu *__alloc_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, false); }@@ -1215,7 +1217,7 @@ EXPORT_SYMBOL_GPL(__alloc_percpu);* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_reserved_percpu (size_t size,size_t align) +void __percpu *__alloc_reserved_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, true); }@@ -1267,7 +1269,7 @@ static void pcpu_reclaim(struct work_struct *work)* CONTEXT: * Can be called from atomic context. */ -void free_percpu (void *ptr) +void free_percpu (void __percpu *ptr) {void *addr;struct pcpu_chunk *chunk;Signature · 1 line
1.6.4.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Tejun Heo
maintainerPATCH 1/8 percpu: add __percpu sparse annotations to core kernel subsystems
In reply to Tejun HeoAdd __percpu sparse annotations to core subsystems.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- include/linux/blktrace_api.h | 4 ++-- include/linux/genhd.h | 2 +- include/linux/kexec.h | 2 +- include/linux/mmzone.h | 2 +- include/linux/module.h | 2 +- include/linux/percpu_counter.h | 2 +- include/linux/srcu.h | 2 +- kernel/kexec.c | 2 +- kernel/sched.c | 4 ++-- kernel/stop_machine.c | 2 +- mm/percpu.c | 18 ++++++++++-------- 11 files changed, 22 insertions(+), 20 deletions(-)
include/linux/blktrace_api.h +2 -2
@@ -150,8 +150,8 @@ struct blk_user_trace_setup {struct blk_trace {int trace_state;struct rchan *rchan; -unsigned long *sequence; -unsigned char *msg_data; +unsigned long __percpu *sequence; +unsigned char __percpu *msg_data;u16 act_mask;u64 start_lba;u64 end_lba;
include/linux/genhd.h +1 -1
@@ -101,7 +101,7 @@ struct hd_struct {unsigned long stamp;int in_flight[2 ];#ifdef CONFIG_SMP -struct disk_stats *dkstats; +struct disk_stats __percpu *dkstats;#else struct disk_stats dkstats;#endif
include/linux/kexec.h +1 -1
@@ -199,7 +199,7 @@ extern struct kimage *kexec_crash_image;*/ extern struct resource crashk_res;typedef u32 note_buf_t [KEXEC_NOTE_BYTES /4 ]; -extern note_buf_t *crash_notes; +extern note_buf_t __percpu *crash_notes;extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE /4 ];extern size_t vmcoreinfo_size;extern size_t vmcoreinfo_max_size;
include/linux/mmzone.h +1 -1
@@ -301,7 +301,7 @@ struct zone {unsigned long min_unmapped_pages;unsigned long min_slab_pages;#endif -struct per_cpu_pageset *pageset; +struct per_cpu_pageset __percpu *pageset;/* * free areas of different sizes */
include/linux/module.h +1 -1
@@ -365,7 +365,7 @@ struct modulestruct module_ref {int count; - } *refptr; + }__percpu *refptr;#endif #ifdef CONFIG_CONSTRUCTORS
include/linux/percpu_counter.h +1 -1
@@ -21,7 +21,7 @@ struct percpu_counter {#ifdef CONFIG_HOTPLUG_CPU struct list_head list;/* All percpu_counters are on a list */ #endif -s32 *counters; +s32 __percpu *counters; };extern int percpu_counter_batch;
include/linux/srcu.h +1 -1
@@ -33,7 +33,7 @@ struct srcu_struct_array {struct srcu_struct {int completed; -struct srcu_struct_array *per_cpu_ref; +struct srcu_struct_array __percpu *per_cpu_ref;struct mutex mutex; };
kernel/kexec.c +1 -1
@@ -40,7 +40,7 @@#include <asm/sections.h> /* Per cpu memory for storing cpu states in case of system crash. */ -note_buf_t * crash_notes; +note_buf_t __percpu *crash_notes;/* vmcoreinfo stuff */ static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES ];
kernel/sched.c +2 -2
@@ -1566,7 +1566,7 @@ static unsigned long cpu_avg_load_per_task(int cpu)#ifdef CONFIG_FAIR_GROUP_SCHED -static __read_mostly unsigned long *update_shares_data; +static __read_mostly unsigned long __percpu *update_shares_data;static void __set_se_shares (struct sched_entity *se,unsigned long shares);
@@ -10668,7 +10668,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {struct cpuacct {struct cgroup_subsys_state css;/* cpuusage holds pointer to a u64-type object on every cpu */ -u64 *cpuusage; +u64 __percpu *cpuusage;struct percpu_counter cpustat[CPUACCT_STAT_NSTATS ];struct cpuacct *parent; };
kernel/stop_machine.c +1 -1
@@ -45,7 +45,7 @@ static int refcount;static struct workqueue_struct *stop_machine_wq;static struct stop_machine_data active, idle;static const struct cpumask *active_cpus; -static void *stop_machine_work; +static void __percpu *stop_machine_work;static void set_state (enum stopmachine_state newstate) {
mm/percpu.c +10 -8
@@ -80,13 +80,15 @@/* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */ #ifndef __addr_to_pcpu_ptr#define __addr_to_pcpu_ptr (addr) \ - (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \ - + (unsigned long)__per_cpu_start) + (void __percpu *)((unsigned long)(addr) - \ + (unsigned long)pcpu_base_addr + \ + (unsigned long)__per_cpu_start)#endif #ifndef __pcpu_ptr_to_addr#define __pcpu_ptr_to_addr (ptr) \ - (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \ - - (unsigned long)__per_cpu_start) + (void __force *)((unsigned long)(ptr) + \ + (unsigned long)pcpu_base_addr - \ + (unsigned long)__per_cpu_start)#endif struct pcpu_chunk {
@@ -1065,7 +1067,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -static void *pcpu_alloc (size_t size,size_t align,bool reserved) +static void __percpu *pcpu_alloc (size_t size,size_t align,bool reserved) {static int warn_limit =10 ;struct pcpu_chunk *chunk;
@@ -1194,7 +1196,7 @@ fail_unlock_mutex:* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_percpu (size_t size,size_t align) +void __percpu *__alloc_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, false); }
@@ -1215,7 +1217,7 @@ EXPORT_SYMBOL_GPL(__alloc_percpu);* RETURNS: * Percpu pointer to the allocated area on success, NULL on failure. */ -void *__alloc_reserved_percpu (size_t size,size_t align) +void __percpu *__alloc_reserved_percpu (size_t size,size_t align) {return pcpu_alloc (size, align, true); }
@@ -1267,7 +1269,7 @@ static void pcpu_reclaim(struct work_struct *work)* CONTEXT: * Can be called from atomic context. */ -void free_percpu (void *ptr) +void free_percpu (void __percpu *ptr) {void *addr;struct pcpu_chunk *chunk;
Signature · 1 line
1.6.4.2
Tejun Heo
maintainerPATCH 2/8 percpu: add __percpu sparse annotations to fs
In reply to Tejun HeoAdd __percpu sparse annotations to fs.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- fs/ext4/ext4.h | 2 +- fs/nfs/iostat.h | 4 ++-- fs/xfs/xfs_mount.h | 2 +- include/linux/mount.h | 2 +- include/linux/nfs_fs_sb.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-)
fs/ext4/ext4.h +1 -1
@@ -1017,7 +1017,7 @@ struct ext4_sb_info {atomic_t s_lock_busy;/* locality groups */ -struct ext4_locality_group *s_locality_groups; +struct ext4_locality_group __percpu *s_locality_groups;/* for write statistics */ unsigned long s_sectors_written_start;
fs/nfs/iostat.h +2 -2
@@ -57,12 +57,12 @@ static inline void nfs_add_fscache_stats(struct inode *inode, }#endif -static inline struct nfs_iostats *nfs_alloc_iostats (void ) +static inline struct nfs_iostats __percpu *nfs_alloc_iostats (void ) { return alloc_percpu(struct nfs_iostats); } -static inline void nfs_free_iostats (struct nfs_iostats *stats) +static inline void nfs_free_iostats (struct nfs_iostats __percpu *stats) {if (stats !=NULL )free_percpu (stats);
fs/xfs/xfs_mount.h +1 -1
@@ -243,7 +243,7 @@ typedef struct xfs_mount {struct xfs_qmops *m_qm_ops;/* vector of XQM ops */ atomic_t m_active_trans;/* number trans frozen */ #ifdef HAVE_PERCPU_SB -xfs_icsb_cnts_t *m_sb_cnts;/* per-cpu superblock counters */ +xfs_icsb_cnts_t __percpu *m_sb_cnts;/* per-cpu superblock counters */ unsigned long m_icsb_counters;/* disabled per-cpu counters */ struct notifier_block m_icsb_notifier;/* hotplug cpu notifier */ struct mutex m_icsb_mutex;/* balancer sync lock */
include/linux/mount.h +1 -1
@@ -66,7 +66,7 @@ struct vfsmount {int mnt_pinned;int mnt_ghosts;#ifdef CONFIG_SMP -int *mnt_writers; +int __percpu *mnt_writers;#else int mnt_writers;#endif
include/linux/nfs_fs_sb.h +1 -1
@@ -105,7 +105,7 @@ struct nfs_server {struct rpc_clnt * client;/* RPC client handle */ struct rpc_clnt * client_acl;/* ACL RPC client handle */ struct nlm_host *nlm_host;/* NLM client handle */ -struct nfs_iostats * io_stats;/* I/O statistics */ +struct nfs_iostats __percpu *io_stats;/* I/O statistics */ struct backing_dev_info backing_dev_info;atomic_long_t writeback;/* number of writeback pages */ int flags;/* various flags */
Signature · 1 line
1.6.4.2
Tejun Heo
maintainerPATCH 3/8 percpu: add __percpu sparse annotations to net
In reply to Tejun HeoAdd __percpu sparse annotations to net.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
The macro and type tricks around snmp stats make things a bit interesting. DEFINE/DECLARE_SNMP_STAT() macros mark the target field as __percpu and SNMP_UPD_PO_STATS() macro is updated accordingly. All snmp_mib_*() users which used to cast the argument to (void **) are updated to cast it to (void __percpu **).
--- include/net/ip.h | 6 ++-- include/net/ipcomp.h | 2 +- include/net/neighbour.h | 2 +- include/net/netns/conntrack.h | 2 +- include/net/netns/core.h | 2 +- include/net/route.h | 2 +- include/net/snmp.h | 12 +++++++--- include/net/tcp.h | 2 +- net/8021q/vlan.h | 2 +- net/dccp/proto.c | 5 ++- net/ipv4/af_inet.c | 46 ++++++++++++++++++++-------------------- net/ipv4/proc.c | 28 ++++++++++++------------ net/ipv4/route.c | 2 +- net/ipv4/tcp.c | 21 ++++++++++-------- net/ipv6/addrconf.c | 24 ++++++++++---------- net/ipv6/af_inet6.c | 28 ++++++++++++------------ net/ipv6/proc.c | 24 ++++++++++++--------- net/sctp/proc.c | 2 +- net/sctp/protocol.c | 5 ++- net/xfrm/xfrm_ipcomp.c | 16 +++++++------- net/xfrm/xfrm_policy.c | 6 ++-- net/xfrm/xfrm_proc.c | 3 +- 22 files changed, 128 insertions(+), 114 deletions(-)
include/net/ip.h +3 -3
@@ -174,9 +174,9 @@ extern struct ipv4_config ipv4_config;#define NET_ADD_STATS_BH (net, field, adnd) SNMP_ADD_STATS_BH((net)->mib.net_statistics, field, adnd)#define NET_ADD_STATS_USER (net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd) -extern unsigned long snmp_fold_field (void *mib[],int offt); -extern int snmp_mib_init (void *ptr[2 ],size_t mibsize); -extern void snmp_mib_free (void *ptr[2 ]); +extern unsigned long snmp_fold_field (void __percpu *mib[],int offt); +extern int snmp_mib_init (void __percpu *ptr[2 ],size_t mibsize); +extern void snmp_mib_free (void __percpu *ptr[2 ]); extern struct local_ports { seqlock_t lock;
include/net/ipcomp.h +1 -1
@@ -9,7 +9,7 @@ struct crypto_comp;struct ipcomp_data {u16 threshold; -struct crypto_comp **tfms; +struct crypto_comp *__percpu *tfms; };struct ip_comp_hdr ;
include/net/neighbour.h +1 -1
@@ -164,7 +164,7 @@ struct neigh_table {rwlock_t lock;unsigned long last_rand;struct kmem_cache *kmem_cachep; -struct neigh_statistics *stats; +struct neigh_statistics __percpu *stats;struct neighbour **hash_buckets;unsigned int hash_mask;__u32 hash_rnd;
include/net/netns/conntrack.h +1 -1
@@ -15,7 +15,7 @@ struct netns_ct {struct hlist_head *expect_hash;struct hlist_nulls_head unconfirmed;struct hlist_nulls_head dying; -struct ip_conntrack_stat *stat; +struct ip_conntrack_stat __percpu *stat;int sysctl_events;unsigned int sysctl_events_retry_timeout;int sysctl_acct;
include/net/netns/core.h +1 -1
@@ -10,7 +10,7 @@ struct netns_core {int sysctl_somaxconn; - struct prot_inuse *inuse; + struct prot_inuse __percpu *inuse; };#endif
include/net/route.h +1 -1
@@ -101,7 +101,7 @@ struct rt_cache_stat {unsigned int out_hlist_search; }; -extern struct ip_rt_acct *ip_rt_acct; +extern struct ip_rt_acct __percpu *ip_rt_acct;struct in_device ;extern int ip_rt_init (void );
include/net/snmp.h +8 -4
@@ -129,9 +129,9 @@ struct linux_xfrm_mib {* nonlocked_atomic_inc() primitives -AK */ #define DEFINE_SNMP_STAT (type, name) \ - __typeof__(type) *name[2] + __typeof__(type) __percpu *name[2]#define DECLARE_SNMP_STAT (type, name) \ - extern __typeof__(type) *name[2] + extern __typeof__(type) __percpu *name[2]#define SNMP_STAT_BHPTR (name) (name[0])#define SNMP_STAT_USRPTR (name) (name[1])
@@ -148,9 +148,13 @@ struct linux_xfrm_mib { __this_cpu_add(mib[0]->mibs[field], addend)#define SNMP_ADD_STATS_USER (mib, field, addend) \ this_cpu_add(mib[1]->mibs[field], addend) +/* +* Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" +* to make @ptr a non-percpu pointer. +*/ #define SNMP_UPD_PO_STATS (mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr; \ + __typeof__(*mib[0]) *ptr; \ preempt_disable(); \ ptr = this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \
@@ -159,7 +163,7 @@ struct linux_xfrm_mib { } while (0)#define SNMP_UPD_PO_STATS_BH (mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr = \ + __typeof__(*mib[0]) *ptr = \ __this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\
include/net/tcp.h +1 -1
@@ -1193,7 +1193,7 @@ extern int tcp_v4_md5_do_del(struct sock *sk,#define tcp_twsk_md5_key (twsk) NULL#endif -extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool (struct sock *); +extern struct tcp_md5sig_pool *__percpu *tcp_alloc_md5sig_pool (struct sock *);extern void tcp_free_md5sig_pool (void );extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool (int cpu);
net/8021q/vlan.h +1 -1
@@ -61,7 +61,7 @@ struct vlan_dev_info {struct proc_dir_entry *dent;unsigned long cnt_inc_headroom_on_tx;unsigned long cnt_encap_on_xmit; -struct vlan_rx_stats *vlan_rx_stats; +struct vlan_rx_stats __percpu *vlan_rx_stats; };static inline struct vlan_dev_info *vlan_dev_info (const struct net_device *dev)
net/dccp/proto.c +3 -2
@@ -1003,12 +1003,13 @@ EXPORT_SYMBOL_GPL(dccp_shutdown);static inline int dccp_mib_init (void ) { -return snmp_mib_init ((void **)dccp_statistics,sizeof (struct dccp_mib )); +return snmp_mib_init ((void __percpu **)dccp_statistics, +sizeof (struct dccp_mib )); }static inline void dccp_mib_exit (void ) { -snmp_mib_free ((void **)dccp_statistics); +snmp_mib_free ((void __percpu **)dccp_statistics); }static int thash_entries;
net/ipv4/af_inet.c +23 -23
99 lines not on this page · raw message
net/ipv4/proc.c +14 -14
@@ -280,7 +280,7 @@ static void icmpmsg_put(struct seq_file *seq) count =0 ;for (i =0 ; i <ICMPMSG_MIB_MAX ; i++) { - val =snmp_fold_field ((void **) net->mib.icmpmsg_statistics, i); + val =snmp_fold_field ((void __percpu **) net->mib.icmpmsg_statistics, i);if (val) { type[count] = i; vals[count++] = val;
@@ -307,18 +307,18 @@ static void icmp_put(struct seq_file *seq)for (i=0 ; icmpmibmap[i].name !=NULL ; i++)seq_printf (seq," Out%s" , icmpmibmap[i].name);seq_printf (seq,"\nIcmp: %lu %lu" , -snmp_fold_field ((void **) net->mib.icmp_statistics,ICMP_MIB_INMSGS ), -snmp_fold_field ((void **) net->mib.icmp_statistics,ICMP_MIB_INERRORS )); +snmp_fold_field ((void __percpu **) net->mib.icmp_statistics,ICMP_MIB_INMSGS ), +snmp_fold_field ((void __percpu **) net->mib.icmp_statistics,ICMP_MIB_INERRORS ));for (i=0 ; icmpmibmap[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **) net->mib.icmpmsg_statistics, +snmp_fold_field ((void __percpu **) net->mib.icmpmsg_statistics, icmpmibmap[i].index));seq_printf (seq," %lu %lu" , -snmp_fold_field ((void **) net->mib.icmp_statistics,ICMP_MIB_OUTMSGS ), -snmp_fold_field ((void **) net->mib.icmp_statistics,ICMP_MIB_OUTERRORS )); +snmp_fold_field ((void __percpu **) net->mib.icmp_statistics,ICMP_MIB_OUTMSGS ), +snmp_fold_field ((void __percpu **) net->mib.icmp_statistics,ICMP_MIB_OUTERRORS ));for (i=0 ; icmpmibmap[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **) net->mib.icmpmsg_statistics, +snmp_fold_field ((void __percpu **) net->mib.icmpmsg_statistics, icmpmibmap[i].index |0x100 )); }
@@ -341,7 +341,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)for (i =0 ; snmp4_ipstats_list[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.ip_statistics, +snmp_fold_field ((void __percpu **)net->mib.ip_statistics, snmp4_ipstats_list[i].entry));icmp_put (seq);/* RFC 2011 compatibility */
@@ -356,11 +356,11 @@ static int snmp_seq_show(struct seq_file *seq, void *v)/* MaxConn field is signed, RFC 2012 */ if (snmp4_tcp_list[i].entry ==TCP_MIB_MAXCONN )seq_printf (seq," %ld" , -snmp_fold_field ((void **)net->mib.tcp_statistics, +snmp_fold_field ((void __percpu **)net->mib.tcp_statistics, snmp4_tcp_list[i].entry));else seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.tcp_statistics, +snmp_fold_field ((void __percpu **)net->mib.tcp_statistics, snmp4_tcp_list[i].entry)); }
@@ -371,7 +371,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)seq_puts (seq,"\nUdp:" );for (i =0 ; snmp4_udp_list[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.udp_statistics, +snmp_fold_field ((void __percpu **)net->mib.udp_statistics, snmp4_udp_list[i].entry));/* the UDP and UDP-Lite MIBs are the same */
@@ -382,7 +382,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)seq_puts (seq,"\nUdpLite:" );for (i =0 ; snmp4_udp_list[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.udplite_statistics, +snmp_fold_field ((void __percpu **)net->mib.udplite_statistics, snmp4_udp_list[i].entry));seq_putc (seq,'\n' );
@@ -419,7 +419,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)seq_puts (seq,"\nTcpExt:" );for (i =0 ; snmp4_net_list[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.net_statistics, +snmp_fold_field ((void __percpu **)net->mib.net_statistics, snmp4_net_list[i].entry));seq_puts (seq,"\nIpExt:" );
@@ -429,7 +429,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)seq_puts (seq,"\nIpExt:" );for (i =0 ; snmp4_ipextstats_list[i].name !=NULL ; i++)seq_printf (seq," %lu" , -snmp_fold_field ((void **)net->mib.ip_statistics, +snmp_fold_field ((void __percpu **)net->mib.ip_statistics, snmp4_ipextstats_list[i].entry));seq_putc (seq,'\n' );
net/ipv4/route.c +1 -1
@@ -3327,7 +3327,7 @@ static __net_initdata struct pernet_operations rt_secret_timer_ops = {#ifdef CONFIG_NET_CLS_ROUTE -struct ip_rt_acct *ip_rt_acct__read_mostly ; +struct ip_rt_acct __percpu *ip_rt_acct__read_mostly ;#endif /* CONFIG_NET_CLS_ROUTE */ static __initdata unsigned long rhash_entries;
net/ipv4/tcp.c +12 -9
@@ -2788,10 +2788,10 @@ EXPORT_SYMBOL(tcp_gro_complete);#ifdef CONFIG_TCP_MD5SIG static unsigned long tcp_md5sig_users; -static struct tcp_md5sig_pool **tcp_md5sig_pool; +static struct tcp_md5sig_pool *__percpu *tcp_md5sig_pool;static DEFINE_SPINLOCK (tcp_md5sig_pool_lock); -static void __tcp_free_md5sig_pool (struct tcp_md5sig_pool **pool) +static void __tcp_free_md5sig_pool (struct tcp_md5sig_pool *__percpu *pool) {int cpu;for_each_possible_cpu (cpu) {
@@ -2808,7 +2808,7 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool)void tcp_free_md5sig_pool (void ) { -struct tcp_md5sig_pool **pool =NULL ; +struct tcp_md5sig_pool *__percpu *pool =NULL ;spin_lock_bh (&tcp_md5sig_pool_lock);if (--tcp_md5sig_users ==0 ) {
@@ -2822,10 +2822,11 @@ void tcp_free_md5sig_pool(void)EXPORT_SYMBOL (tcp_free_md5sig_pool); -static struct tcp_md5sig_pool **__tcp_alloc_md5sig_pool (struct sock *sk) +static struct tcp_md5sig_pool *__percpu * +__tcp_alloc_md5sig_pool (struct sock *sk) {int cpu; -struct tcp_md5sig_pool **pool; +struct tcp_md5sig_pool *__percpu *pool; pool = alloc_percpu(struct tcp_md5sig_pool *);if (!pool)
@@ -2852,9 +2853,9 @@ out_free:return NULL ; } -struct tcp_md5sig_pool **tcp_alloc_md5sig_pool (struct sock *sk) +struct tcp_md5sig_pool *__percpu *tcp_alloc_md5sig_pool (struct sock *sk) { -struct tcp_md5sig_pool **pool; +struct tcp_md5sig_pool *__percpu *pool;int alloc =0 ; retry:
@@ -2873,7 +2874,9 @@ retry:if (alloc) {/* we cannot hold spinlock here because this may sleep. */ -struct tcp_md5sig_pool **p =__tcp_alloc_md5sig_pool (sk); +struct tcp_md5sig_pool *__percpu *p; + + p =__tcp_alloc_md5sig_pool (sk);spin_lock_bh (&tcp_md5sig_pool_lock);if (!p) { tcp_md5sig_users--;
@@ -2897,7 +2900,7 @@ EXPORT_SYMBOL(tcp_alloc_md5sig_pool);struct tcp_md5sig_pool *__tcp_get_md5sig_pool (int cpu) { -struct tcp_md5sig_pool **p; +struct tcp_md5sig_pool *__percpu *p;spin_lock_bh (&tcp_md5sig_pool_lock); p = tcp_md5sig_pool;if (p)
net/ipv6/addrconf.c +12 -12
@@ -278,31 +278,31 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,static int snmp6_alloc_dev (struct inet6_dev *idev) { -if (snmp_mib_init ((void **)idev->stats.ipv6, +if (snmp_mib_init ((void __percpu **)idev->stats.ipv6,sizeof (struct ipstats_mib )) <0 ) goto err_ip; -if (snmp_mib_init ((void **)idev->stats.icmpv6, +if (snmp_mib_init ((void __percpu **)idev->stats.icmpv6,sizeof (struct icmpv6_mib )) <0 ) goto err_icmp; -if (snmp_mib_init ((void **)idev->stats.icmpv6msg, +if (snmp_mib_init ((void __percpu **)idev->stats.icmpv6msg,sizeof (struct icmpv6msg_mib )) <0 ) goto err_icmpmsg;return 0 ; err_icmpmsg: -snmp_mib_free ((void **)idev->stats.icmpv6); +snmp_mib_free ((void __percpu **)idev->stats.icmpv6); err_icmp: -snmp_mib_free ((void **)idev->stats.ipv6); +snmp_mib_free ((void __percpu **)idev->stats.ipv6); err_ip:return -ENOMEM ; }static void snmp6_free_dev (struct inet6_dev *idev) { -snmp_mib_free ((void **)idev->stats.icmpv6msg); -snmp_mib_free ((void **)idev->stats.icmpv6); -snmp_mib_free ((void **)idev->stats.ipv6); +snmp_mib_free ((void __percpu **)idev->stats.icmpv6msg); +snmp_mib_free ((void __percpu **)idev->stats.icmpv6); +snmp_mib_free ((void __percpu **)idev->stats.ipv6); }/* Nobody refers to this device, we may destroy it. */
@@ -3752,8 +3752,8 @@ static inline size_t inet6_if_nlmsg_size(void) ); } -static inline void __snmp6_fill_stats (u64 *stats,void **mib,int items, -int bytes) +static inline void __snmp6_fill_stats (u64 *stats,void __percpu **mib, +int items,int bytes) {int i;int pad = bytes -sizeof (u64) * items;
@@ -3772,10 +3772,10 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, {switch (attrtype) {case IFLA_INET6_STATS : -__snmp6_fill_stats (stats, (void **)idev->stats.ipv6,IPSTATS_MIB_MAX , bytes); +__snmp6_fill_stats (stats, (void __percpu **)idev->stats.ipv6,IPSTATS_MIB_MAX , bytes);break ;case IFLA_INET6_ICMP6STATS : -__snmp6_fill_stats (stats, (void **)idev->stats.icmpv6,ICMP6_MIB_MAX , bytes); +__snmp6_fill_stats (stats, (void __percpu **)idev->stats.icmpv6,ICMP6_MIB_MAX , bytes);break ; } }
net/ipv6/af_inet6.c +14 -14
@@ -971,41 +971,41 @@ static void ipv6_packet_cleanup(void)static int __net_init ipv6_init_mibs (struct net *net) { -if (snmp_mib_init ((void **)net->mib.udp_stats_in6, +if (snmp_mib_init ((void __percpu **)net->mib.udp_stats_in6,sizeof (struct udp_mib )) <0 )return -ENOMEM ; -if (snmp_mib_init ((void **)net->mib.udplite_stats_in6, +if (snmp_mib_init ((void __percpu **)net->mib.udplite_stats_in6,sizeof (struct udp_mib )) <0 ) goto err_udplite_mib; -if (snmp_mib_init ((void **)net->mib.ipv6_statistics, +if (snmp_mib_init ((void __percpu **)net->mib.ipv6_statistics,sizeof (struct ipstats_mib )) <0 ) goto err_ip_mib; -if (snmp_mib_init ((void **)net->mib.icmpv6_statistics, +if (snmp_mib_init ((void __percpu **)net->mib.icmpv6_statistics,sizeof (struct icmpv6_mib )) <0 ) goto err_icmp_mib; -if (snmp_mib_init ((void **)net->mib.icmpv6msg_statistics, +if (snmp_mib_init ((void __percpu **)net->mib.icmpv6msg_statistics,sizeof (struct icmpv6msg_mib )) <0 ) goto err_icmpmsg_mib;return 0 ; err_icmpmsg_mib: -snmp_mib_free ((void **)net->mib.icmpv6_statistics); +snmp_mib_free ((void __percpu **)net->mib.icmpv6_statistics); err_icmp_mib: -snmp_mib_free ((void **)net->mib.ipv6_statistics); +snmp_mib_free ((void __percpu **)net->mib.ipv6_statistics); err_ip_mib: -snmp_mib_free ((void **)net->mib.udplite_stats_in6); +snmp_mib_free ((void __percpu **)net->mib.udplite_stats_in6); err_udplite_mib: -snmp_mib_free ((void **)net->mib.udp_stats_in6); +snmp_mib_free ((void __percpu **)net->mib.udp_stats_in6);return -ENOMEM ; } static void __net_exit ipv6_cleanup_mibs(struct net *net) { -snmp_mib_free ((void **)net->mib.udp_stats_in6); -snmp_mib_free ((void **)net->mib.udplite_stats_in6); -snmp_mib_free ((void **)net->mib.ipv6_statistics); -snmp_mib_free ((void **)net->mib.icmpv6_statistics); -snmp_mib_free ((void **)net->mib.icmpv6msg_statistics); +snmp_mib_free ((void __percpu **)net->mib.udp_stats_in6); +snmp_mib_free ((void __percpu **)net->mib.udplite_stats_in6); +snmp_mib_free ((void __percpu **)net->mib.ipv6_statistics); +snmp_mib_free ((void __percpu **)net->mib.icmpv6_statistics); +snmp_mib_free ((void __percpu **)net->mib.icmpv6msg_statistics); }static int __net_init inet6_net_init (struct net *net)
net/ipv6/proc.c +14 -10
@@ -136,7 +136,7 @@ static struct snmp_mib snmp6_udplite6_list[] = { SNMP_MIB_SENTINEL }; -static void snmp6_seq_show_icmpv6msg (struct seq_file *seq,void **mib) +static void snmp6_seq_show_icmpv6msg (struct seq_file *seq,void __percpu **mib) {char name[32 ];int i;
@@ -171,7 +171,8 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) }static inline void -snmp6_seq_show_item (struct seq_file *seq,void **mib,struct snmp_mib *itemlist) +snmp6_seq_show_item (struct seq_file *seq,void __percpu **mib, +struct snmp_mib *itemlist) {int i;for (i=0 ; itemlist[i].name; i++)
@@ -183,14 +184,15 @@ static int snmp6_seq_show(struct seq_file *seq, void *v) {struct net *net = (struct net *)seq->private; -snmp6_seq_show_item (seq, (void **)net->mib.ipv6_statistics, +snmp6_seq_show_item (seq, (void __percpu **)net->mib.ipv6_statistics, snmp6_ipstats_list); -snmp6_seq_show_item (seq, (void **)net->mib.icmpv6_statistics, +snmp6_seq_show_item (seq, (void __percpu **)net->mib.icmpv6_statistics, snmp6_icmp6_list); -snmp6_seq_show_icmpv6msg (seq, (void **)net->mib.icmpv6msg_statistics); -snmp6_seq_show_item (seq, (void **)net->mib.udp_stats_in6, +snmp6_seq_show_icmpv6msg (seq, + (void __percpu **)net->mib.icmpv6msg_statistics); +snmp6_seq_show_item (seq, (void __percpu **)net->mib.udp_stats_in6, snmp6_udp6_list); -snmp6_seq_show_item (seq, (void **)net->mib.udplite_stats_in6, +snmp6_seq_show_item (seq, (void __percpu **)net->mib.udplite_stats_in6, snmp6_udplite6_list);return 0 ; }
@@ -213,9 +215,11 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)struct inet6_dev *idev = (struct inet6_dev *)seq->private;seq_printf (seq,"%-32s\t%u\n" ,"ifIndex" , idev->dev->ifindex); -snmp6_seq_show_item (seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); -snmp6_seq_show_item (seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); -snmp6_seq_show_icmpv6msg (seq, (void **)idev->stats.icmpv6msg); +snmp6_seq_show_item (seq, (void __percpu **)idev->stats.ipv6, + snmp6_ipstats_list); +snmp6_seq_show_item (seq, (void __percpu **)idev->stats.icmpv6, + snmp6_icmp6_list); +snmp6_seq_show_icmpv6msg (seq, (void __percpu **)idev->stats.icmpv6msg);return 0 ; }
net/sctp/proc.c +1 -1
@@ -83,7 +83,7 @@ static int sctp_snmp_seq_show(struct seq_file *seq, void *v)for (i =0 ; sctp_snmp_list[i].name !=NULL ; i++)seq_printf (seq,"%-32s\t%ld\n" , sctp_snmp_list[i].name, -snmp_fold_field ((void **)sctp_statistics, +snmp_fold_field ((void __percpu **)sctp_statistics, sctp_snmp_list[i].entry));return 0 ;
net/sctp/protocol.c +3 -2
@@ -996,12 +996,13 @@ int sctp_register_pf(struct sctp_pf *pf, sa_family_t family)static inline int init_sctp_mibs (void ) { -return snmp_mib_init ((void **)sctp_statistics,sizeof (struct sctp_mib )); +return snmp_mib_init ((void __percpu **)sctp_statistics, +sizeof (struct sctp_mib )); }static inline void cleanup_sctp_mibs (void ) { -snmp_mib_free ((void **)sctp_statistics); +snmp_mib_free ((void __percpu **)sctp_statistics); }static void sctp_v4_pf_init (void )
net/xfrm/xfrm_ipcomp.c +8 -8
@@ -30,12 +30,12 @@struct ipcomp_tfms {struct list_head list; -struct crypto_comp **tfms; +struct crypto_comp *__percpu *tfms;int users; };static DEFINE_MUTEX (ipcomp_resource_mutex); -static void **ipcomp_scratches; +static void *__percpu *ipcomp_scratches;static int ipcomp_scratch_users;static LIST_HEAD (ipcomp_tfms_list);
@@ -200,7 +200,7 @@ EXPORT_SYMBOL_GPL(ipcomp_output);static void ipcomp_free_scratches (void ) {int i; -void **scratches; +void *__percpu *scratches;if (--ipcomp_scratch_users)return ;
@@ -215,10 +215,10 @@ static void ipcomp_free_scratches(void)free_percpu (scratches); } -static void **ipcomp_alloc_scratches (void ) +static void *__percpu *ipcomp_alloc_scratches (void ) {int i; -void **scratches; +void *__percpu *scratches;if (ipcomp_scratch_users++)return ipcomp_scratches;
@@ -239,7 +239,7 @@ static void **ipcomp_alloc_scratches(void)return scratches; } -static void ipcomp_free_tfms (struct crypto_comp **tfms) +static void ipcomp_free_tfms (struct crypto_comp *__percpu *tfms) {struct ipcomp_tfms *pos;int cpu;
@@ -267,10 +267,10 @@ static void ipcomp_free_tfms(struct crypto_comp **tfms)free_percpu (tfms); } -static struct crypto_comp **ipcomp_alloc_tfms (const char *alg_name) +static struct crypto_comp *__percpu *ipcomp_alloc_tfms (const char *alg_name) {struct ipcomp_tfms *pos; -struct crypto_comp **tfms; +struct crypto_comp *__percpu *tfms;int cpu;/* This can be any valid CPU ID so we don't need locking. */
net/xfrm/xfrm_policy.c +3 -3
@@ -2369,19 +2369,19 @@ static int __net_init xfrm_statistics_init(struct net *net) {int rv; -if (snmp_mib_init ((void **)net->mib.xfrm_statistics, +if (snmp_mib_init ((void __percpu **)net->mib.xfrm_statistics,sizeof (struct linux_xfrm_mib )) <0 )return -ENOMEM ; rv =xfrm_proc_init (net);if (rv <0 ) -snmp_mib_free ((void **)net->mib.xfrm_statistics); +snmp_mib_free ((void __percpu **)net->mib.xfrm_statistics);return rv; }static void xfrm_statistics_fini (struct net *net) {xfrm_proc_fini (net); -snmp_mib_free ((void **)net->mib.xfrm_statistics); +snmp_mib_free ((void __percpu **)net->mib.xfrm_statistics); }#else static int __net_init xfrm_statistics_init (struct net *net)
net/xfrm/xfrm_proc.c +2 -1
@@ -50,7 +50,8 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)int i;for (i=0 ; xfrm_mib_list[i].name; i++)seq_printf (seq,"%-24s\t%lu\n" , xfrm_mib_list[i].name, -snmp_fold_field ((void **)net->mib.xfrm_statistics, +snmp_fold_field ((void __percpu **) + net->mib.xfrm_statistics, xfrm_mib_list[i].entry));return 0 ; }
Signature · 1 line
1.6.4.2
Re: [PATCH 3/8] percpu: add __percpu sparse annotations to net
From: Tejun Heo <[email protected]>
Date: Tue, 26 Jan 2010 00:22:10 +0900
Quoted 6 lines
Add
__percpusparse annotations to net.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
Quoted 7 lines
The macro and type tricks around snmp stats make things a bit interesting. DEFINE/DECLARE_SNMP_STAT() macros mark the target field as
__percpuandSNMP_UPD_PO_STATS()macro is updated accordingly. All snmp_mib_*() users which used to cast the argument to (void **) are updated to cast it to (void__percpu**).Signed-off-by Tejun Heo <[email protected]>
Tejun Heo
maintainerPATCH 4/8 percpu: add __percpu sparse annotations to net drivers
In reply to Tejun HeoAdd __percpu sparse annotations to net drivers.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- drivers/net/chelsio/sge.c | 2 +- drivers/net/loopback.c | 16 +++++++++------- drivers/net/macvlan.c | 2 +- drivers/net/veth.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-)
drivers/net/chelsio/sge.c +1 -1
@@ -267,7 +267,7 @@ struct sge {struct sk_buff *espibug_skb[MAX_NPORTS ];u32 sge_control;/* shadow value of sge control reg */ struct sge_intr_counts stats; -struct sge_port_stats *port_stats[MAX_NPORTS ]; +struct sge_port_stats __percpu *port_stats[MAX_NPORTS ];struct sched *tx_sched;struct cmdQ cmdQ[SGE_CMDQ_N ]____cacheline_aligned_in_smp ; };
drivers/net/loopback.c +9 -7
@@ -72,7 +72,8 @@ struct pcpu_lstats {static netdev_tx_t loopback_xmit (struct sk_buff *skb,struct net_device *dev) { -struct pcpu_lstats *pcpu_lstats, *lb_stats; +struct pcpu_lstats __percpu *pcpu_lstats; +struct pcpu_lstats *lb_stats;int len;skb_orphan (skb);
@@ -80,7 +81,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, skb->protocol =eth_type_trans (skb, dev);/* it's OK to use per_cpu_ptr() because BHs are off */ - pcpu_lstats = dev->ml_priv; + pcpu_lstats = (void __percpu __force *)dev->ml_priv; lb_stats =this_cpu_ptr (pcpu_lstats); len = skb->len;
@@ -95,14 +96,14 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,static struct net_device_stats *loopback_get_stats (struct net_device *dev) { -const struct pcpu_lstats *pcpu_lstats; +const struct pcpu_lstats __percpu *pcpu_lstats;struct net_device_stats *stats = &dev->stats;unsigned long bytes =0 ;unsigned long packets =0 ;unsigned long drops =0 ;int i; - pcpu_lstats = dev->ml_priv; + pcpu_lstats = (void __percpu __force *)dev->ml_priv;for_each_possible_cpu (i) {const struct pcpu_lstats *lb_stats;
@@ -135,19 +136,20 @@ static const struct ethtool_ops loopback_ethtool_ops = {static int loopback_dev_init (struct net_device *dev) { -struct pcpu_lstats *lstats; +struct pcpu_lstats __percpu *lstats; lstats = alloc_percpu(struct pcpu_lstats);if (!lstats)return -ENOMEM ; - dev->ml_priv = lstats; + dev->ml_priv = (void __force *)lstats;return 0 ; }static void loopback_dev_free (struct net_device *dev) { -struct pcpu_lstats *lstats = dev->ml_priv; +struct pcpu_lstats __percpu *lstats = + (void __percpu __force *)dev->ml_priv;free_percpu (lstats);free_netdev (dev);
drivers/net/macvlan.c +1 -1
@@ -59,7 +59,7 @@ struct macvlan_dev {struct hlist_node hlist;struct macvlan_port *port;struct net_device *lowerdev; -struct macvlan_rx_stats *rx_stats; +struct macvlan_rx_stats __percpu *rx_stats;enum macvlan_mode mode; };
drivers/net/veth.c +2 -2
@@ -34,7 +34,7 @@ struct veth_net_stats {struct veth_priv {struct net_device *peer; -struct veth_net_stats *stats; +struct veth_net_stats __percpu *stats;unsigned ip_summed; };
@@ -263,7 +263,7 @@ static int veth_change_mtu(struct net_device *dev, int new_mtu)static int veth_dev_init (struct net_device *dev) { -struct veth_net_stats *stats; +struct veth_net_stats __percpu *stats;struct veth_priv *priv; stats = alloc_percpu(struct veth_net_stats);
Signature · 1 line
1.6.4.2
Tejun Heo
maintainerPATCH 4/8 percpu: add __percpu sparse annotations to net drivers
In reply to Tejun HeoAdd __percpu sparse annotations to net drivers.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- drivers/net/chelsio/sge.c | 2 +- drivers/net/loopback.c | 16 +++++++++------- drivers/net/macvlan.c | 2 +- drivers/net/veth.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-)
drivers/net/chelsio/sge.c +1 -1
@@ -267,7 +267,7 @@ struct sge {struct sk_buff *espibug_skb[MAX_NPORTS ];u32 sge_control;/* shadow value of sge control reg */ struct sge_intr_counts stats; -struct sge_port_stats *port_stats[MAX_NPORTS ]; +struct sge_port_stats __percpu *port_stats[MAX_NPORTS ];struct sched *tx_sched;struct cmdQ cmdQ[SGE_CMDQ_N ]____cacheline_aligned_in_smp ; };
drivers/net/loopback.c +9 -7
@@ -72,7 +72,8 @@ struct pcpu_lstats {static netdev_tx_t loopback_xmit (struct sk_buff *skb,struct net_device *dev) { -struct pcpu_lstats *pcpu_lstats, *lb_stats; +struct pcpu_lstats __percpu *pcpu_lstats; +struct pcpu_lstats *lb_stats;int len;skb_orphan (skb);
@@ -80,7 +81,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, skb->protocol =eth_type_trans (skb, dev);/* it's OK to use per_cpu_ptr() because BHs are off */ - pcpu_lstats = dev->ml_priv; + pcpu_lstats = (void __percpu __force *)dev->ml_priv; lb_stats =this_cpu_ptr (pcpu_lstats); len = skb->len;
@@ -95,14 +96,14 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,static struct net_device_stats *loopback_get_stats (struct net_device *dev) { -const struct pcpu_lstats *pcpu_lstats; +const struct pcpu_lstats __percpu *pcpu_lstats;struct net_device_stats *stats = &dev->stats;unsigned long bytes =0 ;unsigned long packets =0 ;unsigned long drops =0 ;int i; - pcpu_lstats = dev->ml_priv; + pcpu_lstats = (void __percpu __force *)dev->ml_priv;for_each_possible_cpu (i) {const struct pcpu_lstats *lb_stats;
@@ -135,19 +136,20 @@ static const struct ethtool_ops loopback_ethtool_ops = {static int loopback_dev_init (struct net_device *dev) { -struct pcpu_lstats *lstats; +struct pcpu_lstats __percpu *lstats; lstats = alloc_percpu(struct pcpu_lstats);if (!lstats)return -ENOMEM ; - dev->ml_priv = lstats; + dev->ml_priv = (void __force *)lstats;return 0 ; }static void loopback_dev_free (struct net_device *dev) { -struct pcpu_lstats *lstats = dev->ml_priv; +struct pcpu_lstats __percpu *lstats = + (void __percpu __force *)dev->ml_priv;free_percpu (lstats);free_netdev (dev);
drivers/net/macvlan.c +1 -1
@@ -59,7 +59,7 @@ struct macvlan_dev {struct hlist_node hlist;struct macvlan_port *port;struct net_device *lowerdev; -struct macvlan_rx_stats *rx_stats; +struct macvlan_rx_stats __percpu *rx_stats;enum macvlan_mode mode; };
drivers/net/veth.c +2 -2
@@ -34,7 +34,7 @@ struct veth_net_stats {struct veth_priv {struct net_device *peer; -struct veth_net_stats *stats; +struct veth_net_stats __percpu *stats;unsigned ip_summed; };
@@ -263,7 +263,7 @@ static int veth_change_mtu(struct net_device *dev, int new_mtu)static int veth_dev_init (struct net_device *dev) { -struct veth_net_stats *stats; +struct veth_net_stats __percpu *stats;struct veth_priv *priv; stats = alloc_percpu(struct veth_net_stats);
Signature · 1 line
1.6.4.2
Re: [PATCH 4/8] percpu: add __percpu sparse annotations to net drivers
From: Tejun Heo <[email protected]>
Date: Tue, 26 Jan 2010 00:22:11 +0900
Quoted 7 lines
Add
__percpusparse annotations to net drivers.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
Signed-off-by Tejun Heo <[email protected]>
Tejun Heo
maintainerPATCH 5/8 percpu: add __percpu sparse annotations to x86
In reply to Tejun HeoAdd __percpu sparse annotations to x86.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
In arch/x86/kernel/cpu/common.c, per_cpu(exception_stacks, cpu) is replaced with &per_cpu(exception_stacks[0], cpu) which is equivalent except that it allows per_cpu() macro to correctly drop percpu designation during sparse pass.
--- arch/x86/include/asm/msr.h | 12 +++++++----- arch/x86/kernel/acpi/cstate.c | 2 +- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 +- arch/x86/lib/msr-smp.c | 8 +++++--- arch/x86/lib/msr.c | 6 +++--- 6 files changed, 18 insertions(+), 14 deletions(-)
arch/x86/include/asm/msr.h +7 -5
@@ -30,7 +30,7 @@ struct msr {struct msr_info {u32 msr_no;struct msr reg; -struct msr *msrs; +struct msr __percpu *msrs;int err; };
@@ -256,14 +256,16 @@ do { \#define write_rdtscp_aux (val) wrmsr(MSR_TSC_AUX, (val), 0) -struct msr *msrs_alloc (void ); -void msrs_free (struct msr *msrs); +struct msr __percpu *msrs_alloc (void ); +void msrs_free (struct msr __percpu *msrs);#ifdef CONFIG_SMP int rdmsr_on_cpu (unsigned int cpu,u32 msr_no,u32 *l,u32 *h);int wrmsr_on_cpu (unsigned int cpu,u32 msr_no,u32 l,u32 h); -void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs); -void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs); +void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs); +void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs);int rdmsr_safe_on_cpu (unsigned int cpu,u32 msr_no,u32 *l,u32 *h);int wrmsr_safe_on_cpu (unsigned int cpu,u32 msr_no,u32 l,u32 h);int rdmsr_safe_regs_on_cpu (unsigned int cpu,u32 regs[8 ]);
arch/x86/kernel/acpi/cstate.c +1 -1
@@ -61,7 +61,7 @@ struct cstate_entry {unsigned int ecx; } states[ACPI_PROCESSOR_MAX_POWER ]; }; -static struct cstate_entry *cpu_cstate_entry;/* per CPU ptr */ +static struct cstate_entry __percpu *cpu_cstate_entry;/* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER ];
arch/x86/kernel/cpu/common.c +1 -1
@@ -1146,7 +1146,7 @@ void __cpuinit cpu_init(void)* set up and load the per-CPU TSS */ if (!oist->ist[0 ]) { -char *estacks =per_cpu (exception_stacks, cpu); +char *estacks = &per_cpu (exception_stacks[0 ], cpu);for (v =0 ; v <N_EXCEPTION_STACKS ; v++) { estacks += exception_stack_sizes[v];
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +1 -1
@@ -73,7 +73,7 @@ static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);/* acpi_perf_data is a pointer to percpu data. */ -static struct acpi_processor_performance *acpi_perf_data; +static struct acpi_processor_performance __percpu *acpi_perf_data;static struct cpufreq_driver acpi_cpufreq_driver;
arch/x86/lib/msr-smp.c +5 -3
@@ -64,7 +64,7 @@ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)EXPORT_SYMBOL (wrmsr_on_cpu);static void __rwmsr_on_cpus (const struct cpumask *mask,u32 msr_no, -struct msr *msrs, +struct msr __percpu *msrs,void (*msr_func) (void *info)) {struct msr_info rv;
@@ -91,7 +91,8 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,* @msrs: array of MSR values * */ -void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs) +void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs) {__rwmsr_on_cpus (mask, msr_no, msrs, __rdmsr_on_cpu); }
@@ -105,7 +106,8 @@ EXPORT_SYMBOL(rdmsr_on_cpus);* @msrs: array of MSR values * */ -void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs) +void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs) {__rwmsr_on_cpus (mask, msr_no, msrs, __wrmsr_on_cpu); }
arch/x86/lib/msr.c +3 -3
@@ -2,9 +2,9 @@#include <linux/preempt.h> #include <asm/msr.h> -struct msr *msrs_alloc (void ) +struct msr __percpu *msrs_alloc (void ) { -struct msr *msrs =NULL ; +struct msr __percpu *msrs =NULL ; msrs = alloc_percpu(struct msr);if (!msrs) {
@@ -16,7 +16,7 @@ struct msr *msrs_alloc(void) }EXPORT_SYMBOL (msrs_alloc); -void msrs_free (struct msr *msrs) +void msrs_free (struct msr __percpu *msrs) {free_percpu (msrs); }
Signature · 1 line
1.6.4.2
Tejun Heo
maintainerPATCH 5/8 percpu: add __percpu sparse annotations to x86
In reply to Tejun HeoAdd __percpu sparse annotations to x86.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
In arch/x86/kernel/cpu/common.c, per_cpu(exception_stacks, cpu) is replaced with &per_cpu(exception_stacks[0], cpu) which is equivalent except that it allows per_cpu() macro to correctly drop percpu designation during sparse pass.
--- arch/x86/include/asm/msr.h | 12 +++++++----- arch/x86/kernel/acpi/cstate.c | 2 +- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 +- arch/x86/lib/msr-smp.c | 8 +++++--- arch/x86/lib/msr.c | 6 +++--- 6 files changed, 18 insertions(+), 14 deletions(-)
arch/x86/include/asm/msr.h +7 -5
@@ -30,7 +30,7 @@ struct msr {struct msr_info {u32 msr_no;struct msr reg; -struct msr *msrs; +struct msr __percpu *msrs;int err; };
@@ -256,14 +256,16 @@ do { \#define write_rdtscp_aux (val) wrmsr(MSR_TSC_AUX, (val), 0) -struct msr *msrs_alloc (void ); -void msrs_free (struct msr *msrs); +struct msr __percpu *msrs_alloc (void ); +void msrs_free (struct msr __percpu *msrs);#ifdef CONFIG_SMP int rdmsr_on_cpu (unsigned int cpu,u32 msr_no,u32 *l,u32 *h);int wrmsr_on_cpu (unsigned int cpu,u32 msr_no,u32 l,u32 h); -void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs); -void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs); +void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs); +void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs);int rdmsr_safe_on_cpu (unsigned int cpu,u32 msr_no,u32 *l,u32 *h);int wrmsr_safe_on_cpu (unsigned int cpu,u32 msr_no,u32 l,u32 h);int rdmsr_safe_regs_on_cpu (unsigned int cpu,u32 regs[8 ]);
arch/x86/kernel/acpi/cstate.c +1 -1
@@ -61,7 +61,7 @@ struct cstate_entry {unsigned int ecx; } states[ACPI_PROCESSOR_MAX_POWER ]; }; -static struct cstate_entry *cpu_cstate_entry;/* per CPU ptr */ +static struct cstate_entry __percpu *cpu_cstate_entry;/* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER ];
arch/x86/kernel/cpu/common.c +1 -1
@@ -1146,7 +1146,7 @@ void __cpuinit cpu_init(void)* set up and load the per-CPU TSS */ if (!oist->ist[0 ]) { -char *estacks =per_cpu (exception_stacks, cpu); +char *estacks = &per_cpu (exception_stacks[0 ], cpu);for (v =0 ; v <N_EXCEPTION_STACKS ; v++) { estacks += exception_stack_sizes[v];
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +1 -1
@@ -73,7 +73,7 @@ static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);/* acpi_perf_data is a pointer to percpu data. */ -static struct acpi_processor_performance *acpi_perf_data; +static struct acpi_processor_performance __percpu *acpi_perf_data;static struct cpufreq_driver acpi_cpufreq_driver;
arch/x86/lib/msr-smp.c +5 -3
@@ -64,7 +64,7 @@ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)EXPORT_SYMBOL (wrmsr_on_cpu);static void __rwmsr_on_cpus (const struct cpumask *mask,u32 msr_no, -struct msr *msrs, +struct msr __percpu *msrs,void (*msr_func) (void *info)) {struct msr_info rv;
@@ -91,7 +91,8 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,* @msrs: array of MSR values * */ -void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs) +void rdmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs) {__rwmsr_on_cpus (mask, msr_no, msrs, __rdmsr_on_cpu); }
@@ -105,7 +106,8 @@ EXPORT_SYMBOL(rdmsr_on_cpus);* @msrs: array of MSR values * */ -void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no,struct msr *msrs) +void wrmsr_on_cpus (const struct cpumask *mask,u32 msr_no, +struct msr __percpu *msrs) {__rwmsr_on_cpus (mask, msr_no, msrs, __wrmsr_on_cpu); }
arch/x86/lib/msr.c +3 -3
@@ -2,9 +2,9 @@#include <linux/preempt.h> #include <asm/msr.h> -struct msr *msrs_alloc (void ) +struct msr __percpu *msrs_alloc (void ) { -struct msr *msrs =NULL ; +struct msr __percpu *msrs =NULL ; msrs = alloc_percpu(struct msr);if (!msrs) {
@@ -16,7 +16,7 @@ struct msr *msrs_alloc(void) }EXPORT_SYMBOL (msrs_alloc); -void msrs_free (struct msr *msrs) +void msrs_free (struct msr __percpu *msrs) {free_percpu (msrs); }
Signature · 1 line
1.6.4.2
H. Peter Anvin
reviewerRe: [PATCH 5/8] percpu: add __percpu sparse annotations to x86
Quoted 6 lines · Tejun Heo
In
arch/x86/kernel/cpu/common.c,per_cpu(exception_stacks, cpu)is replaced with &per_cpu(exception_stacks[0], cpu) which is equivalent except that it allowsper_cpu()macro to correctly drop percpu designation during sparse pass.
Same comment as Frederic's about this... this kind of uglification really is unacceptable and needs to be addressed.
Other than that, it looks good.
-hpa
Tejun Heo
maintainerRe: [PATCH 5/8] percpu: add __percpu sparse annotations to x86
Quoted 10 lines · H. Peter Anvin
Quoted 6 lines · Tejun Heo
In
arch/x86/kernel/cpu/common.c,per_cpu(exception_stacks, cpu)is replaced with &per_cpu(exception_stacks[0], cpu) which is equivalent except that it allowsper_cpu()macro to correctly drop percpu designation during sparse pass.Same comment as Frederic's about this... this kind of uglification really is unacceptable and needs to be addressed.
Hmm... I don't think it's too bad but if you don't like it that much, probably the right thing to do is just leave it there and let sparse whine about it. There are only three in-kernel instances at this point, so it's not that big a deal.
Thanks.
Signature · 1 line
tejun
H. Peter Anvin
reviewerRe: [PATCH 5/8] percpu: add __percpu sparse annotations to x86
Quoted 9 lines · Tejun Heo
Quoted 8 lines · H. Peter Anvin
Quoted 6 lines · Tejun Heo
In
arch/x86/kernel/cpu/common.c,per_cpu(exception_stacks, cpu)is replaced with &per_cpu(exception_stacks[0], cpu) which is equivalent except that it allowsper_cpu()macro to correctly drop percpu designation during sparse pass.
Quoted 8 lines
Quoted 2 lines
Same comment as Frederic's about this... this kind of uglification really is unacceptable and needs to be addressed.
Hmm... I don't think it's too bad but if you don't like it that much, probably the right thing to do is just leave it there and let sparse whine about it. There are only three in-kernel instances at this point, so it's not that big a deal.
That would probably be my preference until it can be fixed in a better way. If we paper it over now, it will be forgotten -- and then someone will come along and cargo cult it for no good reason.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Tejun Heo
maintainerPATCH 6/8 percpu: add __percpu sparse annotations to trace
In reply to Tejun HeoAdd __percpu sparse annotations to trace.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- include/linux/ftrace_event.h | 4 ++-- include/trace/ftrace.h | 4 ++-- kernel/trace/trace_event_profile.c | 16 ++++++++-------- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_kprobe.c | 4 ++-- kernel/trace/trace_ksym.c | 10 +++++----- kernel/trace/trace_syscalls.c | 4 ++-- 7 files changed, 22 insertions(+), 22 deletions(-)
include/linux/ftrace_event.h +2 -2
@@ -138,8 +138,8 @@ struct ftrace_event_call {#define FTRACE_MAX_PROFILE_SIZE 2048 -extern char *perf_trace_buf; -extern char *perf_trace_buf_nmi; +extern char __percpu *perf_trace_buf; +extern char __percpu *perf_trace_buf_nmi;#define MAX_FILTER_PRED 32#define MAX_FILTER_STR_VAL 256/* Should handle KSYM_SYMBOL_LEN */
include/trace/ftrace.h +2 -2
@@ -773,7 +773,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \* struct ftrace_event_call *event_call = &event_<call>; * extern void perf_tp_event(int, u64, u64, void *, int); * struct ftrace_raw_##call *entry; -* struct perf_trace_buf *trace_buf; +* struct perf_trace_buf __percpu *trace_buf; * u64 __addr = 0, __count = 1; * unsigned long irq_flags; * struct trace_entry *ent;
@@ -859,7 +859,7 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \struct trace_entry *ent; \int __entry_size; \int __data_size; \ -char *trace_buf; \ + char __percpu *trace_buf; \char *raw_data; \int __cpu; \int rctx; \
kernel/trace/trace_event_profile.c +8 -8
@@ -9,11 +9,11 @@#include "trace.h" -char *perf_trace_buf; -EXPORT_SYMBOL_GPL (perf_trace_buf); +char __percpu *perf_trace_buf; +EXPORT_PER_CPU_SYMBOL_GPL (perf_trace_buf); -char *perf_trace_buf_nmi; -EXPORT_SYMBOL_GPL (perf_trace_buf_nmi); +char __percpu *perf_trace_buf_nmi; +EXPORT_PER_CPU_SYMBOL_GPL (perf_trace_buf_nmi);typedef typeof (char [FTRACE_MAX_PROFILE_SIZE ])perf_trace_t ;
@@ -22,20 +22,20 @@ static int total_profile_count;static int ftrace_profile_enable_event (struct ftrace_event_call *event) { -char *buf; +char __percpu *buf;int ret = -ENOMEM ;if (event->profile_count++ >0 )return 0 ;if (!total_profile_count) { - buf = (char *)alloc_percpu (perf_trace_t); + buf = (char __percpu *)alloc_percpu (perf_trace_t);if (!buf) goto fail_buf;rcu_assign_pointer (perf_trace_buf, buf); - buf = (char *)alloc_percpu (perf_trace_t); + buf = (char __percpu *)alloc_percpu (perf_trace_t);if (!buf) goto fail_buf_nmi;
@@ -81,7 +81,7 @@ int ftrace_profile_enable(int event_id)static void ftrace_profile_disable_event (struct ftrace_event_call *event) { -char *buf, *nmi_buf; +char __percpu *buf, *nmi_buf;if (--event->profile_count >0 )return ;
kernel/trace/trace_functions_graph.c +1 -1
@@ -21,7 +21,7 @@ struct fgraph_cpu_data { };struct fgraph_data { -struct fgraph_cpu_data *cpu_data; +struct fgraph_cpu_data __percpu *cpu_data;/* Place to preserve last processed entry. */ struct ftrace_graph_ent_entry ent;
kernel/trace/trace_kprobe.c +2 -2
@@ -1262,7 +1262,7 @@ static __kprobes int kprobe_profile_func(struct kprobe *kp,struct trace_entry *ent;int size, __size, i, pc, __cpu;unsigned long irq_flags; -char *trace_buf; +char __percpu *trace_buf;char *raw_data;int rctx;
@@ -1327,7 +1327,7 @@ static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,struct trace_entry *ent;int size, __size, i, pc, __cpu;unsigned long irq_flags; -char *trace_buf; +char __percpu *trace_buf;char *raw_data;int rctx;
kernel/trace/trace_ksym.c +5 -5
@@ -42,7 +42,7 @@#define KSYM_TRACER_OP_LEN 3/* rw- */ struct trace_ksym { -struct perf_event **ksym_hbp; +struct perf_event *__percpu *ksym_hbp;struct perf_event_attr attr;#ifdef CONFIG_PROFILE_KSYM_TRACER atomic64_t counter;
@@ -200,8 +200,8 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr) entry->ksym_hbp =register_wide_hw_breakpoint (&entry->attr, ksym_hbp_handler); -if (IS_ERR (entry->ksym_hbp)) { - ret =PTR_ERR (entry->ksym_hbp); +if (IS_ERR ((void __force *)entry->ksym_hbp)) { + ret =PTR_ERR ((void __force *)entry->ksym_hbp);printk (KERN_INFO "ksym_tracer request failed. Try again" " later!!\n" ); goto err;
@@ -331,8 +331,8 @@ static ssize_t ksym_trace_filter_write(struct file *file, entry->ksym_hbp =register_wide_hw_breakpoint (&entry->attr, ksym_hbp_handler); -if (IS_ERR (entry->ksym_hbp)) - ret =PTR_ERR (entry->ksym_hbp); +if (IS_ERR ((void __force *)entry->ksym_hbp)) + ret =PTR_ERR ((void __force *)entry->ksym_hbp);else goto out_unlock; }
kernel/trace/trace_syscalls.c +2 -2
@@ -433,7 +433,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)struct syscall_metadata *sys_data;struct syscall_trace_enter *rec;unsigned long flags; -char *trace_buf; +char __percpu *trace_buf;char *raw_data;int syscall_nr;int rctx;
@@ -531,7 +531,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)struct syscall_trace_exit *rec;unsigned long flags;int syscall_nr; -char *trace_buf; +char __percpu *trace_buf;char *raw_data;int rctx;int size;
Signature · 1 line
1.6.4.2
Re: [PATCH 6/8] percpu: add __percpu sparse annotations to trace
Quoted 7 lines · Tejun Heo
Add
__percpusparse annotations to trace.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
Signed-off-by Tejun Heo <[email protected]>
-- Steve
Quoted 12 lines
Cc Frederic Weisbecker <[email protected]>Cc Ingo Molnar <[email protected]>--- include/linux/ftrace_event.h | 4 ++-- include/trace/ftrace.h | 4 ++-- kernel/trace/trace_event_profile.c | 16 ++++++++-------- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_kprobe.c | 4 ++-- kernel/trace/trace_ksym.c | 10 +++++----- kernel/trace/trace_syscalls.c | 4 ++-- 7 files changed, 22 insertions(+), 22 deletions(-)
Tejun Heo
maintainerPATCH 7/8 percpu: add __percpu sparse annotations to hw_breakpoint
In reply to Tejun HeoAdd __percpu sparse annotations to hw_breakpoint.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu) is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allows per_cpu() macro to correctly drop __percpu designation for the returned pointer.
--- include/linux/hw_breakpoint.h | 8 ++++---- kernel/hw_breakpoint.c | 14 +++++++------- samples/hw_breakpoint/data_breakpoint.c | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-)
include/linux/hw_breakpoint.h +4 -4
@@ -66,14 +66,14 @@ register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,perf_overflow_handler_t triggered, int cpu); -extern struct perf_event ** +extern struct perf_event *__percpu *register_wide_hw_breakpoint (struct perf_event_attr *attr,perf_overflow_handler_t triggered);extern int register_perf_hw_breakpoint (struct perf_event *bp);extern int __register_perf_hw_breakpoint (struct perf_event *bp);extern void unregister_hw_breakpoint (struct perf_event *bp); -extern void unregister_wide_hw_breakpoint (struct perf_event **cpu_events); +extern void unregister_wide_hw_breakpoint (struct perf_event *__percpu *cpu_events);extern int reserve_bp_slot (struct perf_event *bp);extern void release_bp_slot (struct perf_event *bp);
@@ -98,7 +98,7 @@ static inline struct perf_event * register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, perf_overflow_handler_t triggered, int cpu) { return NULL; } -static inline struct perf_event ** +static inline struct perf_event *__percpu *register_wide_hw_breakpoint (struct perf_event_attr *attr,perf_overflow_handler_t triggered) {return NULL ; } static inline int
@@ -107,7 +107,7 @@ static inline int __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }static inline void unregister_hw_breakpoint (struct perf_event *bp) { }static inline void -unregister_wide_hw_breakpoint (struct perf_event **cpu_events) { } +unregister_wide_hw_breakpoint (struct perf_event *__percpu *cpu_events) { }static inline int reserve_bp_slot (struct perf_event *bp) {return -ENOSYS ; }static inline void release_bp_slot (struct perf_event *bp) { }
kernel/hw_breakpoint.c +7 -7
@@ -74,7 +74,7 @@ static DEFINE_MUTEX(nr_bp_mutex);static unsigned int max_task_bp_pinned (int cpu) {int i; -unsigned int *tsk_pinned =per_cpu (nr_task_bp_pinned, cpu); +unsigned int *tsk_pinned = &per_cpu (nr_task_bp_pinned[0 ], cpu);for (i =HBP_NUM -1 ; i >=0 ; i--) {if (tsk_pinned[i] >0 )
@@ -163,7 +163,7 @@ static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable) count =task_bp_pinned (tsk); - tsk_pinned =per_cpu (nr_task_bp_pinned, cpu); + tsk_pinned = &per_cpu (nr_task_bp_pinned[0 ], cpu);if (enable) { tsk_pinned[count]++;if (count >0 )
@@ -377,17 +377,17 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint);* * @return a set of per_cpu pointers to perf events */ -struct perf_event ** +struct perf_event *__percpu *register_wide_hw_breakpoint (struct perf_event_attr *attr,perf_overflow_handler_t triggered) { -struct perf_event **cpu_events, **pevent, *bp; +struct perf_event *__percpu *cpu_events, **pevent, *bp;long err;int cpu; cpu_events =alloc_percpu (typeof (*cpu_events));if (!cpu_events) -return ERR_PTR (-ENOMEM ); +return (void __percpu __force *)ERR_PTR (-ENOMEM );get_online_cpus ();for_each_online_cpu (cpu) {
@@ -415,7 +415,7 @@ fail:put_online_cpus ();free_percpu (cpu_events); -return ERR_PTR (err); +return (void __percpu __force *)ERR_PTR (err); }EXPORT_SYMBOL_GPL (register_wide_hw_breakpoint);
@@ -423,7 +423,7 @@ EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);* unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel * @cpu_events: the per cpu set of events to unregister */ -void unregister_wide_hw_breakpoint (struct perf_event **cpu_events) +void unregister_wide_hw_breakpoint (struct perf_event *__percpu *cpu_events) {int cpu;struct perf_event **pevent;
samples/hw_breakpoint/data_breakpoint.c +3 -3
@@ -34,7 +34,7 @@#include <linux/perf_event.h> #include <linux/hw_breakpoint.h> -struct perf_event **sample_hbp; +struct perf_event *__percpu *sample_hbp;static char ksym_name[KSYM_NAME_LEN ] ="pid_max" ;module_param_string (ksym, ksym_name,KSYM_NAME_LEN ,S_IRUGO );
@@ -61,8 +61,8 @@ static int __init hw_break_module_init(void) attr.bp_type =HW_BREAKPOINT_W |HW_BREAKPOINT_R ; sample_hbp =register_wide_hw_breakpoint (&attr, sample_hbp_handler); -if (IS_ERR (sample_hbp)) { - ret =PTR_ERR (sample_hbp); +if (IS_ERR ((void __force *)sample_hbp)) { + ret =PTR_ERR ((void __force *)sample_hbp); goto fail; }
Signature · 1 line
1.6.4.2
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess __percpu is an address_space attribute? Is there no way to force the address space change directly from the per_cpu() macro?
Thanks.
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello, Frederic.
Quoted 12 lines · Frederic Weisbecker
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.
Quoted 6 lines
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?
Yeah, per_cpu() macro does that but when things get a bit complicated with static percpu arrays. In the above case, the variable is defined as
static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);
which gets translated to
static __attribute__((noderef, address_space(3))) \ __attribute__((section(.data.percpu))) \ __typeof__(unsigned int) nr_task_bp_pinned[HBP_NUM];
The above tells sparse that the members of nr_task_bp_pinned array are in address space 3 which is correct. The problematic dereference was
unsigned int *task_pinned = per_cpu(nr_task_bp_pinned, cpu)
per_cpu() macro changes the address space of the resulting address but it does so assuming that the parameter it got passed is the one which got declared to be in the percpu address space. It casts nr_task_bp_pinned itself, which to the sparse isn't in the percpu address space, to the kernel address space. So, the workaround is basically to give per_cpu() macro the same thing that was defined.
This type of usage (define as array, dereference the array as address) was the only place where I needed to work around to make address space change explicit. There are two places which needed this and hwbreak was one. The options were...
* Leave it alone. We can live with a few additional sparse warnings.
* Make the proposed change. It is slightly ugly but not cryptic or difficult.
* Somehow teach per_cpu() macro or sparse how to handle the above right.
I tried to improve per_cpu() macro but couldn't do it in any sane way. Leaving it alone isn't too bad either but given that the workaround is not horribly unreadable, I think it's best to use the slightly less elegant form in the few places where they are needed.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 56 lines · Tejun Heo
Hello, Frederic.
Quoted 12 lines · Frederic Weisbecker
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.Quoted 6 lines
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?Yeah,
per_cpu()macro does that but when things get a bit complicated with static percpu arrays. In the above case, the variable is defined asstatic DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);which gets translated to
static __attribute__((noderef, address_space(3))) \ __attribute__((section(.data.percpu))) \ __typeof__(unsigned int) nr_task_bp_pinned[HBP_NUM];The above tells sparse that the members of
nr_task_bp_pinnedarray are in address space 3 which is correct. The problematic dereference wasunsigned int
*task_pinned=per_cpu(nr_task_bp_pinned, cpu)
per_cpu()macro changes the address space of the resulting address but it does so assuming that the parameter it got passed is the one which got declared to be in the percpu address space. It castsnr_task_bp_pinneditself, which to the sparse isn't in the percpu address space, to the kernel address space. So, the workaround is basically to giveper_cpu()macro the same thing that was defined.This type of usage (define as array, dereference the array as address) was the only place where I needed to work around to make address space change explicit. There are two places which needed this and hwbreak was one. The options were...
* Leave it alone. We can live with a few additional sparse warnings.
* Make the proposed change. It is slightly ugly but not cryptic or difficult.
Quoted 7 lines
* Somehow teach
per_cpu()macro or sparse how to handle the above right.I tried to improve
per_cpu()macro but couldn't do it in any sane way. Leaving it alone isn't too bad either but given that the workaround is not horribly unreadable, I think it's best to use the slightly less elegant form in the few places where they are needed.
Ok.
Well, sorry I must be missing something obvious, but is it impossible to make per_cpu(var, cpu) returning something cast in:
(typeof(var) __force)
Or I guess you did that already and it is not working with static arrays, or?
Is there a patch that shows per_cpu() macro changes in the batch?
Thanks.
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello,
Quoted 7 lines · Frederic Weisbecker
Well, sorry I must be missing something obvious, but is it impossible to make
per_cpu(var, cpu)returning something cast in:(typeof(var) __force)Or I guess you did that already and it is not working with static arrays, or?
Yeap, the definition looks like
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \
__verify_pcpu_ptr((__p)); \
RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \})
#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
but it just ends up putting the __force at the wrong layer. It seems that (typeof(var) __kernel __force) tell sparse var is in the kernel address space but not its members.
Quoted 1 line
Is there a patch that shows
per_cpu()macro changes in the batch?
Sorry I forgot to write about this. It's in the percpu tree.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git for-next
The related commits are 545695fb41da117928ab946067a42d9e15fd009d and e0fdb0e050eae331046385643618f12452aa7e73.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 16 lines · Tejun Heo
Hello,
Quoted 7 lines · Frederic Weisbecker
Well, sorry I must be missing something obvious, but is it impossible to make
per_cpu(var, cpu)returning something cast in:(typeof(var) __force)Or I guess you did that already and it is not working with static arrays, or?
Yeap, the definition looks like
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \
Quoted 8 lines
})
#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))but it just ends up putting the
__forceat the wrong layer. It seems that (typeof(var)__kernel__force) tell sparse var is in the kernel address space but not its members.
So, may be it considers you are applying the address space overriding to the pointer to the type and not to the type itself.
Consider:
int __percpu i;
What you do above *might* be considered as if SHIFT_PERCPU_PTR returns something of a type:
int * __percpu i;
So the pointer is in the normal address space, but its content is in __percpu address space.
What if you do this:
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \
__verify_pcpu_ptr((__p)); \
RELOC_HIDE((__p), (__offset)); \
})#define per_cpu(var, cpu) \
(typeof(var) __kernel __force)(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))This should work because &(var) should be dereferencable directly, since it is not of type "__force t" but of type "*__force t"
And you're not doing anymore this:
*(int * __kernel __force) i; but *(int __kernel __force *) i;
That all might make no sense, I'm just trying to think like a backend so it might sound like I should just take more sleep and just shut up...
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello,
Quoted 18 lines · Frederic Weisbecker
So, may be it considers you are applying the address space overriding to the pointer to the type and not to the type itself.
Consider:
int __percpu i;What you do above *might* be considered as if
SHIFT_PERCPU_PTRreturns something of a type:int * __percpu i;So the pointer is in the normal address space, but its content is in
__percpuaddress space.What if you do this:
Quoted 7 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((__p), (__offset)); \ })#define per_cpu(var, cpu) \ (typeof(var) __kernel __force)(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
arch/x86/kernel/cpu/common.c:1149:20: warning: cast to non-scalar arch/x86/kernel/cpu/common.c:1149:20: error: strange non-value function or array
CC arch/x86/kernel/cpu/common.oarch/x86/kernel/cpu/common.c: In function 'cpu_init':arch/x86/kernel/cpu/common.c:1149: error: cast specifies array type
Can't cast that way. :-(
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 29 lines · Tejun Heo
Hello,
Quoted 18 lines · Frederic Weisbecker
So, may be it considers you are applying the address space overriding to the pointer to the type and not to the type itself.
Consider:
int __percpu i;What you do above *might* be considered as if
SHIFT_PERCPU_PTRreturns something of a type:int * __percpu i;So the pointer is in the normal address space, but its content is in
__percpuaddress space.What if you do this:
Quoted 7 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((__p), (__offset)); \ })#define per_cpu(var, cpu) \ (typeof(var) __kernel __force)(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
Quoted 7 lines
arch/x86/kernel/cpu/common.c:1149:20: warning: cast to non-scalararch/x86/kernel/cpu/common.c:1149:20: error: strange non-value function or array
CCarch/x86/kernel/cpu/common.oarch/x86/kernel/cpu/common.c: In function 'cpu_init':arch/x86/kernel/cpu/common.c:1149: error: cast specifies array typeCan't cast that way. :-(
What about this? It doesn't use direct cast to scalar but should create a pointer type to kernel space datas:
#define kernel_space_t(var) \ (typeof(var) __kernel __force)
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \
__verify_pcpu_ptr((__p)); \
RELOC_HIDE((typeof(*(kernel_space_t(var)) __kernel __force *)(__p), (__offset)); \
})#define per_cpu(var, cpu) \
(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 39 lines · Frederic Weisbecker
Quoted 29 lines · Tejun Heo
Hello,
Quoted 18 lines · Frederic Weisbecker
So, may be it considers you are applying the address space overriding to the pointer to the type and not to the type itself.
Consider:
int __percpu i;What you do above *might* be considered as if
SHIFT_PERCPU_PTRreturns something of a type:int * __percpu i;So the pointer is in the normal address space, but its content is in
__percpuaddress space.What if you do this:
Quoted 7 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((__p), (__offset)); \ })#define per_cpu(var, cpu) \ (typeof(var) __kernel __force)(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))Quoted 7 lines
arch/x86/kernel/cpu/common.c:1149:20: warning: cast to non-scalararch/x86/kernel/cpu/common.c:1149:20: error: strange non-value function or array
CCarch/x86/kernel/cpu/common.oarch/x86/kernel/cpu/common.c: In function 'cpu_init':arch/x86/kernel/cpu/common.c:1149: error: cast specifies array typeCan't cast that way. :-(
Quoted 6 lines
What about this? It doesn't use direct cast to scalar but should create a pointer type to kernel space datas:
#define kernel_space_t(var) \ (typeof(var) __kernel __force)
Should be typeof(*var)
Quoted 9 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(kernel_space_t(var)) __kernel __force *)(__p), (__offset)); \ })#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 4 lines · Frederic Weisbecker
Quoted 4 lines
What about this? It doesn't use direct cast to scalar but should create a pointer type to kernel space datas:
Quoted 11 lines
Quoted 2 lines
#define kernel_space_t(var) \ (typeof(var) __kernel __force)Should be
typeof(*var)Quoted 5 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(kernel_space_t(var)) __kernel __force *)(__p), (__offset)); \ })
Can you balance ()'s here too?
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 12 lines · Tejun Heo
Quoted 11 lines · Frederic Weisbecker
Quoted 6 lines
What about this? It doesn't use direct cast to scalar but should create a pointer type to kernel space datas:
#define kernel_space_t(var) \ (typeof(var) __kernel __force)Should be
typeof(*var)Quoted 1 line
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(kernel_space_t(var)) __kernel __force *)(__p), (__offset)); \ })Can you balance ()'s here too?
#define kernel_space_t(var) \
(typeof(*(var)) __kernel __force)/* Weird cast keeps both GCC and sparse happy. */
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \
__verify_pcpu_ptr((__p)); \
RELOC_HIDE((typeof(*(kernel_space_t(__p))) __kernel __force *)(__p), (__offset)); \
})#define per_cpu(var, cpu) \
(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)));No guarantee that will build. I should pull your tree and install sparse (yeah, shame on me, I've never installed it).
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 2 lines · Frederic Weisbecker
No guarantee that will build. I should pull your tree and install sparse (yeah, shame on me, I've never installed it).
Nope, it doesn't. Please pull from the following tree to receive the whole thing. The definitions in question are in include/asm-generic/percpu.h.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git percpu-sparse-review
After installing sparse,
make C=2 arch/x86/kernel/cpu/common.o
should be enough.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
In reply to Frederic WeisbeckerQuoted 53 lines · Frederic Weisbecker
Quoted 16 lines · Tejun Heo
Hello,
Quoted 7 lines · Frederic Weisbecker
Well, sorry I must be missing something obvious, but is it impossible to make
per_cpu(var, cpu)returning something cast in:(typeof(var) __force)Or I guess you did that already and it is not working with static arrays, or?
Yeap, the definition looks like
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \Quoted 8 lines
})
#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))but it just ends up putting the
__forceat the wrong layer. It seems that (typeof(var)__kernel__force) tell sparse var is in the kernel address space but not its members.So, may be it considers you are applying the address space overriding to the pointer to the type and not to the type itself.
Consider:
int __percpu i;What you do above *might* be considered as if
SHIFT_PERCPU_PTRreturns something of a type:int * __percpu i;So the pointer is in the normal address space, but its content is in
__percpuaddress space.What if you do this:
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((__p), (__offset)); \ })#define per_cpu(var, cpu) \ (typeof(var) __kernel __force)(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
Quoted 8 lines
This should work because &(var) should be dereferencable directly, since it is not of type "
__forcet" but of type "*__forcet"And you're not doing anymore this:
*(int * __kernel __force) i; but *(int __kernel __force *) i;
The above is perhaps a bit confusing.
To be more clear, in the first case you only cast the pointer to the type, which gives you a pointer valid in kernel space to data valid in percpu space.
The second case gives you something valid in kernel space for both.
H. Peter Anvin
reviewerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
In reply to Frederic WeisbeckerQuoted 12 lines · Frederic Weisbecker
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.
Quoted 7 lines
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?
A cast (using __typeof__) combined with an address space override?
-hpa
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello,
Quoted 1 line · H. Peter Anvin
A cast (using
__typeof__) combined with an address space override?
That still puts the address specification at the wrong level. The problem is that the __typeof__ would be an array type which itself doesn't have address space set but its members are in address space 3. So, you need to get *inside* the array type def to change that. :-(
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 9 lines · Tejun Heo
Hello,
Quoted 1 line · H. Peter Anvin
A cast (using
__typeof__) combined with an address space override?That still puts the address specification at the wrong level. The problem is that the
__typeof__would be an array type which itself doesn't have address space set but its members are in address space 3. So, you need to get *inside* the array type def to change that. :-(
Could you post the actual definitions in one piece? Would be easier to discuss what's going on...
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 6 lines · Al Viro
Quoted 5 lines · Tejun Heo
Hello,
Quoted 1 line · H. Peter Anvin
A cast (using
__typeof__) combined with an address space override?
Quoted 7 lines
Quoted 4 lines
That still puts the address specification at the wrong level. The problem is that the
__typeof__would be an array type which itself doesn't have address space set but its members are in address space 3. So, you need to get *inside* the array type def to change that. :-(Could you post the actual definitions in one piece? Would be easier to discuss what's going on...
Here it is.
# define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })#define __verify_pcpu_ptr(ptr) do { \
const void __percpu *__vpp_verify = (typeof(ptr))NULL; \
(void)__vpp_verify; \
} while (0)/* Weird cast keeps both GCC and sparse happy. */
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \
__verify_pcpu_ptr((__p)); \
RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \
})#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 10 lines · Tejun Heo
# define RELOC_HIDE(ptr, off) \ ({ unsigned long __ptr; \ __ptr = (unsigned long) (ptr); \ (typeof(ptr)) (__ptr + (off)); })#define __verify_pcpu_ptr(ptr) do { \ const void __percpu *__vpp_verify = (typeof(ptr))NULL; \ (void)__vpp_verify; \ } while (0)
Quoted 8 lines
/* Weird cast keeps both GCC and sparse happy. */
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \ })#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
Eh... You are leaving that noderef in place in case of array. And _that_ is not an address space, so casts to AS 0 won't do you any good.
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello,
Quoted 18 lines · Al Viro
Quoted 16 lines · Tejun Heo
# define RELOC_HIDE(ptr, off) \ ({ unsigned long __ptr; \ __ptr = (unsigned long) (ptr); \ (typeof(ptr)) (__ptr + (off)); })#define __verify_pcpu_ptr(ptr) do { \ const void __percpu *__vpp_verify = (typeof(ptr))NULL; \ (void)__vpp_verify; \ } while (0)/* Weird cast keeps both GCC and sparse happy. */
#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ __verify_pcpu_ptr((__p)); \ RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \ })
Quoted 5 lines
Quoted 2 lines
#define per_cpu(var, cpu) \ (*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))Eh... You are leaving that noderef in place in case of array. And _that_ is not an address space, so casts to AS 0 won't do you any good.
Any ideas on how to fix it?
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 4 lines · Tejun Heo
Quoted 2 lines
Eh... You are leaving that noderef in place in case of array. And _that_ is not an address space, so casts to AS 0 won't do you any good.
Any ideas on how to fix it?
BTW, before we go any further, which warnings are you getting from sparse and which version of sparse are you using?
noderef is one thing; address_space mess is a different story. The version I have here steps into the former, but not the latter; what are you seeing?
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Hello,
Quoted 5 lines · Al Viro
Quoted 3 lines · Tejun Heo
Quoted 2 lines
Eh... You are leaving that noderef in place in case of array. And _that_ is not an address space, so casts to AS 0 won't do you any good.
Quoted 7 lines
Quoted 1 line
Any ideas on how to fix it?
BTW, before we go any further, which warnings are you getting from sparse and which version of sparse are you using?
noderef is one thing;
address_spacemess is a different story. The version I have here steps into the former, but not the latter; what are you seeing?
Oops, I too am seeing the noderef thing not the address space warning.
char *estacks = per_cpu(exception_stacks, cpu);
I get
arch/x86/kernel/cpu/common.c:1149:19: warning: incorrect type in initializer (different modifiers)arch/x86/kernel/cpu/common.c:1149:19: expected char *estacksarch/x86/kernel/cpu/common.c:1149:19: got char [noderef] *<noident>
CC arch/x86/kernel/cpu/common.o
$ rpm -qi sparse Name : sparse Relocations: (not relocatable) Version : 0.4.1.git1 Vendor: openSUSE Release : 3.2 Build Date: Sat 24 Oct 2009 11:58:16 AM KST
Thanks.
Signature · 1 line
tejun
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 10 lines · Tejun Heo
Hello,
Quoted 7 lines · Al Viro
Quoted 4 lines · Tejun Heo
Quoted 2 lines
Eh... You are leaving that noderef in place in case of array. And _that_ is not an address space, so casts to AS 0 won't do you any good.
Any ideas on how to fix it?
Quoted 7 lines
Quoted 5 lines
BTW, before we go any further, which warnings are you getting from sparse and which version of sparse are you using?
noderef is one thing;
address_spacemess is a different story. The version I have here steps into the former, but not the latter; what are you seeing?Oops, I too am seeing the noderef thing not the address space warning.
OK... So all messing around __kernel __force is actually a red herring.
Frankly, for now I'd keep it as in your patch. Yes, including workarounds in these few places. Longer term... We probably want to implement __attribute__((qualify(...)))/__attribute__((unqualify(...))), revert __typeof__ for AS/noderef to what gcc is doing for normal qualifiers (i.e. "if p is int const *, typeof(*p) v gives const int") go for explicit __unqualify((address_space,noderef)) in there. Playing interesting games with arrays for unqualify (i.e. creating parallel chains of type nodes all way down to the place where original qualifier had been applied).
H. Peter Anvin
reviewerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
In reply to Frederic WeisbeckerQuoted 12 lines · Frederic Weisbecker
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.
Quoted 7 lines
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?
Hmm... thinking more about it, we should be able to just move the & and
[0] into the per_cpu() macro, addressing the situation, or does that cause problems elsewhere?
-hpa
Re: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
Quoted 21 lines · H. Peter Anvin
Quoted 12 lines · Frederic Weisbecker
Quoted 10 lines · Tejun Heo
Add
__percpusparse annotations tohw_breakpoint.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
per_cpu(nr_task_bp_pinned, cpu)is replaced with &per_cpu(nr_task_bp_pinned[0], cpu). This is the same to the compiler but allowsper_cpu()macro to correctly drop__percpudesignation for the returned pointer.Quoted 7 lines
Ouch... It's unpleasant to see such workaround that messes up the code just to make sparse happy.
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?
Quoted 5 lines
Hmm... thinking more about it, we should be able to just move the & and
[0] into theper_cpu()macro, addressing the situation, or does that cause problems elsewhere?-hpa
That would work only with arrays. per_cpu() can access either pointers or direct values. Well that can be worked around with fake casts, but I would except the (typeof(x) __force) to work and then offer a more elegant solution.
Tejun Heo
maintainerRe: [PATCH 7/8] percpu: add __percpu sparse annotations to hw_breakpoint
In reply to H. Peter AnvinHello,
Quoted 8 lines · H. Peter Anvin
Quoted 4 lines
I guess
__percpuis anaddress_spaceattribute? Is there no way to force the address space change directly from theper_cpu()macro?Hmm... thinking more about it, we should be able to just move the & and
[0] into theper_cpu()macro, addressing the situation, or does that cause problems elsewhere?
Hmmm.... the argument gotta be an lvalue. Let me try just in case. Nope, it doesn't work.
Thanks.
Signature · 1 line
tejun
Tejun Heo
maintainerPATCH 8/8 percpu: add __percpu sparse annotations to what's left
In reply to Tejun HeoAdd __percpu sparse annotations to places which didn't make it in one of the previous patches. All converions are trivial.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- crypto/cryptd.c | 2 +- drivers/acpi/processor_perflib.c | 2 +- drivers/dma/dmaengine.c | 2 +- drivers/edac/amd64_edac.c | 2 +- drivers/md/raid5.c | 2 +- drivers/md/raid5.h | 2 +- include/acpi/processor.h | 2 +- include/linux/dmaengine.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-)
crypto/cryptd.c +1 -1
@@ -31,7 +31,7 @@ struct cryptd_cpu_queue { };struct cryptd_queue { -struct cryptd_cpu_queue *cpu_queue; +struct cryptd_cpu_queue __percpu *cpu_queue; };struct cryptd_instance_ctx {
drivers/acpi/processor_perflib.c +1 -1
@@ -557,7 +557,7 @@ end: }int acpi_processor_preregister_performance ( -struct acpi_processor_performance *performance) +struct acpi_processor_performance __percpu *performance) {int count, count_target;int retval =0 ;
drivers/dma/dmaengine.c +1 -1
@@ -284,7 +284,7 @@ struct dma_chan_tbl_ent {/** * channel_table - percpu lookup table for memory-to-memory offload providers */ -static struct dma_chan_tbl_ent *channel_table[DMA_TX_TYPE_END ]; +static struct dma_chan_tbl_ent __percpu *channel_table[DMA_TX_TYPE_END ];static int __init dma_channel_table_init (void ) {
drivers/edac/amd64_edac.c +1 -1
@@ -13,7 +13,7 @@ module_param(report_gart_errors, int, 0644);static int ecc_enable_override;module_param (ecc_enable_override, int,0644 ); -static struct msr *msrs; +static struct msr __percpu *msrs;/* Lookup table for all possible MC control instances */ struct amd64_pvt ;
drivers/md/raid5.c +1 -1
@@ -4680,7 +4680,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf) {unsigned long cpu;struct page *spare_page; -struct raid5_percpu *allcpus; +struct raid5_percpu __percpu *allcpus;void *scribble;int err;
drivers/md/raid5.h +1 -1
@@ -405,7 +405,7 @@ struct raid5_private_data {* lists and performing address * conversions */ - } *percpu; + }__percpu *percpu;size_t scribble_len;/* size of scribble region must be * associated with conf to handle * cpu hotplug while reshaping
include/acpi/processor.h +1 -1
@@ -238,7 +238,7 @@ struct acpi_processor_errata {extern int acpi_processor_preregister_performance (struct acpi_processor_performance - *performance); +__percpu *performance);extern int acpi_processor_register_performance (struct acpi_processor_performance *performance,unsigned int cpu);
include/linux/dmaengine.h +1 -1
@@ -162,7 +162,7 @@ struct dma_chan {struct dma_chan_dev *dev;struct list_head device_node; -struct dma_chan_percpu *local; +struct dma_chan_percpu __percpu *local;int client_count;int table_count;void *private;
Signature · 1 line
1.6.4.2
Tejun Heo
maintainerPATCH 8/8 percpu: add __percpu sparse annotations to what's left
In reply to Tejun HeoAdd __percpu sparse annotations to places which didn't make it in one of the previous patches. All converions are trivial.
These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
--- crypto/cryptd.c | 2 +- drivers/acpi/processor_perflib.c | 2 +- drivers/dma/dmaengine.c | 2 +- drivers/edac/amd64_edac.c | 2 +- drivers/md/raid5.c | 2 +- drivers/md/raid5.h | 2 +- include/acpi/processor.h | 2 +- include/linux/dmaengine.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-)
crypto/cryptd.c +1 -1
@@ -31,7 +31,7 @@ struct cryptd_cpu_queue { };struct cryptd_queue { -struct cryptd_cpu_queue *cpu_queue; +struct cryptd_cpu_queue __percpu *cpu_queue; };struct cryptd_instance_ctx {
drivers/acpi/processor_perflib.c +1 -1
@@ -557,7 +557,7 @@ end: }int acpi_processor_preregister_performance ( -struct acpi_processor_performance *performance) +struct acpi_processor_performance __percpu *performance) {int count, count_target;int retval =0 ;
drivers/dma/dmaengine.c +1 -1
@@ -284,7 +284,7 @@ struct dma_chan_tbl_ent {/** * channel_table - percpu lookup table for memory-to-memory offload providers */ -static struct dma_chan_tbl_ent *channel_table[DMA_TX_TYPE_END ]; +static struct dma_chan_tbl_ent __percpu *channel_table[DMA_TX_TYPE_END ];static int __init dma_channel_table_init (void ) {
drivers/edac/amd64_edac.c +1 -1
@@ -13,7 +13,7 @@ module_param(report_gart_errors, int, 0644);static int ecc_enable_override;module_param (ecc_enable_override, int,0644 ); -static struct msr *msrs; +static struct msr __percpu *msrs;/* Lookup table for all possible MC control instances */ struct amd64_pvt ;
drivers/md/raid5.c +1 -1
@@ -4680,7 +4680,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf) {unsigned long cpu;struct page *spare_page; -struct raid5_percpu *allcpus; +struct raid5_percpu __percpu *allcpus;void *scribble;int err;
drivers/md/raid5.h +1 -1
@@ -405,7 +405,7 @@ struct raid5_private_data {* lists and performing address * conversions */ - } *percpu; + }__percpu *percpu;size_t scribble_len;/* size of scribble region must be * associated with conf to handle * cpu hotplug while reshaping
include/acpi/processor.h +1 -1
@@ -238,7 +238,7 @@ struct acpi_processor_errata {extern int acpi_processor_preregister_performance (struct acpi_processor_performance - *performance); +__percpu *performance);extern int acpi_processor_register_performance (struct acpi_processor_performance *performance,unsigned int cpu);
include/linux/dmaengine.h +1 -1
@@ -162,7 +162,7 @@ struct dma_chan {struct dma_chan_dev *dev;struct list_head device_node; -struct dma_chan_percpu *local; +struct dma_chan_percpu __percpu *local;int client_count;int table_count;void *private;
Signature · 1 line
1.6.4.2
Re: [PATCH 8/8] percpu: add __percpu sparse annotations to what's left
Quoted 13 lines · Tejun Heo
Add
__percpusparse annotations to places which didn't make it in one of the previous patches. All converions are trivial.These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds.
Signed-off-by Tejun Heo <[email protected]>Cc Dan Williams <[email protected]>Cc Borislav Petkov <[email protected]>Cc Huang Ying <[email protected]>Cc Len Brown <[email protected]>Cc Neil Brown <[email protected]>
Quoted 5 lines
--- crypto/cryptd.c | 2 +- drivers/acpi/processor_perflib.c | 2 +- drivers/dma/dmaengine.c | 2 +- drivers/edac/amd64_edac.c | 2 +-
For the edac bits:
Signature · 6 lines
Regards/Gruss, Boris. -- Advanced Micro Devices, Inc. Operating Systems Research Center
Quoted 24 lines · Tejun Heo
This patchset adds
__percpusparse annotations to all percpu users covered byx86_64allmodconfig.__percpuannotation teaches sparse that percpu variables live in a separate address space and can't be accessed directly without going through percpu accessors. This allows detection of most percpu access mistakes involving both static and dyanmic percpu variables.This patchset contains the following eight patches.
0001-percpu-add-__percpu-sparse-annotations-to-core-kerne.patch 0002-percpu-add-__percpu-sparse-annotations-to-fs.patch 0003-percpu-add-__percpu-sparse-annotations-to-net.patch 0004-percpu-add-__percpu-sparse-annotations-to-net-driver.patch 0005-percpu-add-__percpu-sparse-annotations-to-x86.patch 0006-percpu-add-__percpu-sparse-annotations-to-trace.patch 0007-percpu-add-__percpu-sparse-annotations-to-hw_breakpo.patch 0008-percpu-add-__percpu-sparse-annotations-to-what-s-lef.patch
As these annotations are for sparse, none of the above patches affects normal kernel build and most of the conversions are straight-forward and trivial. There are a few places where the conversion isn't completely straight-forward (but still fairly trivial). Those are mentioned in each patch description.
Quoted 8 lines
I can route the patch through percpu and conflict resolution, if necessary, wouldn't be difficult at all for these changes. If anyone wants to route one of these patches through a different tree, please let me know. All that's necessary would be adding dummy
__percpudefinition to the patch.If nobody objects, I'll push these into percpu tree in three or four days.
Um. Where *is* the definition of __percpu? Presumably, that'd be something like __attribute__((noderef,address_space(4)) under ifdef __CHECKER__ and empty otherwise? If so, I'm fine with that patchset, provided that it does grow that #define and becomes self-contained...
Tejun Heo
maintainerHello,
Quoted 4 lines · Al Viro
Um. Where *is* the definition of
__percpu? Presumably, that'd be something like __attribute__((noderef,address_space(4)) under ifdef__CHECKER__and empty otherwise? If so, I'm fine with that patchset, provided that it does grow that #define and becomes self-contained...
Ah... sorry, I forgot about the base tree. The definition has been in the percpu tree for some time now. The patchset is on top of the following branch.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git for-next
and the series is available as git tree in the following branch.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git percpu-sparse-review
The definition is in include/linux/compiler.h.
# define __percpu __attribute__((noderef, address_space(3)))
which gets replaced by dummy def if !__CHECKER__.
Thanks.
Signature · 1 line
tejun
Tejun Heo
maintainerQuoted 2 lines · Tejun Heo
If nobody objects, I'll push these into percpu tree in three or four days.
Patchset pushed out w/ the array workarounds dropped.
Thanks.
Signature · 1 line
tejun