ionic: add private workqueue per-device
authorShannon Nelson <shannon.nelson@amd.com>
Wed, 19 Jun 2024 00:32:52 +0000 (17:32 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 20 Jun 2024 01:31:48 +0000 (18:31 -0700)
Instead of using the system's default workqueue, add a private
workqueue for the device to use for its little jobs.  This is
to better support the new work items we will be adding in the
next patches for PF and VF specific jobs, without inundating
the system workqueue in a couple of customer cases where our
devices get scaled out to 100-200 VFs.

Signed-off-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Link: https://lore.kernel.org/r/20240619003257.6138-4-shannon.nelson@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/pensando/ionic/ionic.h
drivers/net/ethernet/pensando/ionic/ionic_dev.c
drivers/net/ethernet/pensando/ionic/ionic_lif.c
drivers/net/ethernet/pensando/ionic/ionic_lif.h
drivers/net/ethernet/pensando/ionic/ionic_main.c

index 438172cfb1703d9a2e6420dfb2adf26574a03a6f..df29c977a702ad8cb6a50de6d5997a338fe649b1 100644 (file)
@@ -47,6 +47,7 @@ struct ionic {
        struct ionic_dev_bar bars[IONIC_BARS_MAX];
        unsigned int num_bars;
        struct ionic_identity ident;
+       struct workqueue_struct *wq;
        struct ionic_lif *lif;
        unsigned int nnqs_per_lif;
        unsigned int neqs_per_lif;
index 89b4310f244c4740fdaecaaf84343f099d49d872..342863fd0b165fee04e40ba30e0bb0ae7593bfb7 100644 (file)
@@ -43,11 +43,11 @@ static void ionic_watchdog_cb(struct timer_list *t)
 
                work->type = IONIC_DW_TYPE_RX_MODE;
                netdev_dbg(lif->netdev, "deferred: rx_mode\n");
-               ionic_lif_deferred_enqueue(&lif->deferred, work);
+               ionic_lif_deferred_enqueue(lif, work);
        }
 }
 
-static void ionic_watchdog_init(struct ionic *ionic)
+static int ionic_watchdog_init(struct ionic *ionic)
 {
        struct ionic_dev *idev = &ionic->idev;
 
@@ -63,6 +63,15 @@ static void ionic_watchdog_init(struct ionic *ionic)
        idev->fw_status_ready = true;
        idev->fw_generation = IONIC_FW_STS_F_GENERATION &
                              ioread8(&idev->dev_info_regs->fw_status);
+
+       ionic->wq = alloc_workqueue("%s-wq", WQ_UNBOUND, 0,
+                                   dev_name(ionic->dev));
+       if (!ionic->wq) {
+               dev_err(ionic->dev, "alloc_workqueue failed");
+               return -ENOMEM;
+       }
+
+       return 0;
 }
 
 void ionic_init_devinfo(struct ionic *ionic)
@@ -94,6 +103,7 @@ int ionic_dev_setup(struct ionic *ionic)
        struct device *dev = ionic->dev;
        int size;
        u32 sig;
+       int err;
 
        /* BAR0: dev_cmd and interrupts */
        if (num_bars < 1) {
@@ -129,7 +139,9 @@ int ionic_dev_setup(struct ionic *ionic)
                return -EFAULT;
        }
 
-       ionic_watchdog_init(ionic);
+       err = ionic_watchdog_init(ionic);
+       if (err)
+               return err;
 
        idev->db_pages = bar->vaddr;
        idev->phy_db_pages = bar->bus_addr;
@@ -161,6 +173,7 @@ void ionic_dev_teardown(struct ionic *ionic)
        idev->phy_cmb_pages = 0;
        idev->cmb_npages = 0;
 
+       destroy_workqueue(ionic->wq);
        mutex_destroy(&idev->cmb_inuse_lock);
 }
 
@@ -273,7 +286,7 @@ do_check_time:
                        if (work) {
                                work->type = IONIC_DW_TYPE_LIF_RESET;
                                work->fw_status = fw_status_ready;
-                               ionic_lif_deferred_enqueue(&lif->deferred, work);
+                               ionic_lif_deferred_enqueue(lif, work);
                        }
                }
        }
index 46cb143b5941eca25959d8296270259c017cf0fa..2882517f26fbb7135029929e528de966fd88bcf7 100644 (file)
@@ -126,13 +126,13 @@ static void ionic_lif_deferred_work(struct work_struct *work)
        } while (true);
 }
 
-void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
+void ionic_lif_deferred_enqueue(struct ionic_lif *lif,
                                struct ionic_deferred_work *work)
 {
-       spin_lock_bh(&def->lock);
-       list_add_tail(&work->list, &def->list);
-       spin_unlock_bh(&def->lock);
-       schedule_work(&def->work);
+       spin_lock_bh(&lif->deferred.lock);
+       list_add_tail(&work->list, &lif->deferred.list);
+       spin_unlock_bh(&lif->deferred.lock);
+       queue_work(lif->ionic->wq, &lif->deferred.work);
 }
 
 static void ionic_link_status_check(struct ionic_lif *lif)
@@ -207,7 +207,7 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep)
                }
 
                work->type = IONIC_DW_TYPE_LINK_STATUS;
-               ionic_lif_deferred_enqueue(&lif->deferred, work);
+               ionic_lif_deferred_enqueue(lif, work);
        } else {
                ionic_link_status_check(lif);
        }
@@ -1389,7 +1389,7 @@ static void ionic_ndo_set_rx_mode(struct net_device *netdev)
        }
        work->type = IONIC_DW_TYPE_RX_MODE;
        netdev_dbg(lif->netdev, "deferred: rx_mode\n");
-       ionic_lif_deferred_enqueue(&lif->deferred, work);
+       ionic_lif_deferred_enqueue(lif, work);
 }
 
 static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
index a029206c0bc81dbd30728e8e455edb4cd089e8d5..e4a5ae70793eb3de26a8a83802ea2f06da8717e8 100644 (file)
@@ -331,7 +331,7 @@ static inline bool ionic_txq_hwstamp_enabled(struct ionic_queue *q)
 void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep);
 void ionic_get_stats64(struct net_device *netdev,
                       struct rtnl_link_stats64 *ns);
-void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
+void ionic_lif_deferred_enqueue(struct ionic_lif *lif,
                                struct ionic_deferred_work *work);
 int ionic_lif_alloc(struct ionic *ionic);
 int ionic_lif_init(struct ionic_lif *lif);
index c1259324b0be8115104cf964d2e43587e113136f..0f817c3f92d820a0193a956b21ba6a2937de35b5 100644 (file)
@@ -287,7 +287,7 @@ bool ionic_notifyq_service(struct ionic_cq *cq)
                                clear_bit(IONIC_LIF_F_FW_STOPPING, lif->state);
                        } else {
                                work->type = IONIC_DW_TYPE_LIF_RESET;
-                               ionic_lif_deferred_enqueue(&lif->deferred, work);
+                               ionic_lif_deferred_enqueue(lif, work);
                        }
                }
                break;