]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: stmmac: move MSI data out of struct stmmac_priv
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Fri, 13 Mar 2026 11:51:58 +0000 (11:51 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 17 Mar 2026 03:10:51 +0000 (20:10 -0700)
Only three platforms supprt MSIs, which means having all the strings
and interrupt arrays always allocated wastes space. None of this data
is performance critical - this data is only used when requesting and
releasing the MSI interrupts.

Move the MSI data out of struct stmmac_priv into its own separately
allocated structure, and move its initialisation to a separate
function.

This removes 768 bytes from struct stmmac_priv.

Link: https://lore.kernel.org/r/aYtq4ypxXTvn_Is6@shell.armlinux.org.uk
Reviewed-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1w113e-0000000DDwc-2oRv@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index bba9bb9c95bf07b736b4f8b41ca3ea1c9543463b..7a66edba8f66d845f481831d7c20c044903c8847 100644 (file)
@@ -243,6 +243,23 @@ struct stmmac_est {
        u32 max_sdu[MTL_MAX_TX_QUEUES];
 };
 
+struct stmmac_msi {
+       int sfty_ce_irq;
+       int sfty_ue_irq;
+       int rx_irq[MTL_MAX_RX_QUEUES];
+       int tx_irq[MTL_MAX_TX_QUEUES];
+
+       /*irq name */
+       char int_name_mac[IFNAMSIZ + 9];
+       char int_name_wol[IFNAMSIZ + 9];
+       char int_name_lpi[IFNAMSIZ + 9];
+       char int_name_sfty[IFNAMSIZ + 10];
+       char int_name_sfty_ce[IFNAMSIZ + 10];
+       char int_name_sfty_ue[IFNAMSIZ + 10];
+       char int_name_rx_irq[MTL_MAX_RX_QUEUES][IFNAMSIZ + 14];
+       char int_name_tx_irq[MTL_MAX_TX_QUEUES][IFNAMSIZ + 18];
+};
+
 struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
        u32 tx_coal_frames[MTL_MAX_TX_QUEUES];
@@ -329,19 +346,7 @@ struct stmmac_priv {
        unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
        unsigned int num_double_vlans;
        int sfty_irq;
-       int sfty_ce_irq;
-       int sfty_ue_irq;
-       int rx_irq[MTL_MAX_RX_QUEUES];
-       int tx_irq[MTL_MAX_TX_QUEUES];
-       /*irq name */
-       char int_name_mac[IFNAMSIZ + 9];
-       char int_name_wol[IFNAMSIZ + 9];
-       char int_name_lpi[IFNAMSIZ + 9];
-       char int_name_sfty[IFNAMSIZ + 10];
-       char int_name_sfty_ce[IFNAMSIZ + 10];
-       char int_name_sfty_ue[IFNAMSIZ + 10];
-       char int_name_rx_irq[MTL_MAX_RX_QUEUES][IFNAMSIZ + 14];
-       char int_name_tx_irq[MTL_MAX_TX_QUEUES][IFNAMSIZ + 18];
+       struct stmmac_msi *msi;
 
 #ifdef CONFIG_DEBUG_FS
        struct dentry *dbgfs_dir;
index 11150bddd8726dd6c092db0ad302d4a33dcb8bf2..124d7a00f9f00a747e56fc7746aaae43395279fd 100644 (file)
@@ -3725,6 +3725,7 @@ static void stmmac_free_irq(struct net_device *dev,
                            enum request_irq_err irq_err, int irq_idx)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       struct stmmac_msi *msi = priv->msi;
        int j;
 
        switch (irq_err) {
@@ -3732,28 +3733,30 @@ static void stmmac_free_irq(struct net_device *dev,
                irq_idx = priv->plat->tx_queues_to_use;
                fallthrough;
        case REQ_IRQ_ERR_TX:
-               for (j = irq_idx - 1; j >= 0; j--) {
-                       if (priv->tx_irq[j] > 0) {
-                               irq_set_affinity_hint(priv->tx_irq[j], NULL);
-                               free_irq(priv->tx_irq[j], &priv->dma_conf.tx_queue[j]);
+               for (j = irq_idx - 1; msi && j >= 0; j--) {
+                       if (msi->tx_irq[j] > 0) {
+                               irq_set_affinity_hint(msi->tx_irq[j], NULL);
+                               free_irq(msi->tx_irq[j],
+                                        &priv->dma_conf.tx_queue[j]);
                        }
                }
                irq_idx = priv->plat->rx_queues_to_use;
                fallthrough;
        case REQ_IRQ_ERR_RX:
-               for (j = irq_idx - 1; j >= 0; j--) {
-                       if (priv->rx_irq[j] > 0) {
-                               irq_set_affinity_hint(priv->rx_irq[j], NULL);
-                               free_irq(priv->rx_irq[j], &priv->dma_conf.rx_queue[j]);
+               for (j = irq_idx - 1; msi && j >= 0; j--) {
+                       if (msi->rx_irq[j] > 0) {
+                               irq_set_affinity_hint(msi->rx_irq[j], NULL);
+                               free_irq(msi->rx_irq[j],
+                                        &priv->dma_conf.rx_queue[j]);
                        }
                }
 
-               if (priv->sfty_ue_irq > 0 && priv->sfty_ue_irq != dev->irq)
-                       free_irq(priv->sfty_ue_irq, dev);
+               if (msi && msi->sfty_ue_irq > 0 && msi->sfty_ue_irq != dev->irq)
+                       free_irq(msi->sfty_ue_irq, dev);
                fallthrough;
        case REQ_IRQ_ERR_SFTY_UE:
-               if (priv->sfty_ce_irq > 0 && priv->sfty_ce_irq != dev->irq)
-                       free_irq(priv->sfty_ce_irq, dev);
+               if (msi && msi->sfty_ce_irq > 0 && msi->sfty_ce_irq != dev->irq)
+                       free_irq(msi->sfty_ce_irq, dev);
                fallthrough;
        case REQ_IRQ_ERR_SFTY_CE:
                if (priv->wol_irq > 0 && priv->wol_irq != dev->irq)
@@ -3773,9 +3776,30 @@ static void stmmac_free_irq(struct net_device *dev,
        }
 }
 
+static int stmmac_msi_init(struct stmmac_priv *priv,
+                          struct stmmac_resources *res)
+{
+       int i;
+
+       priv->msi = devm_kmalloc(priv->device, sizeof(*priv->msi), GFP_KERNEL);
+       if (!priv->msi)
+               return -ENOMEM;
+
+       priv->msi->sfty_ce_irq = res->sfty_ce_irq;
+       priv->msi->sfty_ue_irq = res->sfty_ue_irq;
+
+       for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
+               priv->msi->rx_irq[i] = res->rx_irq[i];
+       for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
+               priv->msi->tx_irq[i] = res->tx_irq[i];
+
+       return 0;
+}
+
 static int stmmac_request_irq_multi_msi(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       struct stmmac_msi *msi = priv->msi;
        enum request_irq_err irq_err;
        int irq_idx = 0;
        char *int_name;
@@ -3783,7 +3807,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
        int i;
 
        /* For common interrupt */
-       int_name = priv->int_name_mac;
+       int_name = msi->int_name_mac;
        sprintf(int_name, "%s:%s", dev->name, "mac");
        ret = request_irq(dev->irq, stmmac_mac_interrupt,
                          0, int_name, dev);
@@ -3799,7 +3823,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
         * is used for WoL
         */
        if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
-               int_name = priv->int_name_wol;
+               int_name = msi->int_name_wol;
                sprintf(int_name, "%s:%s", dev->name, "wol");
                ret = request_irq(priv->wol_irq,
                                  stmmac_mac_interrupt,
@@ -3817,7 +3841,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
         * Error line in case of another line is used
         */
        if (priv->sfty_irq > 0 && priv->sfty_irq != dev->irq) {
-               int_name = priv->int_name_sfty;
+               int_name = msi->int_name_sfty;
                sprintf(int_name, "%s:%s", dev->name, "safety");
                ret = request_irq(priv->sfty_irq, stmmac_safety_interrupt,
                                  0, int_name, dev);
@@ -3833,16 +3857,16 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
        /* Request the Safety Feature Correctible Error line in
         * case of another line is used
         */
-       if (priv->sfty_ce_irq > 0 && priv->sfty_ce_irq != dev->irq) {
-               int_name = priv->int_name_sfty_ce;
+       if (msi->sfty_ce_irq > 0 && msi->sfty_ce_irq != dev->irq) {
+               int_name = msi->int_name_sfty_ce;
                sprintf(int_name, "%s:%s", dev->name, "safety-ce");
-               ret = request_irq(priv->sfty_ce_irq,
+               ret = request_irq(msi->sfty_ce_irq,
                                  stmmac_safety_interrupt,
                                  0, int_name, dev);
                if (unlikely(ret < 0)) {
                        netdev_err(priv->dev,
                                   "%s: alloc sfty ce MSI %d (error: %d)\n",
-                                  __func__, priv->sfty_ce_irq, ret);
+                                  __func__, msi->sfty_ce_irq, ret);
                        irq_err = REQ_IRQ_ERR_SFTY_CE;
                        goto irq_error;
                }
@@ -3851,16 +3875,16 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
        /* Request the Safety Feature Uncorrectible Error line in
         * case of another line is used
         */
-       if (priv->sfty_ue_irq > 0 && priv->sfty_ue_irq != dev->irq) {
-               int_name = priv->int_name_sfty_ue;
+       if (msi->sfty_ue_irq > 0 && msi->sfty_ue_irq != dev->irq) {
+               int_name = msi->int_name_sfty_ue;
                sprintf(int_name, "%s:%s", dev->name, "safety-ue");
-               ret = request_irq(priv->sfty_ue_irq,
+               ret = request_irq(msi->sfty_ue_irq,
                                  stmmac_safety_interrupt,
                                  0, int_name, dev);
                if (unlikely(ret < 0)) {
                        netdev_err(priv->dev,
                                   "%s: alloc sfty ue MSI %d (error: %d)\n",
-                                  __func__, priv->sfty_ue_irq, ret);
+                                  __func__, msi->sfty_ue_irq, ret);
                        irq_err = REQ_IRQ_ERR_SFTY_UE;
                        goto irq_error;
                }
@@ -3870,23 +3894,23 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
        for (i = 0; i < priv->plat->rx_queues_to_use; i++) {
                if (i >= MTL_MAX_RX_QUEUES)
                        break;
-               if (priv->rx_irq[i] == 0)
+               if (msi->rx_irq[i] == 0)
                        continue;
 
-               int_name = priv->int_name_rx_irq[i];
+               int_name = msi->int_name_rx_irq[i];
                sprintf(int_name, "%s:%s-%d", dev->name, "rx", i);
-               ret = request_irq(priv->rx_irq[i],
+               ret = request_irq(msi->rx_irq[i],
                                  stmmac_msi_intr_rx,
                                  0, int_name, &priv->dma_conf.rx_queue[i]);
                if (unlikely(ret < 0)) {
                        netdev_err(priv->dev,
                                   "%s: alloc rx-%d  MSI %d (error: %d)\n",
-                                  __func__, i, priv->rx_irq[i], ret);
+                                  __func__, i, msi->rx_irq[i], ret);
                        irq_err = REQ_IRQ_ERR_RX;
                        irq_idx = i;
                        goto irq_error;
                }
-               irq_set_affinity_hint(priv->rx_irq[i],
+               irq_set_affinity_hint(msi->rx_irq[i],
                                      cpumask_of(i % num_online_cpus()));
        }
 
@@ -3894,23 +3918,23 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
        for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
                if (i >= MTL_MAX_TX_QUEUES)
                        break;
-               if (priv->tx_irq[i] == 0)
+               if (msi->tx_irq[i] == 0)
                        continue;
 
-               int_name = priv->int_name_tx_irq[i];
+               int_name = msi->int_name_tx_irq[i];
                sprintf(int_name, "%s:%s-%d", dev->name, "tx", i);
-               ret = request_irq(priv->tx_irq[i],
+               ret = request_irq(msi->tx_irq[i],
                                  stmmac_msi_intr_tx,
                                  0, int_name, &priv->dma_conf.tx_queue[i]);
                if (unlikely(ret < 0)) {
                        netdev_err(priv->dev,
                                   "%s: alloc tx-%d  MSI %d (error: %d)\n",
-                                  __func__, i, priv->tx_irq[i], ret);
+                                  __func__, i, msi->tx_irq[i], ret);
                        irq_err = REQ_IRQ_ERR_TX;
                        irq_idx = i;
                        goto irq_error;
                }
-               irq_set_affinity_hint(priv->tx_irq[i],
+               irq_set_affinity_hint(msi->tx_irq[i],
                                      cpumask_of(i % num_online_cpus()));
        }
 
@@ -7806,12 +7830,12 @@ static int __stmmac_dvr_probe(struct device *device,
        priv->dev->irq = res->irq;
        priv->wol_irq = res->wol_irq;
        priv->sfty_irq = res->sfty_irq;
-       priv->sfty_ce_irq = res->sfty_ce_irq;
-       priv->sfty_ue_irq = res->sfty_ue_irq;
-       for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
-               priv->rx_irq[i] = res->rx_irq[i];
-       for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
-               priv->tx_irq[i] = res->tx_irq[i];
+
+       if (priv->plat->flags & STMMAC_FLAG_MULTI_MSI_EN) {
+               ret = stmmac_msi_init(priv, res);
+               if (ret)
+                       return ret;
+       }
 
        if (!is_zero_ether_addr(res->mac))
                eth_hw_addr_set(priv->dev, res->mac);