Re: [PATCH net v1] net/ipv6: mcast: fix circular locking dependency in __ipv6_dev_mc_inc()
From: Jakub Kicinski
Date: Wed Mar 18 2026 - 21:19:24 EST
On Tue, 17 Mar 2026 19:12:07 +0800 Jiayuan Chen wrote:
> syzbot reported a possible circular locking dependency:
>
> fs_reclaim --> sk_lock-AF_INET6 --> &idev->mc_lock
>
> CPU0 CPU1
> ---- ----
> lock(&idev->mc_lock)
> lock(sk_lock-AF_INET6)
> lock(&idev->mc_lock) // blocked
> kzalloc(GFP_KERNEL)
> fs_reclaim
> ...nbd I/O...
> sk_lock-AF_INET6 // blocked -> DEADLOCK
>
> __ipv6_dev_mc_inc() does GFP_KERNEL allocation inside mc_lock via
> mca_alloc(). This can enter memory reclaim, which through nbd block
> I/O may need sk_lock-AF_INET6. But sk_lock -> mc_lock already exists
> via setsockopt -> __ipv6_sock_mc_join, so we have a deadlock.
>
> Before commit 63ed8de4be81 ("mld: add mc_lock for protecting
> per-interface mld data"), only RTNL was held during the allocation.
> The lock ordering was always RTNL -> sk_lock (the nbd path doesn't
> involve RTNL), so there was no circular dependency.
>
> Split mca_alloc() into mca_alloc() + mca_init(): mca_alloc() does the
> GFP_KERNEL allocation before mc_lock, mca_init() initializes under
> mc_lock. If the address already exists, the pre-allocated memory is
> simply freed. Also move inet6_ifmcaddr_notify() outside mc_lock since
> it also does GFP_KERNEL allocation.
Moving the allocation seems fine, but also having to move the
notification, potentially letting the notification go out of order
makes me wonder if we aren't better off adding helpers for taking this
lock which also call memalloc_noio_{save,restore} ?