]> git.baikalelectronics.ru Git - kernel.git/commit
net: dsa: setup master before ports
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 5 Jan 2022 23:11:17 +0000 (01:11 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 Jan 2022 11:59:10 +0000 (11:59 +0000)
commit33966c588e5ea790492710b1fb1e83f6e582d3a0
tree5cd6968ce4e769dd00f10ed556941125d72b977c
parent8faa7135f66278f39e9c792739d6f63a46b6588c
net: dsa: setup master before ports

It is said that as soon as a network interface is registered, all its
resources should have already been prepared, so that it is available for
sending and receiving traffic. One of the resources needed by a DSA
slave interface is the master.

dsa_tree_setup
-> dsa_tree_setup_ports
   -> dsa_port_setup
      -> dsa_slave_create
         -> register_netdevice
-> dsa_tree_setup_master
   -> dsa_master_setup
      -> sets up master->dsa_ptr, which enables reception

Therefore, there is a short period of time after register_netdevice()
during which the master isn't prepared to pass traffic to the DSA layer
(master->dsa_ptr is checked by eth_type_trans). Same thing during
unregistration, there is a time frame in which packets might be missed.

Note that this change opens us to another race: dsa_master_find_slave()
will get invoked potentially earlier than the slave creation, and later
than the slave deletion. Since dp->slave starts off as a NULL pointer,
the earlier calls aren't a problem, but the later calls are. To avoid
use-after-free, we should zeroize dp->slave before calling
dsa_slave_destroy().

In practice I cannot really test real life improvements brought by this
change, since in my systems, netdevice creation races with PHY autoneg
which takes a few seconds to complete, and that masks quite a few races.
Effects might be noticeable in a setup with fixed links all the way to
an external system.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/dsa2.c