Skip to content

kfunc-gen: Don't list sleepable kfuncs for non-sleepable program types - #293

Merged
dylandreimerink merged 2 commits into
isovalent:masterfrom
NAME-ASHWANIYADAV:tools/kfunc-sleepable-filter
Sep 5, 2026
Merged

kfunc-gen: Don't list sleepable kfuncs for non-sleepable program types#293
dylandreimerink merged 2 commits into
isovalent:masterfrom
NAME-ASHWANIYADAV:tools/kfunc-sleepable-filter

Conversation

@NAME-ASHWANIYADAV

Copy link
Copy Markdown
Contributor

Fixes #138

What

kfunc-gen builds the kfunc <-> program type references purely from the sets in data/kfuncs.yaml, without looking at whether a kfunc may sleep. But a kfunc flagged KF_SLEEPABLE can only be called from a sleepable program:

sleepable = is_kfunc_sleepable(&meta);
if (sleepable && !in_sleepable(env)) {
    verbose(env, "program must be sleepable to call sleepable kfunc %s\n", func_name);
    return -EACCES;
}

So listing one under a program type that can never be sleepable is wrong in both directions: the kfunc page offers a program type that cannot call it, and the program type page lists a kfunc the verifier will always reject.

Which program types can be sleepable

check_attach_btf_id() decides this. Every type opts in with BPF_F_SLEEPABLE and has to pass can_be_sleepable(), except BPF_PROG_TYPE_SYSCALL, which is handled just above it and is always sleepable. That gives:

Program type Note
BPF_PROG_TYPE_TRACING fentry, fexit, fmod_ret, iter
BPF_PROG_TYPE_LSM
BPF_PROG_TYPE_KPROBE uprobes only
BPF_PROG_TYPE_STRUCT_OPS
BPF_PROG_TYPE_SYSCALL always sleepable

The set has only ever grown: v5.15 allowed TRACING and LSM, v6.1 added KPROBE, v6.4 added STRUCT_OPS and factored the check into can_be_sleepable(), and it has been unchanged since. So filtering against the current set cannot drop a
combination that is valid on an older kernel.

Note the filter is per program type, so KPROBE and TRACING stay in the lists even though only some of their attach types can be sleepable. Going finer would need attach-type granularity, which the data file does not carry.

Where the fix goes

One filter on the merged progTypes, next to the existing Except handling. That covers both directions at once, since the KFUNC_PROG_REF blocks and the progToKfunc map behind PROG_KFUNC_REF are both derived from it.

Impact

301 kfunc <-> program type combinations removed: 22 kfunc pages and 18 program type pages, 583 deletions and no additions.

BPF_PROG_TYPE_PERF_EVENT and BPF_PROG_TYPE_TRACEPOINT lose 23 entries each; the 15 program types reachable through BPF_PROG_TYPE_UNSPEC expansion (XDP, SCHED_CLS, the CGROUP_* family, LWT_*, NETFILTER, ...) lose 15 each.

Four KF_SLEEPABLE kfuncs are unaffected because they were already correct: bpf_crypto_ctx_create (SYSCALL), bpf_io_uring_submit_sqes (STRUCT_OPS), scx_bpf_create_dsq (STRUCT_OPS + SYSCALL), and cgroup_rstat_flush, which is
in removeKfuncs.

Testing

  • gofmt clean, go vet ./tools/kfunc-gen/ clean
  • The generator is idempotent: a second run produces no further diff, which is
    what the generate-docs workflow asserts
  • No kfunc page is left with an empty program type list
  • Only KF_SLEEPABLE kfunc pages changed, nothing else was touched
  • Cross-checked the output against an independent script that replays the merge
    logic over data/kfuncs.yaml. The only mismatch was
    BPF_PROG_TYPE_LWT_SEG6LOCAL, whose page has no PROG_KFUNC_REF markers, so
    the generator skips it. Pre-existing, left alone.

The kfunc <-> program type references are generated purely from the sets
in data/kfuncs.yaml, without taking the sleepability of a kfunc into
account. A kfunc flagged KF_SLEEPABLE can only be called from a sleepable
program:

    sleepable = is_kfunc_sleepable(&meta);
    if (sleepable && !in_sleepable(env)) {
        verbose(env, "program must be sleepable to call sleepable kfunc %s\n", func_name);
        return -EACCES;
    }

So listing such a kfunc under a program type that can never be sleepable
is wrong in both directions: the kfunc page offers a program type that
cannot call it, and the program type page lists a kfunc that will always
be rejected by the verifier.

check_attach_btf_id() decides which program types may be sleepable. Every
type has to opt in with BPF_F_SLEEPABLE and pass can_be_sleepable(), except
BPF_PROG_TYPE_SYSCALL which is handled just above it and is always
sleepable. That leaves TRACING (fentry/fexit/fmod_ret/iter), LSM, KPROBE
(uprobes) and STRUCT_OPS, plus SYSCALL.

The set only ever grew: v5.15 allowed TRACING and LSM, v6.1 added KPROBE,
v6.4 added STRUCT_OPS and factored the check into can_be_sleepable(), and
it has been unchanged since. Filtering against the current set therefore
cannot drop a combination that is valid on any supported kernel.

Filtering merged progTypes fixes both directions at once, since the
KFUNC_PROG_REF blocks and the progToKfunc map used for PROG_KFUNC_REF are
both derived from it.

Fixes: isovalent#138
Signed-off-by: Ashwani Yadav <22ashwaniyadav@gmail.com>
Result of the kfunc-gen sleepability filter. Removes 301 kfunc <-> program
type combinations the verifier would reject, across 22 kfunc pages and 18
program type pages. No kfunc is left without a program type.

Signed-off-by: Ashwani Yadav <22ashwaniyadav@gmail.com>
@NAME-ASHWANIYADAV

Copy link
Copy Markdown
Contributor Author

@dylandreimerink, could you please review this PR when you have a moment?

@NAME-ASHWANIYADAV NAME-ASHWANIYADAV changed the title Tools/kfunc sleepable filter kfunc-gen: Don't list sleepable kfuncs for non-sleepable program types Sep 4, 2026

@dylandreimerink dylandreimerink left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, thank you

@dylandreimerink
dylandreimerink merged commit a96a150 into isovalent:master Sep 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove sleepable kfuncs from non-sleepable program type references

2 participants