From: Donglin Peng <dolinux.peng@gmail.com>
To: ast@kernel.org, andrii.nakryiko@gmail.com, eddyz87@gmail.com
Cc: zhangxiaoqin@xiaomi.com, ihor.solodrai@linux.dev,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
pengdonglin <pengdonglin@xiaomi.com>,
Alan Maguire <alan.maguire@oracle.com>
Subject: [PATCH bpf-next v10 01/13] libbpf: Add BTF permutation support for type reordering
Date: Thu, 18 Dec 2025 19:30:39 +0800 [thread overview]
Message-ID: <20251218113051.455293-2-dolinux.peng@gmail.com> (raw)
In-Reply-To: <20251218113051.455293-1-dolinux.peng@gmail.com>
From: pengdonglin <pengdonglin@xiaomi.com>
Introduce btf__permute() API to allow in-place rearrangement of BTF types.
This function reorganizes BTF type order according to a provided array of
type IDs, updating all type references to maintain consistency.
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Ihor Solodrai <ihor.solodrai@linux.dev>
Cc: Xiaoqin Zhang <zhangxiaoqin@xiaomi.com>
Signed-off-by: pengdonglin <pengdonglin@xiaomi.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
---
tools/lib/bpf/btf.c | 119 +++++++++++++++++++++++++++++++++++++++
tools/lib/bpf/btf.h | 36 ++++++++++++
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 156 insertions(+)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index b136572e889a..ab204ca403dc 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -5887,3 +5887,122 @@ int btf__relocate(struct btf *btf, const struct btf *base_btf)
btf->owns_base = false;
return libbpf_err(err);
}
+
+struct btf_permute {
+ struct btf *btf;
+ __u32 *id_map;
+};
+
+/* Callback function to remap individual type ID references */
+static int btf_permute_remap_type_id(__u32 *type_id, void *ctx)
+{
+ struct btf_permute *p = ctx;
+ __u32 new_type_id = *type_id;
+
+ /* refer to the base BTF or VOID type */
+ if (new_type_id < p->btf->start_id)
+ return 0;
+
+ if (new_type_id >= btf__type_cnt(p->btf))
+ return -EINVAL;
+
+ *type_id = p->id_map[new_type_id - p->btf->start_id];
+ return 0;
+}
+
+int btf__permute(struct btf *btf, __u32 *id_map, __u32 id_map_cnt,
+ const struct btf_permute_opts *opts)
+{
+ struct btf_permute p;
+ struct btf_ext *btf_ext;
+ void *nt, *new_types = NULL;
+ __u32 *order_map = NULL;
+ int err = 0, i;
+ __u32 id;
+
+ if (!OPTS_VALID(opts, btf_permute_opts) || id_map_cnt != btf->nr_types)
+ return libbpf_err(-EINVAL);
+
+ /* record the sequence of types */
+ order_map = calloc(id_map_cnt, sizeof(*id_map));
+ if (!order_map) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ new_types = calloc(btf->hdr->type_len, 1);
+ if (!new_types) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ if (btf_ensure_modifiable(btf)) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < id_map_cnt; i++) {
+ id = id_map[i];
+ if (id < btf->start_id || id >= btf__type_cnt(btf)) {
+ err = -EINVAL;
+ goto done;
+ }
+ id -= btf->start_id;
+ /* cannot be mapped to the same ID */
+ if (order_map[id]) {
+ err = -EINVAL;
+ goto done;
+ }
+ order_map[id] = i + btf->start_id;
+ }
+
+ p.btf = btf;
+ p.id_map = id_map;
+ nt = new_types;
+ for (i = 0; i < id_map_cnt; i++) {
+ struct btf_field_iter it;
+ const struct btf_type *t;
+ __u32 *type_id;
+ int type_size;
+
+ id = order_map[i];
+ t = btf__type_by_id(btf, id);
+ type_size = btf_type_size(t);
+ memcpy(nt, t, type_size);
+
+ /* fix up referenced IDs for BTF */
+ err = btf_field_iter_init(&it, nt, BTF_FIELD_ITER_IDS);
+ if (err)
+ goto done;
+ while ((type_id = btf_field_iter_next(&it))) {
+ err = btf_permute_remap_type_id(type_id, &p);
+ if (err)
+ goto done;
+ }
+
+ nt += type_size;
+ }
+
+ /* fix up referenced IDs for btf_ext */
+ btf_ext = OPTS_GET(opts, btf_ext, NULL);
+ if (btf_ext) {
+ err = btf_ext_visit_type_ids(btf_ext, btf_permute_remap_type_id, &p);
+ if (err)
+ goto done;
+ }
+
+ for (nt = new_types, i = 0; i < id_map_cnt; i++) {
+ btf->type_offs[i] = nt - new_types;
+ nt += btf_type_size(nt);
+ }
+
+ free(order_map);
+ free(btf->types_data);
+ btf->types_data = new_types;
+ return 0;
+
+done:
+ free(order_map);
+ free(new_types);
+ return libbpf_err(err);
+}
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index cc01494d6210..5d560571b1b5 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -281,6 +281,42 @@ LIBBPF_API int btf__dedup(struct btf *btf, const struct btf_dedup_opts *opts);
*/
LIBBPF_API int btf__relocate(struct btf *btf, const struct btf *base_btf);
+struct btf_permute_opts {
+ size_t sz;
+ /* optional .BTF.ext info along the main BTF info */
+ struct btf_ext *btf_ext;
+ size_t :0;
+};
+#define btf_permute_opts__last_field btf_ext
+
+/**
+ * @brief **btf__permute()** performs in-place BTF type rearrangement
+ * @param btf BTF object to permute
+ * @param id_map Array mapping original type IDs to new IDs
+ * @param id_map_cnt Number of elements in @id_map
+ * @param opts Optional parameters for BTF extension updates
+ * @return 0 on success, negative error code on failure
+ *
+ * **btf__permute()** rearranges BTF types according to the specified ID mapping.
+ * The @id_map array defines the new type ID for each original type ID.
+ *
+ * @id_map must include all types from ID `start_id` to `btf__type_cnt(btf) - 1`.
+ * @id_map_cnt should be `btf__type_cnt(btf) - start_id`
+ * The mapping is defined as: `id_map[original_id - start_id] = new_id`
+ *
+ * For base BTF, its `start_id` is fixed to 1, i.e. the VOID type can
+ * not be redefined or remapped and its ID is fixed to 0.
+ *
+ * For split BTF, its `start_id` can be retrieved by calling
+ * `btf__type_cnt(btf__base_btf(btf))`.
+ *
+ * On error, returns negative error code and sets errno:
+ * - `-EINVAL`: Invalid parameters or ID mapping (duplicates, out-of-range)
+ * - `-ENOMEM`: Memory allocation failure
+ */
+LIBBPF_API int btf__permute(struct btf *btf, __u32 *id_map, __u32 id_map_cnt,
+ const struct btf_permute_opts *opts);
+
struct btf_dump;
struct btf_dump_opts {
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 84fb90a016c9..d18fbcea7578 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -453,4 +453,5 @@ LIBBPF_1.7.0 {
bpf_map__exclusive_program;
bpf_prog_assoc_struct_ops;
bpf_program__assoc_struct_ops;
+ btf__permute;
} LIBBPF_1.6.0;
--
2.34.1
next prev parent reply other threads:[~2025-12-18 11:31 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-18 11:30 [PATCH bpf-next v10 00/13] Improve the performance of BTF type lookups with binary search Donglin Peng
2025-12-18 11:30 ` Donglin Peng [this message]
2025-12-18 23:02 ` [PATCH bpf-next v10 01/13] libbpf: Add BTF permutation support for type reordering Andrii Nakryiko
2025-12-19 3:14 ` Donglin Peng
2025-12-19 3:16 ` Donglin Peng
2025-12-19 17:07 ` Andrii Nakryiko
2025-12-20 8:39 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 02/13] selftests/bpf: Add test cases for btf__permute functionality Donglin Peng
2025-12-18 23:03 ` Andrii Nakryiko
2025-12-19 3:30 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 03/13] tools/resolve_btfids: Support BTF sorting feature Donglin Peng
2025-12-18 23:09 ` Andrii Nakryiko
2025-12-19 3:42 ` Donglin Peng
2025-12-19 17:12 ` Andrii Nakryiko
2025-12-20 8:44 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 04/13] libbpf: Optimize type lookup with binary search for sorted BTF Donglin Peng
2025-12-18 19:32 ` Eduard Zingerman
2025-12-18 23:29 ` Andrii Nakryiko
2025-12-19 0:13 ` Eduard Zingerman
2025-12-19 0:19 ` Andrii Nakryiko
2025-12-19 0:24 ` Eduard Zingerman
2025-12-19 1:01 ` Andrii Nakryiko
2025-12-19 2:53 ` Donglin Peng
2025-12-19 17:28 ` Andrii Nakryiko
2025-12-20 9:38 ` Donglin Peng
2025-12-22 1:58 ` Donglin Peng
2026-01-06 0:38 ` Andrii Nakryiko
2026-01-06 2:42 ` Donglin Peng
2026-01-06 0:36 ` Andrii Nakryiko
2026-01-06 2:50 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 05/13] libbpf: Verify BTF Sorting Donglin Peng
2025-12-18 19:38 ` Eduard Zingerman
2025-12-18 23:44 ` Andrii Nakryiko
2025-12-19 5:06 ` Donglin Peng
2025-12-19 17:33 ` Andrii Nakryiko
[not found] ` <CAErzpmsvirekLBRrJYVgmRC0YKWCbo7OyRQXgNYrk83aF-Wz2Q@mail.gmail.com>
2026-01-07 3:45 ` Donglin Peng
2026-01-07 21:50 ` Andrii Nakryiko
2026-01-08 1:50 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 06/13] btf: Optimize type lookup with binary search Donglin Peng
2025-12-18 21:38 ` Eduard Zingerman
2025-12-19 5:07 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 07/13] btf: Verify BTF Sorting Donglin Peng
2025-12-18 21:43 ` Eduard Zingerman
2025-12-19 5:10 ` Donglin Peng
2025-12-18 23:46 ` Andrii Nakryiko
2025-12-19 5:10 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 08/13] bpf: Skip anonymous types in type lookup for performance Donglin Peng
2025-12-18 22:21 ` Eduard Zingerman
2025-12-18 23:59 ` Andrii Nakryiko
2025-12-19 5:40 ` Donglin Peng
2025-12-18 22:24 ` Eduard Zingerman
2025-12-18 11:30 ` [PATCH bpf-next v10 09/13] bpf: Optimize the performance of find_bpffs_btf_enums Donglin Peng
2025-12-19 0:01 ` Andrii Nakryiko
2025-12-19 5:41 ` Donglin Peng
2025-12-20 14:27 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 10/13] libbpf: Optimize the performance of determine_ptr_size Donglin Peng
2025-12-18 22:27 ` Eduard Zingerman
2025-12-19 0:03 ` Andrii Nakryiko
2025-12-19 5:42 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 11/13] libbpf: Add btf_is_sorted and btf_sorted_start_id helpers to refactor the code Donglin Peng
2025-12-18 22:33 ` Eduard Zingerman
2025-12-19 5:49 ` Donglin Peng
2025-12-19 0:05 ` Andrii Nakryiko
2025-12-19 5:51 ` Donglin Peng
2025-12-19 17:35 ` Andrii Nakryiko
2025-12-20 14:27 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 12/13] btf: Add btf_is_sorted " Donglin Peng
2025-12-18 22:30 ` Eduard Zingerman
2025-12-19 0:05 ` Andrii Nakryiko
2025-12-20 14:25 ` Donglin Peng
2025-12-18 11:30 ` [PATCH bpf-next v10 13/13] btf: Refactor the code by calling str_is_empty Donglin Peng
2025-12-18 22:34 ` Eduard Zingerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251218113051.455293-2-dolinux.peng@gmail.com \
--to=dolinux.peng@gmail.com \
--cc=alan.maguire@oracle.com \
--cc=andrii.nakryiko@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=pengdonglin@xiaomi.com \
--cc=zhangxiaoqin@xiaomi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox