[WARN] net: lockdep reports false ABBA between netdev instance locks during batch unregister

Junseo Lim <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi,

We found a CONFIG_LOCKDEP warning in the netdev unregister path while
network namespaces are being cleaned up in batch.

The warning is:

WARNING: possible circular locking dependency detected
7.2.0-rc1-dirty #93 Not tainted

kworker/u8:2/38 is trying to acquire lock:
ffff888022d54d88 (&dev_instance_lock_key#15){+.+.}-{4:4}, at:
netdev_lock linux/include/linux/netdevice.h:2847 [inline]
unregister_netdevice_many_notify+0x541/0x2180 linux/net/core/dev.c:12400

but task is already holding lock:
ffff888116e10d88 (&dev_instance_lock_key#3){+.+.}-{4:4}, at:
netdev_lock linux/include/linux/netdevice.h:2847 [inline]
unregister_netdevice_many_notify+0x541/0x2180 linux/net/core/dev.c:12400

5 locks held by kworker/u8:2/38:
 #3: ffffffff986ea2e0 (rtnl_mutex){+.+.}-{4:4}, at:
 default_device_exit_batch+0xe1/0xa10 linux/net/core/dev.c:13079

Call Trace:
 unregister_netdevice_many_notify
 unregister_netdevice_many
 default_device_exit_batch
 cleanup_net
 worker_thread

The warning is triggered by the ops-locked close phase in
unregister_netdevice_many_notify():

list_for_each_entry(dev, head, unreg_list) {
	if (!(dev->flags & IFF_UP))
		continue;
	if (netdev_need_ops_lock(dev)) {
		list_add_tail(&dev->close_list, &close_head);
		netdev_lock(dev);
	}
	netif_close_many_and_unlock_cond(&close_head);
}
netif_close_many_and_unlock(&close_head);

This loop can accumulate multiple devices in close_head while their
per-device dev->lock mutexes are held. In this report, lockdep had already
recorded:

  dev_instance_lock_key#15 -> dev_instance_lock_key#3

and the current execution was trying to add the reverse dependency:

  dev_instance_lock_key#3 -> dev_instance_lock_key#15

The current stack is running under rtnl_mutex, and netdev_lock_cmp_fn()
also appears to intend to allow nested netdev locks under RTNL. However,
the two locks in this report are in distinct lockdep classes, so the
RTNL-based ordering exception does not prevent the cross-class ABBA report.

A possible way to avoid the warning is to make
netif_close_many_and_unlock_cond() always flush the accumulated close list
under CONFIG_LOCKDEP, instead of doing so only when lockdep depth exceeds
the limit:

static void netif_close_many_and_unlock_cond(struct list_head *close_head)
{
#ifdef CONFIG_LOCKDEP
	netif_close_many_and_unlock(close_head);
#endif
}

This keeps the non-CONFIG_LOCKDEP behavior unchanged, but makes
CONFIG_LOCKDEP skip batching in this close phase by flushing the close list
earlier.

This was found by our custom fuzzer developed by
Sechang Lim <[email protected]>.

Thanks,
Junseo Lim
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.