Skip to content

Commit

Permalink
uprobes: _unregister() should always do register_for_each_vma(false)
Browse files Browse the repository at this point in the history
uprobe_unregister() removes the breakpoints only if the last consumer
goes away. To support the filtering it should do this every time, we
want to remove the breakpoints which nobody else want to keep.

Note: given that filter_chain() is not actually implemented, this patch
itself doesn't change the behaviour yet, register_for_each_vma(false)
is a heavy "nop" unless there are no more consumers.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
  • Loading branch information
Oleg Nesterov committed Feb 8, 2013
1 parent 63633cb commit 04aab9b
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions kernel/events/uprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,12 +825,20 @@ static int __uprobe_register(struct uprobe *uprobe)
return register_for_each_vma(uprobe, true);
}

static void __uprobe_unregister(struct uprobe *uprobe)
static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
{
if (!register_for_each_vma(uprobe, false))
delete_uprobe(uprobe);
int err;

if (!consumer_del(uprobe, uc)) /* WARN? */
return;

/* TODO : cant unregister? schedule a worker thread */
err = register_for_each_vma(uprobe, false);
if (!uprobe->consumers) {
clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
/* TODO : cant unregister? schedule a worker thread */
if (!err)
delete_uprobe(uprobe);
}
}

/*
Expand Down Expand Up @@ -868,8 +876,7 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
} else if (!consumer_add(uprobe, uc)) {
ret = __uprobe_register(uprobe);
if (ret) {
uprobe->consumers = NULL;
__uprobe_unregister(uprobe);
__uprobe_unregister(uprobe, uc);
} else {
set_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
}
Expand Down Expand Up @@ -897,14 +904,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
return;

mutex_lock(uprobes_hash(inode));

if (consumer_del(uprobe, uc)) {
if (!uprobe->consumers) {
__uprobe_unregister(uprobe);
clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
}
}

__uprobe_unregister(uprobe, uc);
mutex_unlock(uprobes_hash(inode));
put_uprobe(uprobe);
}
Expand Down

0 comments on commit 04aab9b

Please sign in to comment.