]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
kprobes: Cleanup collect_one_slot() and __disable_kprobe()
authorJinjie Ruan <ruanjinjie@huawei.com>
Tue, 13 Aug 2024 11:53:34 +0000 (19:53 +0800)
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>
Thu, 31 Oct 2024 01:59:42 +0000 (10:59 +0900)
If kip->nused is not zero, collect_one_slot() return false, otherwise do
a lot of linked list operations, reverse the processing order to make the
code if nesting more concise. __disable_kprobe() is the same as well.

Link: https://lore.kernel.org/all/20240813115334.3922580-4-ruanjinjie@huawei.com/
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
kernel/kprobes.c

index 5f4117b1ff70937d2aa199652a3670498cf04a42..5381c6571fa24831931f017fcb261721c97df886 100644 (file)
@@ -206,29 +206,29 @@ static bool collect_one_slot(struct kprobe_insn_page *kip, int idx)
 {
        kip->slot_used[idx] = SLOT_CLEAN;
        kip->nused--;
-       if (kip->nused == 0) {
+       if (kip->nused != 0)
+               return false;
+
+       /*
+        * Page is no longer in use.  Free it unless
+        * it's the last one.  We keep the last one
+        * so as not to have to set it up again the
+        * next time somebody inserts a probe.
+        */
+       if (!list_is_singular(&kip->list)) {
                /*
-                * Page is no longer in use.  Free it unless
-                * it's the last one.  We keep the last one
-                * so as not to have to set it up again the
-                * next time somebody inserts a probe.
+                * Record perf ksymbol unregister event before removing
+                * the page.
                 */
-               if (!list_is_singular(&kip->list)) {
-                       /*
-                        * Record perf ksymbol unregister event before removing
-                        * the page.
-                        */
-                       perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL,
-                                          (unsigned long)kip->insns, PAGE_SIZE, true,
-                                          kip->cache->sym);
-                       list_del_rcu(&kip->list);
-                       synchronize_rcu();
-                       kip->cache->free(kip->insns);
-                       kfree(kip);
-               }
-               return true;
+               perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL,
+                                  (unsigned long)kip->insns, PAGE_SIZE, true,
+                                  kip->cache->sym);
+               list_del_rcu(&kip->list);
+               synchronize_rcu();
+               kip->cache->free(kip->insns);
+               kfree(kip);
        }
-       return false;
+       return true;
 }
 
 static int collect_garbage_slots(struct kprobe_insn_cache *c)
@@ -1725,28 +1725,29 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
        if (unlikely(orig_p == NULL))
                return ERR_PTR(-EINVAL);
 
-       if (!kprobe_disabled(p)) {
-               /* Disable probe if it is a child probe */
-               if (p != orig_p)
-                       p->flags |= KPROBE_FLAG_DISABLED;
+       if (kprobe_disabled(p))
+               return orig_p;
 
-               /* Try to disarm and disable this/parent probe */
-               if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
-                       /*
-                        * Don't be lazy here.  Even if 'kprobes_all_disarmed'
-                        * is false, 'orig_p' might not have been armed yet.
-                        * Note arm_all_kprobes() __tries__ to arm all kprobes
-                        * on the best effort basis.
-                        */
-                       if (!kprobes_all_disarmed && !kprobe_disabled(orig_p)) {
-                               ret = disarm_kprobe(orig_p, true);
-                               if (ret) {
-                                       p->flags &= ~KPROBE_FLAG_DISABLED;
-                                       return ERR_PTR(ret);
-                               }
+       /* Disable probe if it is a child probe */
+       if (p != orig_p)
+               p->flags |= KPROBE_FLAG_DISABLED;
+
+       /* Try to disarm and disable this/parent probe */
+       if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
+               /*
+                * Don't be lazy here.  Even if 'kprobes_all_disarmed'
+                * is false, 'orig_p' might not have been armed yet.
+                * Note arm_all_kprobes() __tries__ to arm all kprobes
+                * on the best effort basis.
+                */
+               if (!kprobes_all_disarmed && !kprobe_disabled(orig_p)) {
+                       ret = disarm_kprobe(orig_p, true);
+                       if (ret) {
+                               p->flags &= ~KPROBE_FLAG_DISABLED;
+                               return ERR_PTR(ret);
                        }
-                       orig_p->flags |= KPROBE_FLAG_DISABLED;
                }
+               orig_p->flags |= KPROBE_FLAG_DISABLED;
        }
 
        return orig_p;