On Mon, 2025-10-06 at 16:58 -0700, Andrii Nakryiko wrote: > On Fri, Oct 3, 2025 at 1:47 AM KaFai Wan <[email protected]> wrote: > > > > When unpinning a BPF hash table (htab or htab_lru) that contains internal > > structures (timer, workqueue, or task_work) in its values, a BUG warning > > is triggered: > > BUG: sleeping function called from invalid context at > > kernel/bpf/hashtab.c:244 > > in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 14, name: > > ksoftirqd/0 > > ... > > > > The issue arises from the interaction between BPF object unpinning and > > RCU callback mechanisms: > > 1. BPF object unpinning uses ->free_inode() which schedules cleanup via > > call_rcu(), deferring the actual freeing to an RCU callback that > > executes within the RCU_SOFTIRQ context. > > 2. During cleanup of hash tables containing internal structures, > > htab_map_free_internal_structs() is invoked, which includes > > cond_resched() or cond_resched_rcu() calls to yield the CPU during > > potentially long operations. > > > > However, cond_resched() or cond_resched_rcu() cannot be safely called from > > atomic RCU softirq context, leading to the BUG warning when attempting > > to reschedule. > > > > Fix this by changing from ->free_inode() to ->destroy_inode() for BPF > > objects (prog, map, link). This allows direct inode freeing without > > RCU callback scheduling, avoiding the invalid context warning. > > > > Reported-by: Le Chen <[email protected]> > > Closes: > > https://lore.kernel.org/all/[email protected]/ > > Fixes: 68134668c17f ("bpf: Add map side support for bpf timers.") > > Suggested-by: Alexei Starovoitov <[email protected]> > > Signed-off-by: KaFai Wan <[email protected]> > > --- > > kernel/bpf/inode.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c > > index f90bdcc0a047..65c2a71d7de1 100644 > > --- a/kernel/bpf/inode.c > > +++ b/kernel/bpf/inode.c > > @@ -790,7 +790,7 @@ const struct super_operations bpf_super_ops = { > > .statfs = simple_statfs, > > .drop_inode = inode_just_drop, > > .show_options = bpf_show_options, > > - .free_inode = bpf_free_inode, > > + .destroy_inode = bpf_free_inode, > > s/bpf_free_inode/bpf_destroy_inode/ then? ok, done in v2. > > > }; > > > > enum { > > -- > > 2.43.0 > >
-- Thanks, KaFai

