mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-26 07:13:42 -04:00
libbpf: Add section handlers for sleepable tracepoints
Add SEC_DEF entries for sleepable tracepoint variants: - "tp_btf.s+" for sleepable BTF-based raw tracepoints - "raw_tp.s+" for sleepable raw tracepoints - "raw_tracepoint.s+" (alias) - "tp.s+" for sleepable classic tracepoints - "tracepoint.s+" (alias) Extract sec_name_match_prefix() to share the prefix matching logic between attach_tp() and attach_raw_tp(), eliminating duplicated loops and hardcoded strcmp() checks for bare section names. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/bpf/20260422-sleepable_tracepoints-v13-5-99005dff21ef@meta.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
committed by
Kumar Kartikeya Dwivedi
parent
8cfb77d309
commit
0cd420a6f4
@@ -10018,11 +10018,16 @@ static const struct bpf_sec_def section_defs[] = {
|
||||
SEC_DEF("netkit/peer", SCHED_CLS, BPF_NETKIT_PEER, SEC_NONE),
|
||||
SEC_DEF("tracepoint+", TRACEPOINT, 0, SEC_NONE, attach_tp),
|
||||
SEC_DEF("tp+", TRACEPOINT, 0, SEC_NONE, attach_tp),
|
||||
SEC_DEF("tracepoint.s+", TRACEPOINT, 0, SEC_SLEEPABLE, attach_tp),
|
||||
SEC_DEF("tp.s+", TRACEPOINT, 0, SEC_SLEEPABLE, attach_tp),
|
||||
SEC_DEF("raw_tracepoint+", RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
|
||||
SEC_DEF("raw_tp+", RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
|
||||
SEC_DEF("raw_tracepoint.s+", RAW_TRACEPOINT, 0, SEC_SLEEPABLE, attach_raw_tp),
|
||||
SEC_DEF("raw_tp.s+", RAW_TRACEPOINT, 0, SEC_SLEEPABLE, attach_raw_tp),
|
||||
SEC_DEF("raw_tracepoint.w+", RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
|
||||
SEC_DEF("raw_tp.w+", RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
|
||||
SEC_DEF("tp_btf+", TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF, attach_trace),
|
||||
SEC_DEF("tp_btf.s+", TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
|
||||
SEC_DEF("fentry+", TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF, attach_trace),
|
||||
SEC_DEF("fmod_ret+", TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF, attach_trace),
|
||||
SEC_DEF("fexit+", TRACING, BPF_TRACE_FEXIT, SEC_ATTACH_BTF, attach_trace),
|
||||
@@ -13152,25 +13157,61 @@ struct bpf_link *bpf_program__attach_tracepoint(const struct bpf_program *prog,
|
||||
return bpf_program__attach_tracepoint_opts(prog, tp_category, tp_name, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Match section name against a prefix array. Returns pointer past
|
||||
* "prefix/" on match, empty string for bare sections (exact prefix
|
||||
* match), or NULL if no prefix matches.
|
||||
*/
|
||||
static const char *sec_name_match_prefix(const char *sec_name,
|
||||
const char *const *prefixes,
|
||||
size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
size_t pfx_len;
|
||||
|
||||
if (!str_has_pfx(sec_name, prefixes[i]))
|
||||
continue;
|
||||
|
||||
pfx_len = strlen(prefixes[i]);
|
||||
if (sec_name[pfx_len] == '\0')
|
||||
return sec_name + pfx_len;
|
||||
|
||||
if (sec_name[pfx_len] != '/' || sec_name[pfx_len + 1] == '\0')
|
||||
continue;
|
||||
|
||||
return sec_name + pfx_len + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)
|
||||
{
|
||||
static const char *const prefixes[] = {
|
||||
"tp.s",
|
||||
"tp",
|
||||
"tracepoint.s",
|
||||
"tracepoint",
|
||||
};
|
||||
char *sec_name, *tp_cat, *tp_name;
|
||||
const char *match;
|
||||
|
||||
*link = NULL;
|
||||
|
||||
/* no auto-attach for SEC("tp") or SEC("tracepoint") */
|
||||
if (strcmp(prog->sec_name, "tp") == 0 || strcmp(prog->sec_name, "tracepoint") == 0)
|
||||
match = sec_name_match_prefix(prog->sec_name, prefixes, ARRAY_SIZE(prefixes));
|
||||
if (!match) {
|
||||
pr_warn("prog '%s': invalid section name '%s'\n", prog->name, prog->sec_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!match[0]) /* bare section name no autoattach */
|
||||
return 0;
|
||||
|
||||
sec_name = strdup(prog->sec_name);
|
||||
if (!sec_name)
|
||||
return -ENOMEM;
|
||||
|
||||
/* extract "tp/<category>/<name>" or "tracepoint/<category>/<name>" */
|
||||
if (str_has_pfx(prog->sec_name, "tp/"))
|
||||
tp_cat = sec_name + sizeof("tp/") - 1;
|
||||
else
|
||||
tp_cat = sec_name + sizeof("tracepoint/") - 1;
|
||||
tp_cat = sec_name + (match - prog->sec_name);
|
||||
tp_name = strchr(tp_cat, '/');
|
||||
if (!tp_name) {
|
||||
free(sec_name);
|
||||
@@ -13234,37 +13275,22 @@ static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf
|
||||
"raw_tracepoint",
|
||||
"raw_tp.w",
|
||||
"raw_tracepoint.w",
|
||||
"raw_tp.s",
|
||||
"raw_tracepoint.s",
|
||||
};
|
||||
size_t i;
|
||||
const char *tp_name = NULL;
|
||||
const char *match;
|
||||
|
||||
*link = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
|
||||
size_t pfx_len;
|
||||
|
||||
if (!str_has_pfx(prog->sec_name, prefixes[i]))
|
||||
continue;
|
||||
|
||||
pfx_len = strlen(prefixes[i]);
|
||||
/* no auto-attach case of, e.g., SEC("raw_tp") */
|
||||
if (prog->sec_name[pfx_len] == '\0')
|
||||
return 0;
|
||||
|
||||
if (prog->sec_name[pfx_len] != '/')
|
||||
continue;
|
||||
|
||||
tp_name = prog->sec_name + pfx_len + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tp_name) {
|
||||
pr_warn("prog '%s': invalid section name '%s'\n",
|
||||
prog->name, prog->sec_name);
|
||||
match = sec_name_match_prefix(prog->sec_name, prefixes, ARRAY_SIZE(prefixes));
|
||||
if (!match) {
|
||||
pr_warn("prog '%s': invalid section name '%s'\n", prog->name, prog->sec_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!match[0])
|
||||
return 0;
|
||||
|
||||
*link = bpf_program__attach_raw_tracepoint(prog, tp_name);
|
||||
*link = bpf_program__attach_raw_tracepoint(prog, match);
|
||||
return libbpf_get_error(*link);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user