net: xgbe: Convert tasklet API to new bottom half workqueue mechanism
authorAllen Pais <allen.lkml@gmail.com>
Tue, 30 Jul 2024 18:33:50 +0000 (11:33 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 Aug 2024 01:59:46 +0000 (18:59 -0700)
Migrate tasklet APIs to the new bottom half workqueue mechanism. It
replaces all occurrences of tasklet usage with the appropriate workqueue
APIs throughout the xgbe driver. This transition ensures compatibility
with the latest design and enhances performance.

Signed-off-by: Allen Pais <allen.lkml@gmail.com>
Link: https://patch.msgid.link/20240730183403.4176544-3-allen.lkml@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
drivers/net/ethernet/amd/xgbe/xgbe-pci.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index c4a4e316683fa854168f260e70cdafed73321ece..5475867708f426ff7a389773cb3a9332dc369351 100644 (file)
@@ -403,9 +403,9 @@ static bool xgbe_ecc_ded(struct xgbe_prv_data *pdata, unsigned long *period,
        return false;
 }
 
-static void xgbe_ecc_isr_task(struct tasklet_struct *t)
+static void xgbe_ecc_isr_bh_work(struct work_struct *work)
 {
-       struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_ecc);
+       struct xgbe_prv_data *pdata = from_work(pdata, work, ecc_bh_work);
        unsigned int ecc_isr;
        bool stop = false;
 
@@ -465,17 +465,17 @@ static irqreturn_t xgbe_ecc_isr(int irq, void *data)
 {
        struct xgbe_prv_data *pdata = data;
 
-       if (pdata->isr_as_tasklet)
-               tasklet_schedule(&pdata->tasklet_ecc);
+       if (pdata->isr_as_bh_work)
+               queue_work(system_bh_wq, &pdata->ecc_bh_work);
        else
-               xgbe_ecc_isr_task(&pdata->tasklet_ecc);
+               xgbe_ecc_isr_bh_work(&pdata->ecc_bh_work);
 
        return IRQ_HANDLED;
 }
 
-static void xgbe_isr_task(struct tasklet_struct *t)
+static void xgbe_isr_bh_work(struct work_struct *work)
 {
-       struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_dev);
+       struct xgbe_prv_data *pdata = from_work(pdata, work, dev_bh_work);
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
        struct xgbe_channel *channel;
        unsigned int dma_isr, dma_ch_isr;
@@ -582,7 +582,7 @@ isr_done:
 
        /* If there is not a separate ECC irq, handle it here */
        if (pdata->vdata->ecc_support && (pdata->dev_irq == pdata->ecc_irq))
-               xgbe_ecc_isr_task(&pdata->tasklet_ecc);
+               xgbe_ecc_isr_bh_work(&pdata->ecc_bh_work);
 
        /* If there is not a separate I2C irq, handle it here */
        if (pdata->vdata->i2c_support && (pdata->dev_irq == pdata->i2c_irq))
@@ -604,10 +604,10 @@ static irqreturn_t xgbe_isr(int irq, void *data)
 {
        struct xgbe_prv_data *pdata = data;
 
-       if (pdata->isr_as_tasklet)
-               tasklet_schedule(&pdata->tasklet_dev);
+       if (pdata->isr_as_bh_work)
+               queue_work(system_bh_wq, &pdata->dev_bh_work);
        else
-               xgbe_isr_task(&pdata->tasklet_dev);
+               xgbe_isr_bh_work(&pdata->dev_bh_work);
 
        return IRQ_HANDLED;
 }
@@ -1007,8 +1007,8 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata)
        unsigned int i;
        int ret;
 
-       tasklet_setup(&pdata->tasklet_dev, xgbe_isr_task);
-       tasklet_setup(&pdata->tasklet_ecc, xgbe_ecc_isr_task);
+       INIT_WORK(&pdata->dev_bh_work, xgbe_isr_bh_work);
+       INIT_WORK(&pdata->ecc_bh_work, xgbe_ecc_isr_bh_work);
 
        ret = devm_request_irq(pdata->dev, pdata->dev_irq, xgbe_isr, 0,
                               netdev_name(netdev), pdata);
@@ -1078,8 +1078,8 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
 
        devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
 
-       tasklet_kill(&pdata->tasklet_dev);
-       tasklet_kill(&pdata->tasklet_ecc);
+       cancel_work_sync(&pdata->dev_bh_work);
+       cancel_work_sync(&pdata->ecc_bh_work);
 
        if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
                devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
index a9ccc4258ee50de5e51fe1b4d2fd21946b2a9cea..7a833894f52ad430fe0cf2f44d2353d2b881ef09 100644 (file)
@@ -274,9 +274,9 @@ static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata,
                XI2C_IOREAD(pdata, IC_CLR_STOP_DET);
 }
 
-static void xgbe_i2c_isr_task(struct tasklet_struct *t)
+static void xgbe_i2c_isr_bh_work(struct work_struct *work)
 {
-       struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_i2c);
+       struct xgbe_prv_data *pdata = from_work(pdata, work, i2c_bh_work);
        struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
        unsigned int isr;
 
@@ -321,10 +321,10 @@ static irqreturn_t xgbe_i2c_isr(int irq, void *data)
 {
        struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
 
-       if (pdata->isr_as_tasklet)
-               tasklet_schedule(&pdata->tasklet_i2c);
+       if (pdata->isr_as_bh_work)
+               queue_work(system_bh_wq, &pdata->i2c_bh_work);
        else
-               xgbe_i2c_isr_task(&pdata->tasklet_i2c);
+               xgbe_i2c_isr_bh_work(&pdata->i2c_bh_work);
 
        return IRQ_HANDLED;
 }
@@ -369,7 +369,7 @@ static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr)
 
 static irqreturn_t xgbe_i2c_combined_isr(struct xgbe_prv_data *pdata)
 {
-       xgbe_i2c_isr_task(&pdata->tasklet_i2c);
+       xgbe_i2c_isr_bh_work(&pdata->i2c_bh_work);
 
        return IRQ_HANDLED;
 }
@@ -449,7 +449,7 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
 
        if (pdata->dev_irq != pdata->i2c_irq) {
                devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
-               tasklet_kill(&pdata->tasklet_i2c);
+               cancel_work_sync(&pdata->i2c_bh_work);
        }
 }
 
@@ -464,7 +464,7 @@ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
 
        /* If we have a separate I2C irq, enable it */
        if (pdata->dev_irq != pdata->i2c_irq) {
-               tasklet_setup(&pdata->tasklet_i2c, xgbe_i2c_isr_task);
+               INIT_WORK(&pdata->i2c_bh_work, xgbe_i2c_isr_bh_work);
 
                ret = devm_request_irq(pdata->dev, pdata->i2c_irq,
                                       xgbe_i2c_isr, 0, pdata->i2c_name,
index 4a2dc705b52801792652c3ba6a9c945b306c3198..07f4f3418d0187f26321bdc660ea5793c3d1c638 100644 (file)
@@ -703,9 +703,9 @@ static void xgbe_an73_isr(struct xgbe_prv_data *pdata)
        }
 }
 
-static void xgbe_an_isr_task(struct tasklet_struct *t)
+static void xgbe_an_isr_bh_work(struct work_struct *work)
 {
-       struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_an);
+       struct xgbe_prv_data *pdata = from_work(pdata, work, an_bh_work);
 
        netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");
 
@@ -727,17 +727,17 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
 {
        struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
 
-       if (pdata->isr_as_tasklet)
-               tasklet_schedule(&pdata->tasklet_an);
+       if (pdata->isr_as_bh_work)
+               queue_work(system_bh_wq, &pdata->an_bh_work);
        else
-               xgbe_an_isr_task(&pdata->tasklet_an);
+               xgbe_an_isr_bh_work(&pdata->an_bh_work);
 
        return IRQ_HANDLED;
 }
 
 static irqreturn_t xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
 {
-       xgbe_an_isr_task(&pdata->tasklet_an);
+       xgbe_an_isr_bh_work(&pdata->an_bh_work);
 
        return IRQ_HANDLED;
 }
@@ -1454,7 +1454,7 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
 
        if (pdata->dev_irq != pdata->an_irq) {
                devm_free_irq(pdata->dev, pdata->an_irq, pdata);
-               tasklet_kill(&pdata->tasklet_an);
+               cancel_work_sync(&pdata->an_bh_work);
        }
 
        pdata->phy_if.phy_impl.stop(pdata);
@@ -1477,7 +1477,7 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
 
        /* If we have a separate AN irq, enable it */
        if (pdata->dev_irq != pdata->an_irq) {
-               tasklet_setup(&pdata->tasklet_an, xgbe_an_isr_task);
+               INIT_WORK(&pdata->an_bh_work, xgbe_an_isr_bh_work);
 
                ret = devm_request_irq(pdata->dev, pdata->an_irq,
                                       xgbe_an_isr, 0, pdata->an_name,
index c5e5fac49779e52398db4bf2a2baa6d2395968c8..c636999a6a8491460d6060d3a6392bd93b0e1f92 100644 (file)
@@ -139,7 +139,7 @@ static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
                return ret;
        }
 
-       pdata->isr_as_tasklet = 1;
+       pdata->isr_as_bh_work = 1;
        pdata->irq_count = ret;
 
        pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
@@ -176,7 +176,7 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
                return ret;
        }
 
-       pdata->isr_as_tasklet = pdata->pcidev->msi_enabled ? 1 : 0;
+       pdata->isr_as_bh_work = pdata->pcidev->msi_enabled ? 1 : 0;
        pdata->irq_count = 1;
        pdata->channel_irq_count = 1;
 
index f01a1e566da676d8adbea84cffeefa94f28f6fd7..d85386cac8d1669c2ad5f6ecc020c35bea9d9107 100644 (file)
@@ -1298,11 +1298,11 @@ struct xgbe_prv_data {
 
        unsigned int lpm_ctrl;          /* CTRL1 for resume */
 
-       unsigned int isr_as_tasklet;
-       struct tasklet_struct tasklet_dev;
-       struct tasklet_struct tasklet_ecc;
-       struct tasklet_struct tasklet_i2c;
-       struct tasklet_struct tasklet_an;
+       unsigned int isr_as_bh_work;
+       struct work_struct dev_bh_work;
+       struct work_struct ecc_bh_work;
+       struct work_struct i2c_bh_work;
+       struct work_struct an_bh_work;
 
        struct dentry *xgbe_debugfs;