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:
Mykyta Yatsenko
2026-04-22 12:41:10 -07:00
committed by Kumar Kartikeya Dwivedi
parent 8cfb77d309
commit 0cd420a6f4

View File

@@ -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);
}