Skip to content

Commit 516fca5

Browse files
committed
Merge branch 'libbpf-type-suffixes-and-autocreate-flag-for-struct_ops-maps'
Eduard Zingerman says: ==================== libbpf: type suffixes and autocreate flag for struct_ops maps Tweak struct_ops related APIs to allow the following features: - specify version suffixes for stuct_ops map types; - share same BPF program between several map definitions with different local BTF types, assuming only maps with same kernel BTF type would be selected for load; - toggle autocreate flag for struct_ops maps; - automatically toggle autoload for struct_ops programs referenced from struct_ops maps, depending on autocreate status of the corresponding map; - use SEC("?.struct_ops") and SEC("?.struct_ops.link") to define struct_ops maps with autocreate == false after object open. This would allow loading programs like below: SEC("struct_ops/foo") int BPF_PROG(foo) { ... } SEC("struct_ops/bar") int BPF_PROG(bar) { ... } struct bpf_testmod_ops___v1 { int (*foo)(void); }; struct bpf_testmod_ops___v2 { int (*foo)(void); int (*bar)(void); }; /* Assume kernel type name to be 'test_ops' */ SEC(".struct_ops.link") struct test_ops___v1 map_v1 = { /* Program 'foo' shared by maps with * different local BTF type */ .foo = (void *)foo }; SEC(".struct_ops.link") struct test_ops___v2 map_v2 = { .foo = (void *)foo, .bar = (void *)bar }; Assuming the following tweaks are done before loading: /* to load v1 */ bpf_map__set_autocreate(skel->maps.map_v1, true); bpf_map__set_autocreate(skel->maps.map_v2, false); /* to load v2 */ bpf_map__set_autocreate(skel->maps.map_v1, false); bpf_map__set_autocreate(skel->maps.map_v2, true); Patch #8 ties autocreate and autoload flags for struct_ops maps and programs. Changelog: - v3 [3] -> v4: - changes for multiple styling suggestions from Andrii; - patch #5: libbpf log capture now happens for LIBBPF_INFO and LIBBPF_WARN messages and does not depend on verbosity flags (Andrii); - patch #6: fixed runtime crash caused by conflict with newly added test case struct_ops_multi_pages; - patch #7: fixed free of possibly uninitialized pointer (Daniel) - patch #8: simpler algorithm to detect which programs to autoload (Andrii); - patch #9: added assertions for autoload flag after object load (Andrii); - patch #12: DATASEC name rewrite in libbpf is now done inplace, no new strings added to BTF (Andrii); - patch #14: allow any printable characters in DATASEC names when kernel validates BTF (Andrii) - v2 [2] -> v3: - moved patch #8 logic to be fully done on load (requested by Andrii in offlist discussion); - in patch #9 added test case for shadow vars and autocreate/autoload interaction. - v1 [1] -> v2: - fixed memory leak in patch #1 (Kui-Feng); - improved error messages in patch #2 (Martin, Andrii); - in bad_struct_ops selftest from patch #6 added .test_2 map member setup (David); - added utility functions to capture libbpf log from selftests (David) - in selftests replaced usage of ...__open_and_load by separate calls to ..._open() and ..._load() (Andrii); - removed serial_... in selftest definitions (Andrii); - improved comments in selftest struct_ops_autocreate from patch #7 (David); - removed autoload toggling logic incompatible with shadow variables from bpf_map__set_autocreate(), instead struct_ops programs autoload property is computed at struct_ops maps load phase, see patch #8 (Kui-Feng, Martin, Andrii); - added support for SEC("?.struct_ops") and SEC("?.struct_ops.link") (Andrii). [1] https://lore.kernel.org/bpf/[email protected]/ [2] https://lore.kernel.org/bpf/[email protected]/ [3] https://lore.kernel.org/bpf/[email protected]/ ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents 0f79bb8 + 5208930 commit 516fca5

File tree

17 files changed

+704
-69
lines changed

17 files changed

+704
-69
lines changed

kernel/bpf/btf.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,23 @@ static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
809809
return __btf_name_valid(btf, offset);
810810
}
811811

812+
/* Allow any printable character in DATASEC names */
812813
static bool btf_name_valid_section(const struct btf *btf, u32 offset)
813814
{
814-
return __btf_name_valid(btf, offset);
815+
/* offset must be valid */
816+
const char *src = btf_str_by_offset(btf, offset);
817+
const char *src_limit;
818+
819+
/* set a limit on identifier length */
820+
src_limit = src + KSYM_NAME_LEN;
821+
src++;
822+
while (*src && src < src_limit) {
823+
if (!isprint(*src))
824+
return false;
825+
src++;
826+
}
827+
828+
return !*src;
815829
}
816830

817831
static const char *__btf_name_by_offset(const struct btf *btf, u32 offset)

tools/lib/bpf/features.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,25 @@ static int probe_kern_btf_datasec(int token_fd)
147147
strs, sizeof(strs), token_fd));
148148
}
149149

150+
static int probe_kern_btf_qmark_datasec(int token_fd)
151+
{
152+
static const char strs[] = "\0x\0?.data";
153+
/* static int a; */
154+
__u32 types[] = {
155+
/* int */
156+
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
157+
/* VAR x */ /* [2] */
158+
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
159+
BTF_VAR_STATIC,
160+
/* DATASEC ?.data */ /* [3] */
161+
BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
162+
BTF_VAR_SECINFO_ENC(2, 0, 4),
163+
};
164+
165+
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
166+
strs, sizeof(strs), token_fd));
167+
}
168+
150169
static int probe_kern_btf_float(int token_fd)
151170
{
152171
static const char strs[] = "\0float";
@@ -534,6 +553,9 @@ static struct kern_feature_desc {
534553
[FEAT_ARG_CTX_TAG] = {
535554
"kernel-side __arg_ctx tag", probe_kern_arg_ctx_tag,
536555
},
556+
[FEAT_BTF_QMARK_DATASEC] = {
557+
"BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
558+
},
537559
};
538560

539561
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)

0 commit comments

Comments
 (0)