libbpf-tools: Fix renaming of the state field of task_struct
authorHengqi Chen <chenhengqi@outlook.com>
Thu, 14 Oct 2021 13:40:45 +0000 (21:40 +0800)
committeryonghong-song <ys114321@gmail.com>
Sat, 16 Oct 2021 00:28:13 +0000 (17:28 -0700)
Kernel commit 2f064a59a1 ("sched: Change task_struct::state") changes
the name of task_struct::state to task_struct::__state, which breaks
several libbpf tools. Fix them by utilizing the libbpf CO-RE support.

Signed-off-by: Hengqi Chen <chenhengqi@outlook.com>
libbpf-tools/core_fixes.bpf.h [new file with mode: 0644]
libbpf-tools/cpudist.bpf.c
libbpf-tools/offcputime.bpf.c
libbpf-tools/runqlat.bpf.c
libbpf-tools/runqslower.bpf.c

diff --git a/libbpf-tools/core_fixes.bpf.h b/libbpf-tools/core_fixes.bpf.h
new file mode 100644 (file)
index 0000000..762445e
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+/* Copyright (c) 2021 Hengqi Chen */
+
+#ifndef __CORE_FIXES_BPF_H
+#define __CORE_FIXES_BPF_H
+
+#include <vmlinux.h>
+#include <bpf/bpf_core_read.h>
+
+/**
+ * commit 2f064a59a1 ("sched: Change task_struct::state") changes
+ * the name of task_struct::state to task_struct::__state
+ * see:
+ *     https://github.com/torvalds/linux/commit/2f064a59a1
+ */
+struct task_struct___x {
+       unsigned int __state;
+};
+
+static __s64 get_task_state(void *task)
+{
+       struct task_struct___x *t = task;
+
+       if (bpf_core_field_exists(t->__state))
+               return t->__state;
+       return ((struct task_struct *)task)->state;
+}
+
+#endif /* __CORE_FIXES_BPF_H */
index bee2af9eb19882dc2d18a1f2d8de1a926569f264..7c3f8ce0f622e23a715bc2bdf13d2136d7388aa8 100644 (file)
@@ -6,6 +6,7 @@
 #include <bpf/bpf_tracing.h>
 #include "cpudist.h"
 #include "bits.bpf.h"
+#include "core_fixes.bpf.h"
 
 #define TASK_RUNNING   0
 
@@ -88,7 +89,7 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev,
                store_start(prev_tgid, prev_pid, ts);
                update_hist(next, tgid, pid, ts);
        } else {
-               if (prev->state == TASK_RUNNING)
+               if (get_task_state(prev) == TASK_RUNNING)
                        update_hist(prev, prev_tgid, prev_pid, ts);
                store_start(tgid, pid, ts);
        }
index 3b0277a0e6d4a047493bcddcc334f667139afcfc..92f505ab19a58998f14d8b28a4de91609c4a6462 100644 (file)
@@ -5,6 +5,7 @@
 #include <bpf/bpf_core_read.h>
 #include <bpf/bpf_tracing.h>
 #include "offcputime.h"
+#include "core_fixes.bpf.h"
 
 #define PF_KTHREAD             0x00200000      /* I am a kernel thread */
 #define MAX_ENTRIES            10240
@@ -51,7 +52,7 @@ static bool allow_record(struct task_struct *t)
                return false;
        else if (kernel_threads_only && !(t->flags & PF_KTHREAD))
                return false;
-       if (state != -1 && t->state != state)
+       if (state != -1 && get_task_state(t) != state)
                return false;
        return true;
 }
index 911a55066a8160a3fe3fc3240bba3882eeb878f6..85e6619770b70235052c41bacfe17e83fb743129 100644 (file)
@@ -7,6 +7,7 @@
 #include "runqlat.h"
 #include "bits.bpf.h"
 #include "maps.bpf.h"
+#include "core_fixes.bpf.h"
 
 #define MAX_ENTRIES    10240
 #define TASK_RUNNING   0
@@ -69,7 +70,7 @@ int BPF_PROG(sched_swith, bool preempt, struct task_struct *prev,
        u32 pid, hkey;
        s64 delta;
 
-       if (prev->state == TASK_RUNNING)
+       if (get_task_state(prev) == TASK_RUNNING)
                trace_enqueue(prev->tgid, prev->pid);
 
        pid = next->pid;
index 84e7aea6234a48d30e628cdea31dba74daea6fd9..277dbc16eb484e04820ce222579de5dfb730badf 100644 (file)
@@ -3,6 +3,7 @@
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 #include "runqslower.h"
+#include "core_fixes.bpf.h"
 
 #define TASK_RUNNING   0
 
@@ -69,11 +70,10 @@ int handle__sched_switch(u64 *ctx)
        struct task_struct *next = (struct task_struct *)ctx[2];
        struct event event = {};
        u64 *tsp, delta_us;
-       long state;
        u32 pid;
 
        /* ivcsw: treat like an enqueue event and store timestamp */
-       if (prev->state == TASK_RUNNING)
+       if (get_task_state(prev) == TASK_RUNNING)
                trace_enqueue(prev->tgid, prev->pid);
 
        pid = next->pid;