|
@@ -700,9 +700,10 @@ static void unoptimize_kprobe(struct kprobe *p, bool force)
|
|
|
}
|
|
|
|
|
|
/* Cancel unoptimizing for reusing */
|
|
|
-static void reuse_unused_kprobe(struct kprobe *ap)
|
|
|
+static int reuse_unused_kprobe(struct kprobe *ap)
|
|
|
{
|
|
|
struct optimized_kprobe *op;
|
|
|
+ int ret;
|
|
|
|
|
|
/*
|
|
|
* Unused kprobe MUST be on the way of delayed unoptimizing (means
|
|
@@ -713,8 +714,12 @@ static void reuse_unused_kprobe(struct kprobe *ap)
|
|
|
/* Enable the probe again */
|
|
|
ap->flags &= ~KPROBE_FLAG_DISABLED;
|
|
|
/* Optimize it again (remove from op->list) */
|
|
|
- BUG_ON(!kprobe_optready(ap));
|
|
|
+ ret = kprobe_optready(ap);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
optimize_kprobe(ap);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/* Remove optimized instructions */
|
|
@@ -939,11 +944,16 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt)
|
|
|
#define kprobe_disarmed(p) kprobe_disabled(p)
|
|
|
#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)
|
|
|
+static int reuse_unused_kprobe(struct kprobe *ap)
|
|
|
{
|
|
|
+ /*
|
|
|
+ * If the optimized kprobe is NOT supported, the aggr kprobe is
|
|
|
+ * released at the same time that the last aggregated kprobe is
|
|
|
+ * unregistered.
|
|
|
+ * Thus there should be no chance to reuse unused kprobe.
|
|
|
+ */
|
|
|
printk(KERN_ERR "Error: There should be no unused kprobe here.\n");
|
|
|
- BUG_ON(kprobe_unused(ap));
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
static void free_aggr_kprobe(struct kprobe *p)
|
|
@@ -1315,9 +1325,12 @@ static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
|
|
|
goto out;
|
|
|
}
|
|
|
init_aggr_kprobe(ap, orig_p);
|
|
|
- } else if (kprobe_unused(ap))
|
|
|
+ } else if (kprobe_unused(ap)) {
|
|
|
/* This probe is going to die. Rescue it */
|
|
|
- reuse_unused_kprobe(ap);
|
|
|
+ ret = reuse_unused_kprobe(ap);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
if (kprobe_gone(ap)) {
|
|
|
/*
|