aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
authormao, bibo <bibo.mao@intel.com>2006-06-26 03:25:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:22 -0400
commit36721656776f177280ccb50477a02e86e6444292 (patch)
tree20cb06eb08e98636e97703d6e0df77790ede23cf /kernel/kprobes.c
parent585deacaca3e7bfc63580623f0344d1fa9c47f11 (diff)
[PATCH] Kprobe: multi kprobe posthandler for booster
If there are multi kprobes on the same probepoint, there will be one extra aggr_kprobe on the head of kprobe list. The aggr_kprobe has aggr_post_handler/aggr_break_handler whether the other kprobe post_hander/break_handler is NULL or not. This patch modifies this, only when there is one or more kprobe in the list whose post_handler is not NULL, post_handler of aggr_kprobe will be set as aggr_post_handler. [soshima@redhat.com: !CONFIG_PREEMPT fix] Signed-off-by: bibo, mao <bibo.mao@intel.com> Cc: Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: "Keshavamurthy, Anil S" <anil.s.keshavamurthy@intel.com> Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Yumiko Sugita <sugita@sdl.hitachi.co.jp> Cc: Hideo Aoki <haoki@redhat.com> Signed-off-by: Satoshi Oshima <soshima@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 1fbf466a29a..f095178e48c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -368,16 +368,15 @@ static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
368*/ 368*/
369static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p) 369static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
370{ 370{
371 struct kprobe *kp;
372
373 if (p->break_handler) { 371 if (p->break_handler) {
374 list_for_each_entry_rcu(kp, &old_p->list, list) { 372 if (old_p->break_handler)
375 if (kp->break_handler) 373 return -EEXIST;
376 return -EEXIST;
377 }
378 list_add_tail_rcu(&p->list, &old_p->list); 374 list_add_tail_rcu(&p->list, &old_p->list);
375 old_p->break_handler = aggr_break_handler;
379 } else 376 } else
380 list_add_rcu(&p->list, &old_p->list); 377 list_add_rcu(&p->list, &old_p->list);
378 if (p->post_handler && !old_p->post_handler)
379 old_p->post_handler = aggr_post_handler;
381 return 0; 380 return 0;
382} 381}
383 382
@@ -390,9 +389,11 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
390 copy_kprobe(p, ap); 389 copy_kprobe(p, ap);
391 ap->addr = p->addr; 390 ap->addr = p->addr;
392 ap->pre_handler = aggr_pre_handler; 391 ap->pre_handler = aggr_pre_handler;
393 ap->post_handler = aggr_post_handler;
394 ap->fault_handler = aggr_fault_handler; 392 ap->fault_handler = aggr_fault_handler;
395 ap->break_handler = aggr_break_handler; 393 if (p->post_handler)
394 ap->post_handler = aggr_post_handler;
395 if (p->break_handler)
396 ap->break_handler = aggr_break_handler;
396 397
397 INIT_LIST_HEAD(&ap->list); 398 INIT_LIST_HEAD(&ap->list);
398 list_add_rcu(&p->list, &ap->list); 399 list_add_rcu(&p->list, &ap->list);
@@ -536,6 +537,21 @@ valid_p:
536 kfree(old_p); 537 kfree(old_p);
537 } 538 }
538 arch_remove_kprobe(p); 539 arch_remove_kprobe(p);
540 } else {
541 mutex_lock(&kprobe_mutex);
542 if (p->break_handler)
543 old_p->break_handler = NULL;
544 if (p->post_handler){
545 list_for_each_entry_rcu(list_p, &old_p->list, list){
546 if (list_p->post_handler){
547 cleanup_p = 2;
548 break;
549 }
550 }
551 if (cleanup_p == 0)
552 old_p->post_handler = NULL;
553 }
554 mutex_unlock(&kprobe_mutex);
539 } 555 }
540} 556}
541 557