net-sysfs: try not to restart the syscall if it will fail eventually
authorAntoine Tenart <atenart@kernel.org>
Thu, 7 Oct 2021 14:00:51 +0000 (16:00 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Oct 2021 14:24:02 +0000 (15:24 +0100)
commit146e5e733310379f51924111068f08a3af0db830
tree0a2b2774a35a2383a83d29a17c9bbe105e671dc0
parent2b12d51c4fa8dab6a879681cbf52f30e667c928c
net-sysfs: try not to restart the syscall if it will fail eventually

Due to deadlocks in the networking subsystem spotted 12 years ago[1],
a workaround was put in place[2] to avoid taking the rtnl lock when it
was not available and restarting the syscall (back to VFS, letting
userspace spin). The following construction is found a lot in the net
sysfs and sysctl code:

  if (!rtnl_trylock())
          return restart_syscall();

This can be problematic when multiple userspace threads use such
interfaces in a short period, making them to spin a lot. This happens
for example when adding and moving virtual interfaces: userspace
programs listening on events, such as systemd-udevd and NetworkManager,
do trigger actions reading files in sysfs. It gets worse when a lot of
virtual interfaces are created concurrently, say when creating
containers at boot time.

Returning early without hitting the above pattern when the syscall will
fail eventually does make things better. While it is not a fix for the
issue, it does ease things.

[1] https://lore.kernel.org/netdev/49A4D5D5.5090602@trash.net/
    https://lore.kernel.org/netdev/m14oyhis31.fsf@fess.ebiederm.org/
    and https://lore.kernel.org/netdev/20090226084924.16cb3e08@nehalam/
[2] Rightfully, those deadlocks are *hard* to solve.

Signed-off-by: Antoine Tenart <atenart@kernel.org>
Reviewed-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/net-sysfs.c