net: repack struct netdev_queue
authorJakub Kicinski <kuba@kernel.org>
Tue, 20 Aug 2024 20:51:19 +0000 (13:51 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 22 Aug 2024 00:37:39 +0000 (17:37 -0700)
Adding the NAPI pointer to struct netdev_queue made it grow into another
cacheline, even though there was 44 bytes of padding available.

The struct was historically grouped as follows:

    /* read-mostly stuff (align) */
    /* ... random control path fields ... */
    /* write-mostly stuff (align) */
    /* ... 40 byte hole ... */
    /* struct dql (align) */

It seems that people want to add control path fields after
the read only fields. struct dql looks pretty innocent
but it forces its own alignment and nothing indicates that
there is a lot of empty space above it.

Move dql above the xmit_lock. This shifts the empty space
to the end of the struct rather than in the middle of it.
Move two example fields there to set an example.
Hopefully people will now add new fields at the end of
the struct. A lot of the read-only stuff is also control
path-only, but if we move it all we'll have another hole
in the middle.

Before:
/* size: 384, cachelines: 6, members: 16 */
/* sum members: 284, holes: 3, sum holes: 100 */

After:
        /* size: 320, cachelines: 5, members: 16 */
        /* sum members: 284, holes: 1, sum holes: 8 */

Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20240820205119.1321322-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/netdevice.h

index 0ef3eaa23f4b726d0e402b9065a4841c0dacb33a..614ec5d3d75b33f538c12c8604dcf9b816d3e173 100644 (file)
@@ -644,9 +644,6 @@ struct netdev_queue {
        struct Qdisc __rcu      *qdisc_sleeping;
 #ifdef CONFIG_SYSFS
        struct kobject          kobj;
-#endif
-#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
-       int                     numa_node;
 #endif
        unsigned long           tx_maxrate;
        /*
@@ -660,13 +657,13 @@ struct netdev_queue {
 #ifdef CONFIG_XDP_SOCKETS
        struct xsk_buff_pool    *pool;
 #endif
-       /* NAPI instance for the queue
-        * Readers and writers must hold RTNL
-        */
-       struct napi_struct      *napi;
+
 /*
  * write-mostly part
  */
+#ifdef CONFIG_BQL
+       struct dql              dql;
+#endif
        spinlock_t              _xmit_lock ____cacheline_aligned_in_smp;
        int                     xmit_lock_owner;
        /*
@@ -676,8 +673,16 @@ struct netdev_queue {
 
        unsigned long           state;
 
-#ifdef CONFIG_BQL
-       struct dql              dql;
+/*
+ * slow- / control-path part
+ */
+       /* NAPI instance for the queue
+        * Readers and writers must hold RTNL
+        */
+       struct napi_struct      *napi;
+
+#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
+       int                     numa_node;
 #endif
 } ____cacheline_aligned_in_smp;