bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/3] libbpf: add bulk BTF type copying API
@ 2021-10-05  6:47 andrii.nakryiko
  2021-10-05  6:47 ` [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another andrii.nakryiko
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: andrii.nakryiko @ 2021-10-05  6:47 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Arnaldo Carvalho de Melo

From: Andrii Nakryiko <andrii@kernel.org>

Add bulk BTF type data copying API, btf__add_btf(), to libbpf. This API is
useful for tools that are manipulating BPF, such as pahole. They abstract away
the details of implementing a pretty mundane, but important to get right,
details of handling all possible BTF kinds, as well as, importantly, adjusting
BTF type IDs and copying/deduplicating strings and string offsets, referenced
from copied BTF types.

Also, being a batch API, it's possible to improve the efficiency by
preallocating necessary memory more efficiently.

This API is going to be used by pahole to implement efficient parallelized BTF
encoding.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>

Andrii Nakryiko (3):
  libbpf: add API that copies all BTF types from one BTF object to
    another
  selftests/bpf: refactor btf_write selftest to reuse BTF generation
    logic
  selftests/bpf: test new btf__add_btf() API

 tools/lib/bpf/btf.c                           | 114 +++++++++++++-
 tools/lib/bpf/btf.h                           |  22 +++
 tools/lib/bpf/libbpf.map                      |   1 +
 .../selftests/bpf/prog_tests/btf_write.c      | 141 +++++++++++++++++-
 4 files changed, 270 insertions(+), 8 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another
  2021-10-05  6:47 [PATCH bpf-next 0/3] libbpf: add bulk BTF type copying API andrii.nakryiko
@ 2021-10-05  6:47 ` andrii.nakryiko
  2021-10-05 21:55   ` Song Liu
  2021-10-05  6:47 ` [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic andrii.nakryiko
  2021-10-05  6:47 ` [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API andrii.nakryiko
  2 siblings, 1 reply; 8+ messages in thread
From: andrii.nakryiko @ 2021-10-05  6:47 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Arnaldo Carvalho de Melo

From: Andrii Nakryiko <andrii@kernel.org>

Add a bulk copying api, btf__add_btf(), that speeds up and simplifies
appending entire contents of one BTF object to another one, taking care
of copying BTF type data, adjusting resulting BTF type IDs according to
their new locations in the destination BTF object, as well as copying
and deduplicating all the referenced strings and updating all the string
offsets in new BTF types as appropriate.

This API is intended to be used from tools that are generating and
otherwise manipulating BTFs generically, such as pahole. In pahole's
case, this API is useful for speeding up parallelized BTF encoding, as
it allows pahole to offload all the intricacies of BTF type copying to
libbpf and handle the parallelization aspects of the process.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 tools/lib/bpf/btf.c      | 114 ++++++++++++++++++++++++++++++++++++++-
 tools/lib/bpf/btf.h      |  22 ++++++++
 tools/lib/bpf/libbpf.map |   1 +
 3 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 6ad63e4d418a..5faa94273d56 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -189,12 +189,17 @@ int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_
 	return 0;
 }
 
+static void *btf_add_type_offs_mem(struct btf *btf, size_t add_cnt)
+{
+	return libbpf_add_mem((void **)&btf->type_offs, &btf->type_offs_cap, sizeof(__u32),
+			      btf->nr_types, BTF_MAX_NR_TYPES, add_cnt);
+}
+
 static int btf_add_type_idx_entry(struct btf *btf, __u32 type_off)
 {
 	__u32 *p;
 
-	p = libbpf_add_mem((void **)&btf->type_offs, &btf->type_offs_cap, sizeof(__u32),
-			   btf->nr_types, BTF_MAX_NR_TYPES, 1);
+	p = btf_add_type_offs_mem(btf, 1);
 	if (!p)
 		return -ENOMEM;
 
@@ -1691,6 +1696,111 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t
 	return btf_commit_type(btf, sz);
 }
 
+static int btf_rewrite_type_ids(__u32 *type_id, void *ctx)
+{
+	struct btf *btf = ctx;
+
+	if (!*type_id) /* nothing to do for VOID references */
+		return 0;
+
+	/* we haven't updated btf's type count yet, so
+	 * btf->start_id + btf->nr_types - 1 is the type ID offset we should
+	 * add to all newly added BTF types
+	 */
+	*type_id += btf->start_id + btf->nr_types - 1;
+	return 0;
+}
+
+int btf__add_btf(struct btf *btf, const struct btf *src_btf)
+{
+	struct btf_pipe p = { .src = src_btf, .dst = btf };
+	int data_sz, sz, cnt, i, err, old_strs_len;
+	__u32 *off;
+	void *t;
+
+	/* appending split BTF isn't supported yet */
+	if (src_btf->base_btf)
+		return libbpf_err(-ENOTSUP);
+
+	/* deconstruct BTF, if necessary, and invalidate raw_data */
+	if (btf_ensure_modifiable(btf))
+		return libbpf_err(-ENOMEM);
+
+	/* remember original strings section size if we have to roll back
+	 * partial strings section changes
+	 */
+	old_strs_len = btf->hdr->str_len;
+
+	data_sz = src_btf->hdr->type_len;
+	cnt = btf__get_nr_types(src_btf);
+
+	/* pre-allocate enough memory for new types */
+	t = btf_add_type_mem(btf, data_sz);
+	if (!t)
+		return libbpf_err(-ENOMEM);
+
+	/* pre-allocate enough memory for type offset index for new types */
+	off = btf_add_type_offs_mem(btf, cnt);
+	if (!off)
+		return libbpf_err(-ENOMEM);
+
+	/* bulk copy types data for all types from src_btf */
+	memcpy(t, src_btf->types_data, data_sz);
+
+	for (i = 0; i < cnt; i++) {
+		sz = btf_type_size(t);
+		if (sz < 0) {
+			/* unlikely, has to be corrupted src_btf */
+			err = sz;
+			goto err_out;
+		}
+
+		/* fill out type ID to type offset mapping for lookups by type ID */
+		*off = t - btf->types_data;
+
+		/* add, dedup, and remap strings referenced by this BTF type */
+		err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
+		if (err)
+			goto err_out;
+
+		/* remap all type IDs referenced from this BTF type */
+		err = btf_type_visit_type_ids(t, btf_rewrite_type_ids, btf);
+		if (err)
+			goto err_out;
+
+		/* go to next type data and type offset index entry */
+		t += sz;
+		off++;
+	}
+
+	/* Up until now any of the copied type data was effectively invisible,
+	 * so if we exited early before this point due to error, BTF would be
+	 * effectively unmodified. There would be extra internal memory
+	 * pre-allocated, but it would not be available for querying.  But now
+	 * that we've copied and rewritten all the data successfully, we can
+	 * update type count and various internal offsets and sizes to
+	 * "commit" the changes and made them visible to the outside world.
+	 */
+	btf->hdr->type_len += data_sz;
+	btf->hdr->str_off += data_sz;
+	btf->nr_types += cnt;
+
+	/* return type ID of the first added BTF type */
+	return btf->start_id + btf->nr_types - cnt;
+err_out:
+	/* zero out preallocated memory as if it was just allocated with
+	 * libbpf_add_mem()
+	 */
+	memset(btf->types_data + btf->hdr->type_len, 0, data_sz);
+	memset(btf->strs_data + old_strs_len, 0, btf->hdr->str_len - old_strs_len);
+
+	/* and now restore original strings section size; types data size
+	 * wasn't modified, so doesn't need restoring, see big comment above */
+	btf->hdr->str_len = old_strs_len;
+
+	return libbpf_err(err);
+}
+
 /*
  * Append new BTF_KIND_INT type with:
  *   - *name* - non-empty, non-NULL type name;
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 2cfe31327920..823e7067d34e 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -173,6 +173,28 @@ LIBBPF_API int btf__find_str(struct btf *btf, const char *s);
 LIBBPF_API int btf__add_str(struct btf *btf, const char *s);
 LIBBPF_API int btf__add_type(struct btf *btf, const struct btf *src_btf,
 			     const struct btf_type *src_type);
+/**
+ * @brief **btf__add_btf()** appends all the BTF types from *src_btf* into *btf*
+ * @param btf BTF object which all the BTF types and strings are added to
+ * @param src_btf BTF object which all BTF types and referenced strings are copied from
+ * @return BTF type ID of the first appended BTF type, or negative error code
+ *
+ * **btf__add_btf()** can be used to simply and efficiently append the entire
+ * contents of one BTF object to another one. All the BTF type data is copied
+ * over, all referenced type IDs are adjusted by adding a necessary ID offset.
+ * Only strings referenced from BTF types are copied over and deduplicated, so
+ * if there were some unused strings in *src_btf*, those won't be copied over,
+ * which is consistent with the general string deduplication semantics of BTF
+ * writing APIs.
+ *
+ * If any error is encountered during this process, the contents of *btf* is
+ * left intact, which means that **btf__add_btf()** follows the transactional
+ * semantics and the operation as a whole is all-or-nothing.
+ *
+ * *src_btf* has to be non-split BTF, as of now copying types from split BTF
+ * is not supported and will result in -OPNOTSUP error code returned.
+ */
+LIBBPF_API int btf__add_btf(struct btf *btf, const struct btf *src_btf);
 
 LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
 LIBBPF_API int btf__add_float(struct btf *btf, const char *name, size_t byte_sz);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 9e649cf9e771..f6b0db1e8c8b 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -389,5 +389,6 @@ LIBBPF_0.5.0 {
 
 LIBBPF_0.6.0 {
 	global:
+		btf__add_btf;
 		btf__add_tag;
 } LIBBPF_0.5.0;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic
  2021-10-05  6:47 [PATCH bpf-next 0/3] libbpf: add bulk BTF type copying API andrii.nakryiko
  2021-10-05  6:47 ` [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another andrii.nakryiko
@ 2021-10-05  6:47 ` andrii.nakryiko
  2021-10-05 22:00   ` Song Liu
  2021-10-05  6:47 ` [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API andrii.nakryiko
  2 siblings, 1 reply; 8+ messages in thread
From: andrii.nakryiko @ 2021-10-05  6:47 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Arnaldo Carvalho de Melo

From: Andrii Nakryiko <andrii@kernel.org>

Next patch will need to reuse BTF generation logic, which tests every
supported BTF kind, for testing btf__add_btf() APIs. So restructure
existing selftests and make it as a single subtest that uses bulk
VALIDATE_RAW_BTF() macro for raw BTF dump checking.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 .../selftests/bpf/prog_tests/btf_write.c      | 55 +++++++++++++++++--
 1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/btf_write.c b/tools/testing/selftests/bpf/prog_tests/btf_write.c
index 76548eecce2c..aa4505618252 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_write.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_write.c
@@ -4,19 +4,15 @@
 #include <bpf/btf.h>
 #include "btf_helpers.h"
 
-void test_btf_write() {
+static void gen_btf(struct btf *btf)
+{
 	const struct btf_var_secinfo *vi;
 	const struct btf_type *t;
 	const struct btf_member *m;
 	const struct btf_enum *v;
 	const struct btf_param *p;
-	struct btf *btf;
 	int id, err, str_off;
 
-	btf = btf__new_empty();
-	if (!ASSERT_OK_PTR(btf, "new_empty"))
-		return;
-
 	str_off = btf__find_str(btf, "int");
 	ASSERT_EQ(str_off, -ENOENT, "int_str_missing_off");
 
@@ -301,6 +297,53 @@ void test_btf_write() {
 	ASSERT_EQ(btf_tag(t)->component_idx, 1, "tag_component_idx");
 	ASSERT_STREQ(btf_type_raw_dump(btf, 19),
 		     "[19] TAG 'tag2' type_id=14 component_idx=1", "raw_dump");
+}
+
+static void test_btf_add()
+{
+	struct btf *btf;
+
+	btf = btf__new_empty();
+	if (!ASSERT_OK_PTR(btf, "new_empty"))
+		return;
+
+	gen_btf(btf);
+
+	VALIDATE_RAW_BTF(
+		btf,
+		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+		"[2] PTR '(anon)' type_id=1",
+		"[3] CONST '(anon)' type_id=5",
+		"[4] VOLATILE '(anon)' type_id=3",
+		"[5] RESTRICT '(anon)' type_id=4",
+		"[6] ARRAY '(anon)' type_id=2 index_type_id=1 nr_elems=10",
+		"[7] STRUCT 's1' size=8 vlen=2\n"
+		"\t'f1' type_id=1 bits_offset=0\n"
+		"\t'f2' type_id=1 bits_offset=32 bitfield_size=16",
+		"[8] UNION 'u1' size=8 vlen=1\n"
+		"\t'f1' type_id=1 bits_offset=0 bitfield_size=16",
+		"[9] ENUM 'e1' size=4 vlen=2\n"
+		"\t'v1' val=1\n"
+		"\t'v2' val=2",
+		"[10] FWD 'struct_fwd' fwd_kind=struct",
+		"[11] FWD 'union_fwd' fwd_kind=union",
+		"[12] ENUM 'enum_fwd' size=4 vlen=0",
+		"[13] TYPEDEF 'typedef1' type_id=1",
+		"[14] FUNC 'func1' type_id=15 linkage=global",
+		"[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n"
+		"\t'p1' type_id=1\n"
+		"\t'p2' type_id=2",
+		"[16] VAR 'var1' type_id=1, linkage=global-alloc",
+		"[17] DATASEC 'datasec1' size=12 vlen=1\n"
+		"\ttype_id=1 offset=4 size=8",
+		"[18] TAG 'tag1' type_id=16 component_idx=-1",
+		"[19] TAG 'tag2' type_id=14 component_idx=1");
 
 	btf__free(btf);
 }
+
+void test_btf_write()
+{
+	if (test__start_subtest("btf_add"))
+		test_btf_add();
+}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API
  2021-10-05  6:47 [PATCH bpf-next 0/3] libbpf: add bulk BTF type copying API andrii.nakryiko
  2021-10-05  6:47 ` [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another andrii.nakryiko
  2021-10-05  6:47 ` [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic andrii.nakryiko
@ 2021-10-05  6:47 ` andrii.nakryiko
  2021-10-05 22:04   ` Song Liu
  2 siblings, 1 reply; 8+ messages in thread
From: andrii.nakryiko @ 2021-10-05  6:47 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Arnaldo Carvalho de Melo

From: Andrii Nakryiko <andrii@kernel.org>

Add a test that validates that btf__add_btf() API is correctly copying
all the types from the source BTF into destination BTF object and
adjusts type IDs and string offsets properly.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 .../selftests/bpf/prog_tests/btf_write.c      | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/btf_write.c b/tools/testing/selftests/bpf/prog_tests/btf_write.c
index aa4505618252..75fd280f75b2 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_write.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_write.c
@@ -342,8 +342,94 @@ static void test_btf_add()
 	btf__free(btf);
 }
 
+static void test_btf_add_btf()
+{
+	struct btf *btf1 = NULL, *btf2 = NULL;
+	int id;
+
+	btf1 = btf__new_empty();
+	if (!ASSERT_OK_PTR(btf1, "btf1"))
+		return;
+
+	btf2 = btf__new_empty();
+	if (!ASSERT_OK_PTR(btf2, "btf2"))
+		return;
+
+	gen_btf(btf1);
+	gen_btf(btf2);
+
+	id = btf__add_btf(btf1, btf2);
+	if (!ASSERT_EQ(id, 20, "id"))
+		goto cleanup;
+
+	VALIDATE_RAW_BTF(
+		btf1,
+		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+		"[2] PTR '(anon)' type_id=1",
+		"[3] CONST '(anon)' type_id=5",
+		"[4] VOLATILE '(anon)' type_id=3",
+		"[5] RESTRICT '(anon)' type_id=4",
+		"[6] ARRAY '(anon)' type_id=2 index_type_id=1 nr_elems=10",
+		"[7] STRUCT 's1' size=8 vlen=2\n"
+		"\t'f1' type_id=1 bits_offset=0\n"
+		"\t'f2' type_id=1 bits_offset=32 bitfield_size=16",
+		"[8] UNION 'u1' size=8 vlen=1\n"
+		"\t'f1' type_id=1 bits_offset=0 bitfield_size=16",
+		"[9] ENUM 'e1' size=4 vlen=2\n"
+		"\t'v1' val=1\n"
+		"\t'v2' val=2",
+		"[10] FWD 'struct_fwd' fwd_kind=struct",
+		"[11] FWD 'union_fwd' fwd_kind=union",
+		"[12] ENUM 'enum_fwd' size=4 vlen=0",
+		"[13] TYPEDEF 'typedef1' type_id=1",
+		"[14] FUNC 'func1' type_id=15 linkage=global",
+		"[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n"
+		"\t'p1' type_id=1\n"
+		"\t'p2' type_id=2",
+		"[16] VAR 'var1' type_id=1, linkage=global-alloc",
+		"[17] DATASEC 'datasec1' size=12 vlen=1\n"
+		"\ttype_id=1 offset=4 size=8",
+		"[18] TAG 'tag1' type_id=16 component_idx=-1",
+		"[19] TAG 'tag2' type_id=14 component_idx=1",
+
+		/* types appended from the second BTF */
+		"[20] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+		"[21] PTR '(anon)' type_id=20",
+		"[22] CONST '(anon)' type_id=24",
+		"[23] VOLATILE '(anon)' type_id=22",
+		"[24] RESTRICT '(anon)' type_id=23",
+		"[25] ARRAY '(anon)' type_id=21 index_type_id=20 nr_elems=10",
+		"[26] STRUCT 's1' size=8 vlen=2\n"
+		"\t'f1' type_id=20 bits_offset=0\n"
+		"\t'f2' type_id=20 bits_offset=32 bitfield_size=16",
+		"[27] UNION 'u1' size=8 vlen=1\n"
+		"\t'f1' type_id=20 bits_offset=0 bitfield_size=16",
+		"[28] ENUM 'e1' size=4 vlen=2\n"
+		"\t'v1' val=1\n"
+		"\t'v2' val=2",
+		"[29] FWD 'struct_fwd' fwd_kind=struct",
+		"[30] FWD 'union_fwd' fwd_kind=union",
+		"[31] ENUM 'enum_fwd' size=4 vlen=0",
+		"[32] TYPEDEF 'typedef1' type_id=20",
+		"[33] FUNC 'func1' type_id=34 linkage=global",
+		"[34] FUNC_PROTO '(anon)' ret_type_id=20 vlen=2\n"
+		"\t'p1' type_id=20\n"
+		"\t'p2' type_id=21",
+		"[35] VAR 'var1' type_id=20, linkage=global-alloc",
+		"[36] DATASEC 'datasec1' size=12 vlen=1\n"
+		"\ttype_id=20 offset=4 size=8",
+		"[37] TAG 'tag1' type_id=35 component_idx=-1",
+		"[38] TAG 'tag2' type_id=33 component_idx=1");
+
+cleanup:
+	btf__free(btf1);
+	btf__free(btf2);
+}
+
 void test_btf_write()
 {
 	if (test__start_subtest("btf_add"))
 		test_btf_add();
+	if (test__start_subtest("btf_add_btf"))
+		test_btf_add_btf();
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another
  2021-10-05  6:47 ` [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another andrii.nakryiko
@ 2021-10-05 21:55   ` Song Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Song Liu @ 2021-10-05 21:55 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Kernel Team, Arnaldo Carvalho de Melo



> On Oct 4, 2021, at 11:47 PM, andrii.nakryiko@gmail.com wrote:
> 
> From: Andrii Nakryiko <andrii@kernel.org>
> 
> Add a bulk copying api, btf__add_btf(), that speeds up and simplifies
> appending entire contents of one BTF object to another one, taking care
> of copying BTF type data, adjusting resulting BTF type IDs according to
> their new locations in the destination BTF object, as well as copying
> and deduplicating all the referenced strings and updating all the string
> offsets in new BTF types as appropriate.
> 
> This API is intended to be used from tools that are generating and
> otherwise manipulating BTFs generically, such as pahole. In pahole's
> case, this API is useful for speeding up parallelized BTF encoding, as
> it allows pahole to offload all the intricacies of BTF type copying to
> libbpf and handle the parallelization aspects of the process.
> 
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

Acked-by: Song Liu <songliubraving@fb.com>  

with on typo below. 

> ---
> tools/lib/bpf/btf.c      | 114 ++++++++++++++++++++++++++++++++++++++-
> tools/lib/bpf/btf.h      |  22 ++++++++
> tools/lib/bpf/libbpf.map |   1 +
> 3 files changed, 135 insertions(+), 2 deletions(-)
[...]

> diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
> index 2cfe31327920..823e7067d34e 100644
> --- a/tools/lib/bpf/btf.h
> +++ b/tools/lib/bpf/btf.h
> @@ -173,6 +173,28 @@ LIBBPF_API int btf__find_str(struct btf *btf, const char *s);
> LIBBPF_API int btf__add_str(struct btf *btf, const char *s);
> LIBBPF_API int btf__add_type(struct btf *btf, const struct btf *src_btf,
> 			     const struct btf_type *src_type);
> +/**
> + * @brief **btf__add_btf()** appends all the BTF types from *src_btf* into *btf*
> + * @param btf BTF object which all the BTF types and strings are added to
> + * @param src_btf BTF object which all BTF types and referenced strings are copied from
> + * @return BTF type ID of the first appended BTF type, or negative error code
> + *
> + * **btf__add_btf()** can be used to simply and efficiently append the entire
> + * contents of one BTF object to another one. All the BTF type data is copied
> + * over, all referenced type IDs are adjusted by adding a necessary ID offset.
> + * Only strings referenced from BTF types are copied over and deduplicated, so
> + * if there were some unused strings in *src_btf*, those won't be copied over,
> + * which is consistent with the general string deduplication semantics of BTF
> + * writing APIs.
> + *
> + * If any error is encountered during this process, the contents of *btf* is
> + * left intact, which means that **btf__add_btf()** follows the transactional
> + * semantics and the operation as a whole is all-or-nothing.
> + *
> + * *src_btf* has to be non-split BTF, as of now copying types from split BTF
> + * is not supported and will result in -OPNOTSUP error code returned.
                                         ^^^ typo: -ENOTSUP
> 
> + */
> +LIBBPF_API int btf__add_btf(struct btf *btf, const struct btf *src_btf);
> 
> LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
> LIBBPF_API int btf__add_float(struct btf *btf, const char *name, size_t byte_sz);
> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
> index 9e649cf9e771..f6b0db1e8c8b 100644
> --- a/tools/lib/bpf/libbpf.map
> +++ b/tools/lib/bpf/libbpf.map
> @@ -389,5 +389,6 @@ LIBBPF_0.5.0 {
> 
> LIBBPF_0.6.0 {
> 	global:
> +		btf__add_btf;
> 		btf__add_tag;
> } LIBBPF_0.5.0;
> -- 
> 2.30.2
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic
  2021-10-05  6:47 ` [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic andrii.nakryiko
@ 2021-10-05 22:00   ` Song Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Song Liu @ 2021-10-05 22:00 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: bpf, ast, daniel, andrii, Kernel Team, Arnaldo Carvalho de Melo



> On Oct 4, 2021, at 11:47 PM, andrii.nakryiko@gmail.com wrote:
> 
> From: Andrii Nakryiko <andrii@kernel.org>
> 
> Next patch will need to reuse BTF generation logic, which tests every
> supported BTF kind, for testing btf__add_btf() APIs. So restructure
> existing selftests and make it as a single subtest that uses bulk
> VALIDATE_RAW_BTF() macro for raw BTF dump checking.
> 
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

Acked-by: Song Liu <songliubraving@fb.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API
  2021-10-05  6:47 ` [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API andrii.nakryiko
@ 2021-10-05 22:04   ` Song Liu
  2021-10-06  3:12     ` Andrii Nakryiko
  0 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2021-10-05 22:04 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: bpf, ast, daniel, andrii, Kernel Team, Arnaldo Carvalho de Melo



> On Oct 4, 2021, at 11:47 PM, andrii.nakryiko@gmail.com wrote:
> 
> From: Andrii Nakryiko <andrii@kernel.org>
> 
> Add a test that validates that btf__add_btf() API is correctly copying
> all the types from the source BTF into destination BTF object and
> adjusts type IDs and string offsets properly.
> 
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> ---
> .../selftests/bpf/prog_tests/btf_write.c      | 86 +++++++++++++++++++
> 1 file changed, 86 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/btf_write.c b/tools/testing/selftests/bpf/prog_tests/btf_write.c
> index aa4505618252..75fd280f75b2 100644
> --- a/tools/testing/selftests/bpf/prog_tests/btf_write.c
> +++ b/tools/testing/selftests/bpf/prog_tests/btf_write.c
> @@ -342,8 +342,94 @@ static void test_btf_add()
> 	btf__free(btf);
> }
> 
> +static void test_btf_add_btf()
> +{
> +	struct btf *btf1 = NULL, *btf2 = NULL;
> +	int id;
> +
> +	btf1 = btf__new_empty();
> +	if (!ASSERT_OK_PTR(btf1, "btf1"))
> +		return;
> +
> +	btf2 = btf__new_empty();
> +	if (!ASSERT_OK_PTR(btf2, "btf2"))
> +		return;
We need goto cleanup here, no?

Thanks,
Song

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API
  2021-10-05 22:04   ` Song Liu
@ 2021-10-06  3:12     ` Andrii Nakryiko
  0 siblings, 0 replies; 8+ messages in thread
From: Andrii Nakryiko @ 2021-10-06  3:12 UTC (permalink / raw)
  To: Song Liu; +Cc: bpf, ast, daniel, andrii, Kernel Team, Arnaldo Carvalho de Melo

On Tue, Oct 5, 2021 at 3:05 PM Song Liu <songliubraving@fb.com> wrote:
>
>
>
> > On Oct 4, 2021, at 11:47 PM, andrii.nakryiko@gmail.com wrote:
> >
> > From: Andrii Nakryiko <andrii@kernel.org>
> >
> > Add a test that validates that btf__add_btf() API is correctly copying
> > all the types from the source BTF into destination BTF object and
> > adjusts type IDs and string offsets properly.
> >
> > Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> > ---
> > .../selftests/bpf/prog_tests/btf_write.c      | 86 +++++++++++++++++++
> > 1 file changed, 86 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/prog_tests/btf_write.c b/tools/testing/selftests/bpf/prog_tests/btf_write.c
> > index aa4505618252..75fd280f75b2 100644
> > --- a/tools/testing/selftests/bpf/prog_tests/btf_write.c
> > +++ b/tools/testing/selftests/bpf/prog_tests/btf_write.c
> > @@ -342,8 +342,94 @@ static void test_btf_add()
> >       btf__free(btf);
> > }
> >
> > +static void test_btf_add_btf()
> > +{
> > +     struct btf *btf1 = NULL, *btf2 = NULL;
> > +     int id;
> > +
> > +     btf1 = btf__new_empty();
> > +     if (!ASSERT_OK_PTR(btf1, "btf1"))
> > +             return;
> > +
> > +     btf2 = btf__new_empty();
> > +     if (!ASSERT_OK_PTR(btf2, "btf2"))
> > +             return;
> We need goto cleanup here, no?
>

yep, my bad, will fix

> Thanks,
> Song

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-10-06  3:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-05  6:47 [PATCH bpf-next 0/3] libbpf: add bulk BTF type copying API andrii.nakryiko
2021-10-05  6:47 ` [PATCH bpf-next 1/3] libbpf: add API that copies all BTF types from one BTF object to another andrii.nakryiko
2021-10-05 21:55   ` Song Liu
2021-10-05  6:47 ` [PATCH bpf-next 2/3] selftests/bpf: refactor btf_write selftest to reuse BTF generation logic andrii.nakryiko
2021-10-05 22:00   ` Song Liu
2021-10-05  6:47 ` [PATCH bpf-next 3/3] selftests/bpf: test new btf__add_btf() API andrii.nakryiko
2021-10-05 22:04   ` Song Liu
2021-10-06  3:12     ` Andrii Nakryiko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).