net-sysfs: remove rtnl_trylock from device attributes
authorAntoine Tenart <atenart@kernel.org>
Tue, 4 Feb 2025 17:03:10 +0000 (18:03 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Feb 2025 01:49:07 +0000 (17:49 -0800)
commit79c61899b5eee317907efd1b0d06a1ada0cc00d8
tree34daadd961dee44cfbf772f62761fbc79881caac
parent0bea93fdbaf8675b7e8124bdcaf51497dcc8bcfa
net-sysfs: remove rtnl_trylock from device attributes

There is an ABBA deadlock between net device unregistration and sysfs
files being accessed[1][2]. To prevent this from happening all paths
taking the rtnl lock after the sysfs one (actually kn->active refcount)
use rtnl_trylock and return early (using restart_syscall)[3], which can
make syscalls to spin for a long time when there is contention on the
rtnl lock[4].

There are not many possibilities to improve the above:
- Rework the entire net/ locking logic.
- Invert two locks in one of the paths — not possible.

But here it's actually possible to drop one of the locks safely: the
kernfs_node refcount. More details in the code itself, which comes with
lots of comments.

Note that we check the device is alive in the added sysfs_rtnl_lock
helper to disallow sysfs operations to run after device dismantle has
started. This also help keeping the same behavior as before. Because of
this calls to dev_isalive in sysfs ops were removed.

[1] https://lore.kernel.org/netdev/49A4D5D5.5090602@trash.net/
[2] https://lore.kernel.org/netdev/m14oyhis31.fsf@fess.ebiederm.org/
[3] https://lore.kernel.org/netdev/20090226084924.16cb3e08@nehalam/
[4] https://lore.kernel.org/all/20210928125500.167943-1-atenart@kernel.org/T/

Signed-off-by: Antoine Tenart <atenart@kernel.org>
Link: https://patch.msgid.link/20250204170314.146022-2-atenart@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/rtnetlink.h
net/core/net-sysfs.c
net/core/rtnetlink.c