From: Masami Hiramatsu (Google) <mhira...@kernel.org>

Move the BTF APIs used in tracing to the BTF library code for sharing it
with others.
Previously, to avoid complex dependency in a series I made it on the
tracing tree, but now it is a good time to move it to BPF tree because
these functions are pure BTF functions.

Signed-off-by: Masami Hiramatsu (Google) <mhira...@kernel.org>
---
 include/linux/btf.h        |   24 +++++++++
 kernel/bpf/btf.c           |  115 +++++++++++++++++++++++++++++++++++++++++
 kernel/trace/Makefile      |    1 
 kernel/trace/trace_btf.c   |  122 --------------------------------------------
 kernel/trace/trace_btf.h   |   11 ----
 kernel/trace/trace_probe.c |    2 -
 6 files changed, 140 insertions(+), 135 deletions(-)
 delete mode 100644 kernel/trace/trace_btf.c
 delete mode 100644 kernel/trace/trace_btf.h

diff --git a/include/linux/btf.h b/include/linux/btf.h
index 928113a80a95..8372d93ea402 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -507,6 +507,14 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, const 
struct btf *btf,
 int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type 
prog_type);
 bool btf_types_are_same(const struct btf *btf1, u32 id1,
                        const struct btf *btf2, u32 id2);
+const struct btf_type *btf_find_func_proto(const char *func_name,
+                                          struct btf **btf_p);
+const struct btf_param *btf_get_func_param(const struct btf_type *func_proto,
+                                          s32 *nr);
+const struct btf_member *btf_find_struct_member(struct btf *btf,
+                                               const struct btf_type *type,
+                                               const char *member_name,
+                                               u32 *anon_offset);
 #else
 static inline const struct btf_type *btf_type_by_id(const struct btf *btf,
                                                    u32 type_id)
@@ -559,6 +567,22 @@ static inline bool btf_types_are_same(const struct btf 
*btf1, u32 id1,
 {
        return false;
 }
+static inline const struct btf_type *btf_find_func_proto(const char *func_name,
+                                                        struct btf **btf_p)
+{
+       return NULL;
+}
+static inline const struct btf_param *
+btf_get_func_param(const struct btf_type *func_proto, s32 *nr)
+{
+       return NULL;
+}
+static inline const struct btf_member *
+btf_find_struct_member(struct btf *btf, const struct btf_type *type,
+                      const char *member_name, u32 *anon_offset)
+{
+       return NULL;
+}
 #endif
 
 static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct 
btf_type *t)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 8090d7fb11ef..e5cbf3b31b78 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -912,6 +912,121 @@ static const struct btf_type 
*btf_type_skip_qualifiers(const struct btf *btf,
        return t;
 }
 
+/*
+ * Find a function proto type by name, and return the btf_type with its btf
+ * in *@btf_p. Return NULL if not found.
+ * Note that caller has to call btf_put(*@btf_p) after using the btf_type.
+ */
+const struct btf_type *btf_find_func_proto(const char *func_name, struct btf 
**btf_p)
+{
+       const struct btf_type *t;
+       s32 id;
+
+       id = bpf_find_btf_id(func_name, BTF_KIND_FUNC, btf_p);
+       if (id < 0)
+               return NULL;
+
+       /* Get BTF_KIND_FUNC type */
+       t = btf_type_by_id(*btf_p, id);
+       if (!t || !btf_type_is_func(t))
+               goto err;
+
+       /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */
+       t = btf_type_by_id(*btf_p, t->type);
+       if (!t || !btf_type_is_func_proto(t))
+               goto err;
+
+       return t;
+err:
+       btf_put(*btf_p);
+       return NULL;
+}
+
+/*
+ * Get function parameter with the number of parameters.
+ * This can return NULL if the function has no parameters.
+ * It can return -EINVAL if the @func_proto is not a function proto type.
+ */
+const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, 
s32 *nr)
+{
+       if (!btf_type_is_func_proto(func_proto))
+               return ERR_PTR(-EINVAL);
+
+       *nr = btf_type_vlen(func_proto);
+       if (*nr > 0)
+               return (const struct btf_param *)(func_proto + 1);
+       else
+               return NULL;
+}
+
+#define BTF_ANON_STACK_MAX     16
+
+struct btf_anon_stack {
+       u32 tid;
+       u32 offset;
+};
+
+/*
+ * Find a member of data structure/union by name and return it.
+ * Return NULL if not found, or -EINVAL if parameter is invalid.
+ * If the member is an member of anonymous union/structure, the offset
+ * of that anonymous union/structure is stored into @anon_offset. Caller
+ * can calculate the correct offset from the root data structure by
+ * adding anon_offset to the member's offset.
+ */
+const struct btf_member *btf_find_struct_member(struct btf *btf,
+                                               const struct btf_type *type,
+                                               const char *member_name,
+                                               u32 *anon_offset)
+{
+       struct btf_anon_stack *anon_stack;
+       const struct btf_member *member;
+       u32 tid, cur_offset = 0;
+       const char *name;
+       int i, top = 0;
+
+       anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), 
GFP_KERNEL);
+       if (!anon_stack)
+               return ERR_PTR(-ENOMEM);
+
+retry:
+       if (!btf_type_is_struct(type)) {
+               member = ERR_PTR(-EINVAL);
+               goto out;
+       }
+
+       for_each_member(i, type, member) {
+               if (!member->name_off) {
+                       /* Anonymous union/struct: push it for later use */
+                       type = btf_type_skip_modifiers(btf, member->type, &tid);
+                       if (type && top < BTF_ANON_STACK_MAX) {
+                               anon_stack[top].tid = tid;
+                               anon_stack[top++].offset =
+                                       cur_offset + member->offset;
+                       }
+               } else {
+                       name = btf_name_by_offset(btf, member->name_off);
+                       if (name && !strcmp(member_name, name)) {
+                               if (anon_offset)
+                                       *anon_offset = cur_offset;
+                               goto out;
+                       }
+               }
+       }
+       if (top > 0) {
+               /* Pop from the anonymous stack and retry */
+               tid = anon_stack[--top].tid;
+               cur_offset = anon_stack[top].offset;
+               type = btf_type_by_id(btf, tid);
+               goto retry;
+       }
+       member = NULL;
+
+out:
+       kfree(anon_stack);
+       return member;
+}
+
 #define BTF_SHOW_MAX_ITER      10
 
 #define BTF_KIND_BIT(kind)     (1ULL << kind)
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 057cd975d014..64b61f67a403 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -99,7 +99,6 @@ obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
 endif
 obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o
 obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
-obj-$(CONFIG_PROBE_EVENTS_BTF_ARGS) += trace_btf.o
 obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o
 obj-$(CONFIG_BOOTTIME_TRACING) += trace_boot.o
 obj-$(CONFIG_FTRACE_RECORD_RECURSION) += trace_recursion_record.o
diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c
deleted file mode 100644
index ca224d53bfdc..000000000000
--- a/kernel/trace/trace_btf.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/btf.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "trace_btf.h"
-
-/*
- * Find a function proto type by name, and return the btf_type with its btf
- * in *@btf_p. Return NULL if not found.
- * Note that caller has to call btf_put(*@btf_p) after using the btf_type.
- */
-const struct btf_type *btf_find_func_proto(const char *func_name, struct btf 
**btf_p)
-{
-       const struct btf_type *t;
-       s32 id;
-
-       id = bpf_find_btf_id(func_name, BTF_KIND_FUNC, btf_p);
-       if (id < 0)
-               return NULL;
-
-       /* Get BTF_KIND_FUNC type */
-       t = btf_type_by_id(*btf_p, id);
-       if (!t || !btf_type_is_func(t))
-               goto err;
-
-       /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */
-       t = btf_type_by_id(*btf_p, t->type);
-       if (!t || !btf_type_is_func_proto(t))
-               goto err;
-
-       return t;
-err:
-       btf_put(*btf_p);
-       return NULL;
-}
-
-/*
- * Get function parameter with the number of parameters.
- * This can return NULL if the function has no parameters.
- * It can return -EINVAL if the @func_proto is not a function proto type.
- */
-const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, 
s32 *nr)
-{
-       if (!btf_type_is_func_proto(func_proto))
-               return ERR_PTR(-EINVAL);
-
-       *nr = btf_type_vlen(func_proto);
-       if (*nr > 0)
-               return (const struct btf_param *)(func_proto + 1);
-       else
-               return NULL;
-}
-
-#define BTF_ANON_STACK_MAX     16
-
-struct btf_anon_stack {
-       u32 tid;
-       u32 offset;
-};
-
-/*
- * Find a member of data structure/union by name and return it.
- * Return NULL if not found, or -EINVAL if parameter is invalid.
- * If the member is an member of anonymous union/structure, the offset
- * of that anonymous union/structure is stored into @anon_offset. Caller
- * can calculate the correct offset from the root data structure by
- * adding anon_offset to the member's offset.
- */
-const struct btf_member *btf_find_struct_member(struct btf *btf,
-                                               const struct btf_type *type,
-                                               const char *member_name,
-                                               u32 *anon_offset)
-{
-       struct btf_anon_stack *anon_stack;
-       const struct btf_member *member;
-       u32 tid, cur_offset = 0;
-       const char *name;
-       int i, top = 0;
-
-       anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), 
GFP_KERNEL);
-       if (!anon_stack)
-               return ERR_PTR(-ENOMEM);
-
-retry:
-       if (!btf_type_is_struct(type)) {
-               member = ERR_PTR(-EINVAL);
-               goto out;
-       }
-
-       for_each_member(i, type, member) {
-               if (!member->name_off) {
-                       /* Anonymous union/struct: push it for later use */
-                       type = btf_type_skip_modifiers(btf, member->type, &tid);
-                       if (type && top < BTF_ANON_STACK_MAX) {
-                               anon_stack[top].tid = tid;
-                               anon_stack[top++].offset =
-                                       cur_offset + member->offset;
-                       }
-               } else {
-                       name = btf_name_by_offset(btf, member->name_off);
-                       if (name && !strcmp(member_name, name)) {
-                               if (anon_offset)
-                                       *anon_offset = cur_offset;
-                               goto out;
-                       }
-               }
-       }
-       if (top > 0) {
-               /* Pop from the anonymous stack and retry */
-               tid = anon_stack[--top].tid;
-               cur_offset = anon_stack[top].offset;
-               type = btf_type_by_id(btf, tid);
-               goto retry;
-       }
-       member = NULL;
-
-out:
-       kfree(anon_stack);
-       return member;
-}
-
diff --git a/kernel/trace/trace_btf.h b/kernel/trace/trace_btf.h
deleted file mode 100644
index 4bc44bc261e6..000000000000
--- a/kernel/trace/trace_btf.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <linux/btf.h>
-
-const struct btf_type *btf_find_func_proto(const char *func_name,
-                                          struct btf **btf_p);
-const struct btf_param *btf_get_func_param(const struct btf_type *func_proto,
-                                          s32 *nr);
-const struct btf_member *btf_find_struct_member(struct btf *btf,
-                                               const struct btf_type *type,
-                                               const char *member_name,
-                                               u32 *anon_offset);
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 4dc74d73fc1d..b33c424b8ee0 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -12,7 +12,7 @@
 #define pr_fmt(fmt)    "trace_probe: " fmt
 
 #include <linux/bpf.h>
-#include "trace_btf.h"
+#include <linux/btf.h>
 
 #include "trace_probe.h"
 


Reply via email to