diff options
author | Ananth N Mavinakayanahalli <ananth@in.ibm.com> | 2005-11-07 04:00:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:46 -0500 |
commit | d217d5450f11d8c907c0458d175b0dc999b4d06d (patch) | |
tree | ebd68eb9e0b632049d22240a3589887ca27077a5 /arch/ia64 | |
parent | 991a51d83a3d9bebfafdd1e692cf310899d60791 (diff) |
[PATCH] Kprobes: preempt_disable/enable() simplification
Reorganize the preempt_disable/enable calls to eliminate the extra preempt
depth. Changes based on Paul McKenney's review suggestions for the kprobes
RCU changeset.
Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
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>
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index fddbac32d44a..96736a119c91 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -389,11 +389,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
389 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 389 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
390 | preempt_enable_no_resched(); | 390 | preempt_enable_no_resched(); |
391 | 391 | ||
392 | /* | 392 | /* |
393 | * By returning a non-zero value, we are telling | 393 | * By returning a non-zero value, we are telling |
394 | * kprobe_handler() that we have handled unlocking | 394 | * kprobe_handler() that we don't want the post_handler |
395 | * and re-enabling preemption | 395 | * to run (and have re-enabled preemption) |
396 | */ | 396 | */ |
397 | return 1; | 397 | return 1; |
398 | } | 398 | } |
399 | 399 | ||
@@ -604,7 +604,14 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
604 | int ret = 0; | 604 | int ret = 0; |
605 | struct pt_regs *regs = args->regs; | 605 | struct pt_regs *regs = args->regs; |
606 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); | 606 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); |
607 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 607 | struct kprobe_ctlblk *kcb; |
608 | |||
609 | /* | ||
610 | * We don't want to be preempted for the entire | ||
611 | * duration of kprobe processing | ||
612 | */ | ||
613 | preempt_disable(); | ||
614 | kcb = get_kprobe_ctlblk(); | ||
608 | 615 | ||
609 | /* Handle recursion cases */ | 616 | /* Handle recursion cases */ |
610 | if (kprobe_running()) { | 617 | if (kprobe_running()) { |
@@ -659,11 +666,6 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
659 | goto no_kprobe; | 666 | goto no_kprobe; |
660 | } | 667 | } |
661 | 668 | ||
662 | /* | ||
663 | * This preempt_disable() matches the preempt_enable_no_resched() | ||
664 | * in post_kprobes_handler() | ||
665 | */ | ||
666 | preempt_disable(); | ||
667 | set_current_kprobe(p, kcb); | 669 | set_current_kprobe(p, kcb); |
668 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | 670 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
669 | 671 | ||
@@ -681,6 +683,7 @@ ss_probe: | |||
681 | return 1; | 683 | return 1; |
682 | 684 | ||
683 | no_kprobe: | 685 | no_kprobe: |
686 | preempt_enable_no_resched(); | ||
684 | return ret; | 687 | return ret; |
685 | } | 688 | } |
686 | 689 | ||
@@ -716,9 +719,6 @@ static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) | |||
716 | struct kprobe *cur = kprobe_running(); | 719 | struct kprobe *cur = kprobe_running(); |
717 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 720 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
718 | 721 | ||
719 | if (!cur) | ||
720 | return 0; | ||
721 | |||
722 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | 722 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) |
723 | return 1; | 723 | return 1; |
724 | 724 | ||
@@ -737,7 +737,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
737 | struct die_args *args = (struct die_args *)data; | 737 | struct die_args *args = (struct die_args *)data; |
738 | int ret = NOTIFY_DONE; | 738 | int ret = NOTIFY_DONE; |
739 | 739 | ||
740 | rcu_read_lock(); | ||
741 | switch(val) { | 740 | switch(val) { |
742 | case DIE_BREAK: | 741 | case DIE_BREAK: |
743 | if (pre_kprobes_handler(args)) | 742 | if (pre_kprobes_handler(args)) |
@@ -748,12 +747,15 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
748 | ret = NOTIFY_STOP; | 747 | ret = NOTIFY_STOP; |
749 | break; | 748 | break; |
750 | case DIE_PAGE_FAULT: | 749 | case DIE_PAGE_FAULT: |
751 | if (kprobes_fault_handler(args->regs, args->trapnr)) | 750 | /* kprobe_running() needs smp_processor_id() */ |
751 | preempt_disable(); | ||
752 | if (kprobe_running() && | ||
753 | kprobes_fault_handler(args->regs, args->trapnr)) | ||
752 | ret = NOTIFY_STOP; | 754 | ret = NOTIFY_STOP; |
755 | preempt_enable(); | ||
753 | default: | 756 | default: |
754 | break; | 757 | break; |
755 | } | 758 | } |
756 | rcu_read_unlock(); | ||
757 | return ret; | 759 | return ret; |
758 | } | 760 | } |
759 | 761 | ||
@@ -785,6 +787,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
785 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 787 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
786 | 788 | ||
787 | *regs = kcb->jprobe_saved_regs; | 789 | *regs = kcb->jprobe_saved_regs; |
790 | preempt_enable_no_resched(); | ||
788 | return 1; | 791 | return 1; |
789 | } | 792 | } |
790 | 793 | ||