]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
docs: net: document new locking reality
authorStanislav Fomichev <sdf@fomichev.me>
Wed, 5 Mar 2025 16:37:31 +0000 (08:37 -0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Mar 2025 20:59:45 +0000 (12:59 -0800)
Also clarify ndo_get_stats (that read and write paths can run
concurrently) and mention only RCU.

Cc: Saeed Mahameed <saeed@kernel.org>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250305163732.2766420-14-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/netdevices.rst
include/linux/netdevice.h

index 1d37038e9fbed945aa95c08879289c288b7d5cc2..d235a73648930ccb88392c62bd11363a7801b26f 100644 (file)
@@ -210,49 +210,55 @@ packets is preferred.
 struct net_device synchronization rules
 =======================================
 ndo_open:
-       Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
        Context: process
 
 ndo_stop:
-       Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
        Context: process
        Note: netif_running() is guaranteed false
 
 ndo_do_ioctl:
        Synchronization: rtnl_lock() semaphore.
-       Context: process
 
-        This is only called by network subsystems internally,
-        not by user space calling ioctl as it was in before
-        linux-5.14.
+       This is only called by network subsystems internally,
+       not by user space calling ioctl as it was in before
+       linux-5.14.
 
 ndo_siocbond:
-        Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
         Context: process
 
-        Used by the bonding driver for the SIOCBOND family of
-        ioctl commands.
+       Used by the bonding driver for the SIOCBOND family of
+       ioctl commands.
 
 ndo_siocwandev:
-       Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
        Context: process
 
        Used by the drivers/net/wan framework to handle
        the SIOCWANDEV ioctl with the if_settings structure.
 
 ndo_siocdevprivate:
-       Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
        Context: process
 
        This is used to implement SIOCDEVPRIVATE ioctl helpers.
        These should not be added to new drivers, so don't use.
 
 ndo_eth_ioctl:
-       Synchronization: rtnl_lock() semaphore.
+       Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+       lock if the driver implements queue management or shaper API.
        Context: process
 
 ndo_get_stats:
-       Synchronization: rtnl_lock() semaphore, or RCU.
+       Synchronization: RCU (can be called concurrently with the stats
+       update path).
        Context: atomic (can't sleep under RCU)
 
 ndo_start_xmit:
@@ -284,6 +290,10 @@ ndo_set_rx_mode:
        Synchronization: netif_addr_lock spinlock.
        Context: BHs disabled
 
+Most ndo callbacks not specified in the list above are running
+under ``rtnl_lock``. In addition, netdev instance lock is taken as well if
+the driver implements queue management or shaper API.
+
 struct napi_struct synchronization rules
 ========================================
 napi->poll:
@@ -298,6 +308,35 @@ napi->poll:
                 softirq
                 will be called with interrupts disabled by netconsole.
 
+struct netdev_queue_mgmt_ops synchronization rules
+==================================================
+
+All queue management ndo callbacks are holding netdev instance lock.
+
+RTNL and netdev instance lock
+=============================
+
+Historically, all networking control operations were protected by a single
+global lock known as ``rtnl_lock``. There is an ongoing effort to replace this
+global lock with separate locks for each network namespace. Additionally,
+properties of individual netdev are increasingly protected by per-netdev locks.
+
+For device drivers that implement shaping or queue management APIs, all control
+operations will be performed under the netdev instance lock. Currently, this
+instance lock is acquired within the context of ``rtnl_lock``. The drivers
+can also explicitly request instance lock to be acquired via
+``request_ops_lock``. In the future, there will be an option for individual
+drivers to opt out of using ``rtnl_lock`` and instead perform their control
+operations directly under the netdev instance lock.
+
+Devices drivers are encouraged to rely on the instance lock where possible.
+
+For the (mostly software) drivers that need to interact with the core stack,
+there are two sets of interfaces: ``dev_xxx`` and ``netif_xxx`` (e.g.,
+``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx`` functions handle
+acquiring the instance lock themselves, while the ``netif_xxx`` functions
+assume that the driver has already acquired the instance lock.
+
 NETDEV_INTERNAL symbol namespace
 ================================
 
index adf201617b72f85b464f4e5202321e7c2e97455a..2f8560a354ba4cf486b3a3b20e160866d5be7007 100644 (file)
@@ -2505,6 +2505,10 @@ struct net_device {
         *
         * Also protects some fields in struct napi_struct.
         *
+        * For the drivers that implement shaper or queue API, the scope
+        * of this lock is expanded to cover most ndo/queue/ethtool/sysfs
+        * operations.
+        *
         * Ordering: take after rtnl_lock.
         */
        struct mutex            lock;