kprobes: Reuse unused kprobe
Reuse unused (waiting for unoptimizing and no user handler) kprobe on given address instead of returning -EBUSY for registering a new kprobe. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Jason Baron <jbaron@redhat.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: 2nddept-manager@sdl.hitachi.co.jp LKML-Reference: <20101203095416.2961.39080.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
6274de4984
commit
0490cd1f9d
1 changed files with 30 additions and 2 deletions
|
@ -692,6 +692,27 @@ static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cancel unoptimizing for reusing */
|
||||||
|
static void reuse_unused_kprobe(struct kprobe *ap)
|
||||||
|
{
|
||||||
|
struct optimized_kprobe *op;
|
||||||
|
|
||||||
|
BUG_ON(!kprobe_unused(ap));
|
||||||
|
/*
|
||||||
|
* Unused kprobe MUST be on the way of delayed unoptimizing (means
|
||||||
|
* there is still a relative jump) and disabled.
|
||||||
|
*/
|
||||||
|
op = container_of(ap, struct optimized_kprobe, kp);
|
||||||
|
if (unlikely(list_empty(&op->list)))
|
||||||
|
printk(KERN_WARNING "Warning: found a stray unused "
|
||||||
|
"aggrprobe@%p\n", ap->addr);
|
||||||
|
/* Enable the probe again */
|
||||||
|
ap->flags &= ~KPROBE_FLAG_DISABLED;
|
||||||
|
/* Optimize it again (remove from op->list) */
|
||||||
|
BUG_ON(!kprobe_optready(ap));
|
||||||
|
optimize_kprobe(ap);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove optimized instructions */
|
/* Remove optimized instructions */
|
||||||
static void __kprobes kill_optimized_kprobe(struct kprobe *p)
|
static void __kprobes kill_optimized_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
|
@ -872,6 +893,13 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, bool reopt)
|
||||||
#define kprobe_disarmed(p) kprobe_disabled(p)
|
#define kprobe_disarmed(p) kprobe_disabled(p)
|
||||||
#define wait_for_kprobe_optimizer() do {} while (0)
|
#define wait_for_kprobe_optimizer() do {} while (0)
|
||||||
|
|
||||||
|
/* There should be no unused kprobes can be reused without optimization */
|
||||||
|
static void reuse_unused_kprobe(struct kprobe *ap)
|
||||||
|
{
|
||||||
|
printk(KERN_ERR "Error: There should be no unused kprobe here.\n");
|
||||||
|
BUG_ON(kprobe_unused(ap));
|
||||||
|
}
|
||||||
|
|
||||||
static __kprobes void free_aggr_kprobe(struct kprobe *p)
|
static __kprobes void free_aggr_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
arch_remove_kprobe(p);
|
arch_remove_kprobe(p);
|
||||||
|
@ -1173,8 +1201,8 @@ static int __kprobes register_aggr_kprobe(struct kprobe *orig_p,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
init_aggr_kprobe(ap, orig_p);
|
init_aggr_kprobe(ap, orig_p);
|
||||||
} else if (kprobe_unused(ap))
|
} else if (kprobe_unused(ap))
|
||||||
/* Busy to die */
|
/* This probe is going to die. Rescue it */
|
||||||
return -EBUSY;
|
reuse_unused_kprobe(ap);
|
||||||
|
|
||||||
if (kprobe_gone(ap)) {
|
if (kprobe_gone(ap)) {
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue