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);
+ }
}
/*
} 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);
}
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);
}