Commit 44ee63587dce85593c22497140db16f4e5027860
Committed by
Frederic Weisbecker
1 parent
018cbffe68
Exists in
master
and in
20 other branches
percpu: Add __percpu sparse annotations to hw_breakpoint
Add __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. In kernel/hw_breakpoint.c, per_cpu(nr_task_bp_pinned, cpu)'s will trigger spurious noderef related warnings from sparse. Changing it to &per_cpu(nr_task_bp_pinned[0], cpu) will work around the problem but deemed to ugly by the maintainer. Leave it alone until better solution can be found. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: K.Prasad <prasad@linux.vnet.ibm.com> LKML-Reference: <4B7B4B7A.9050902@kernel.org> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Showing 3 changed files with 12 additions and 12 deletions Side-by-side Diff
include/linux/hw_breakpoint.h
... | ... | @@ -66,14 +66,14 @@ |
66 | 66 | perf_overflow_handler_t triggered, |
67 | 67 | int cpu); |
68 | 68 | |
69 | -extern struct perf_event ** | |
69 | +extern struct perf_event * __percpu * | |
70 | 70 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
71 | 71 | perf_overflow_handler_t triggered); |
72 | 72 | |
73 | 73 | extern int register_perf_hw_breakpoint(struct perf_event *bp); |
74 | 74 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); |
75 | 75 | extern void unregister_hw_breakpoint(struct perf_event *bp); |
76 | -extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events); | |
76 | +extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); | |
77 | 77 | |
78 | 78 | extern int dbg_reserve_bp_slot(struct perf_event *bp); |
79 | 79 | extern int dbg_release_bp_slot(struct perf_event *bp); |
... | ... | @@ -100,7 +100,7 @@ |
100 | 100 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
101 | 101 | perf_overflow_handler_t triggered, |
102 | 102 | int cpu) { return NULL; } |
103 | -static inline struct perf_event ** | |
103 | +static inline struct perf_event * __percpu * | |
104 | 104 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
105 | 105 | perf_overflow_handler_t triggered) { return NULL; } |
106 | 106 | static inline int |
... | ... | @@ -109,7 +109,7 @@ |
109 | 109 | __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } |
110 | 110 | static inline void unregister_hw_breakpoint(struct perf_event *bp) { } |
111 | 111 | static inline void |
112 | -unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { } | |
112 | +unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { } | |
113 | 113 | static inline int |
114 | 114 | reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } |
115 | 115 | static inline void release_bp_slot(struct perf_event *bp) { } |
kernel/hw_breakpoint.c
... | ... | @@ -413,17 +413,17 @@ |
413 | 413 | * |
414 | 414 | * @return a set of per_cpu pointers to perf events |
415 | 415 | */ |
416 | -struct perf_event ** | |
416 | +struct perf_event * __percpu * | |
417 | 417 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
418 | 418 | perf_overflow_handler_t triggered) |
419 | 419 | { |
420 | - struct perf_event **cpu_events, **pevent, *bp; | |
420 | + struct perf_event * __percpu *cpu_events, **pevent, *bp; | |
421 | 421 | long err; |
422 | 422 | int cpu; |
423 | 423 | |
424 | 424 | cpu_events = alloc_percpu(typeof(*cpu_events)); |
425 | 425 | if (!cpu_events) |
426 | - return ERR_PTR(-ENOMEM); | |
426 | + return (void __percpu __force *)ERR_PTR(-ENOMEM); | |
427 | 427 | |
428 | 428 | get_online_cpus(); |
429 | 429 | for_each_online_cpu(cpu) { |
... | ... | @@ -451,7 +451,7 @@ |
451 | 451 | put_online_cpus(); |
452 | 452 | |
453 | 453 | free_percpu(cpu_events); |
454 | - return ERR_PTR(err); | |
454 | + return (void __percpu __force *)ERR_PTR(err); | |
455 | 455 | } |
456 | 456 | EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); |
457 | 457 | |
... | ... | @@ -459,7 +459,7 @@ |
459 | 459 | * unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel |
460 | 460 | * @cpu_events: the per cpu set of events to unregister |
461 | 461 | */ |
462 | -void unregister_wide_hw_breakpoint(struct perf_event **cpu_events) | |
462 | +void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) | |
463 | 463 | { |
464 | 464 | int cpu; |
465 | 465 | struct perf_event **pevent; |
samples/hw_breakpoint/data_breakpoint.c
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | #include <linux/perf_event.h> |
35 | 35 | #include <linux/hw_breakpoint.h> |
36 | 36 | |
37 | -struct perf_event **sample_hbp; | |
37 | +struct perf_event * __percpu *sample_hbp; | |
38 | 38 | |
39 | 39 | static char ksym_name[KSYM_NAME_LEN] = "pid_max"; |
40 | 40 | module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO); |
... | ... | @@ -61,8 +61,8 @@ |
61 | 61 | attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; |
62 | 62 | |
63 | 63 | sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler); |
64 | - if (IS_ERR(sample_hbp)) { | |
65 | - ret = PTR_ERR(sample_hbp); | |
64 | + if (IS_ERR((void __force *)sample_hbp)) { | |
65 | + ret = PTR_ERR((void __force *)sample_hbp); | |
66 | 66 | goto fail; |
67 | 67 | } |
68 | 68 |