aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events/uprobes.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-11-24 12:27:08 -0500
committerOleg Nesterov <oleg@redhat.com>2013-02-08 11:47:06 -0500
commitbb929284be40cbbdb347690742557d708fd504a9 (patch)
tree6f86aba2f415508fdccb88804bc03bdae3a0e160 /kernel/events/uprobes.c
parent1ff6fee5e62c57d5923b805bb4206acb7953f16e (diff)
uprobes: Kill UPROBE_RUN_HANDLER flag
Simply remove UPROBE_RUN_HANDLER and the corresponding code. It can only help if uprobe has a single consumer, and in fact it is no longer needed after handler_chain() was changed to use ->register_rwsem, we simply can not race with uprobe_register(). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/events/uprobes.c')
-rw-r--r--kernel/events/uprobes.c23
1 files changed, 5 insertions, 18 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4d0452363686..7ec2eb278634 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -83,10 +83,8 @@ static atomic_t uprobe_events = ATOMIC_INIT(0);
83 83
84/* Have a copy of original instruction */ 84/* Have a copy of original instruction */
85#define UPROBE_COPY_INSN 0 85#define UPROBE_COPY_INSN 0
86/* Dont run handlers when first register/ last unregister in progress*/
87#define UPROBE_RUN_HANDLER 1
88/* Can skip singlestep */ 86/* Can skip singlestep */
89#define UPROBE_SKIP_SSTEP 2 87#define UPROBE_SKIP_SSTEP 1
90 88
91struct uprobe { 89struct uprobe {
92 struct rb_node rb_node; /* node in the rb tree */ 90 struct rb_node rb_node; /* node in the rb tree */
@@ -475,9 +473,6 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
475{ 473{
476 struct uprobe_consumer *uc; 474 struct uprobe_consumer *uc;
477 475
478 if (!test_bit(UPROBE_RUN_HANDLER, &uprobe->flags))
479 return;
480
481 down_read(&uprobe->register_rwsem); 476 down_read(&uprobe->register_rwsem);
482 for (uc = uprobe->consumers; uc; uc = uc->next) 477 for (uc = uprobe->consumers; uc; uc = uc->next)
483 uc->handler(uc, regs); 478 uc->handler(uc, regs);
@@ -825,13 +820,8 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
825 820
826static int __uprobe_register(struct uprobe *uprobe, struct uprobe_consumer *uc) 821static int __uprobe_register(struct uprobe *uprobe, struct uprobe_consumer *uc)
827{ 822{
828 int err;
829
830 consumer_add(uprobe, uc); 823 consumer_add(uprobe, uc);
831 err = register_for_each_vma(uprobe, true); 824 return register_for_each_vma(uprobe, true);
832 if (!err) /* TODO: pointless unless the first consumer */
833 set_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
834 return err;
835} 825}
836 826
837static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc) 827static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
@@ -842,12 +832,9 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
842 return; 832 return;
843 833
844 err = register_for_each_vma(uprobe, false); 834 err = register_for_each_vma(uprobe, false);
845 if (!uprobe->consumers) { 835 /* TODO : cant unregister? schedule a worker thread */
846 clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags); 836 if (!uprobe->consumers && !err)
847 /* TODO : cant unregister? schedule a worker thread */ 837 delete_uprobe(uprobe);
848 if (!err)
849 delete_uprobe(uprobe);
850 }
851} 838}
852 839
853/* 840/*