Commit bf8d5c52c3b6b27061e3b7d779057fd9a6cac164
Committed by
Linus Torvalds
1 parent
00d7c05ab1
Exists in
master
and in
7 other branches
[PATCH] kprobes: increment kprobe missed count for multiprobes
When multiple probes are registered at the same address and if due to some recursion (probe getting triggered within a probe handler), we skip calling pre_handlers and just increment nmissed field. The below patch make sure it walks the list for multiple probes case. Without the below patch we get incorrect results of nmissed count for multiple probe case. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 7 changed files with 19 additions and 5 deletions Side-by-side Diff
arch/i386/kernel/kprobes.c
arch/ia64/kernel/kprobes.c
arch/powerpc/kernel/kprobes.c
... | ... | @@ -177,7 +177,7 @@ |
177 | 177 | save_previous_kprobe(kcb); |
178 | 178 | set_current_kprobe(p, regs, kcb); |
179 | 179 | kcb->kprobe_saved_msr = regs->msr; |
180 | - p->nmissed++; | |
180 | + kprobes_inc_nmissed_count(p); | |
181 | 181 | prepare_singlestep(p, regs); |
182 | 182 | kcb->kprobe_status = KPROBE_REENTER; |
183 | 183 | return 1; |
arch/sparc64/kernel/kprobes.c
arch/x86_64/kernel/kprobes.c
include/linux/kprobes.h
... | ... | @@ -158,6 +158,7 @@ |
158 | 158 | extern void show_registers(struct pt_regs *regs); |
159 | 159 | extern kprobe_opcode_t *get_insn_slot(void); |
160 | 160 | extern void free_insn_slot(kprobe_opcode_t *slot); |
161 | +extern void kprobes_inc_nmissed_count(struct kprobe *p); | |
161 | 162 | |
162 | 163 | /* Get the kprobe at this addr (if any) - called with preemption disabled */ |
163 | 164 | struct kprobe *get_kprobe(void *addr); |
kernel/kprobes.c
... | ... | @@ -246,6 +246,19 @@ |
246 | 246 | return ret; |
247 | 247 | } |
248 | 248 | |
249 | +/* Walks the list and increments nmissed count for multiprobe case */ | |
250 | +void __kprobes kprobes_inc_nmissed_count(struct kprobe *p) | |
251 | +{ | |
252 | + struct kprobe *kp; | |
253 | + if (p->pre_handler != aggr_pre_handler) { | |
254 | + p->nmissed++; | |
255 | + } else { | |
256 | + list_for_each_entry_rcu(kp, &p->list, list) | |
257 | + kp->nmissed++; | |
258 | + } | |
259 | + return; | |
260 | +} | |
261 | + | |
249 | 262 | /* Called with kretprobe_lock held */ |
250 | 263 | struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp) |
251 | 264 | { |