From 5dca7d991922f9033e03428e742307e1d229f7d1 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Mon, 1 Apr 2024 15:16:19 -0700 Subject: [PATCH 1/2] dsc-drivers: update ionic drivers to 24.03.4-002 Under a large scale use we found that the check for a missed doorbell was taking too much CPU, so we reworked the check to use a per-device timer rather than a per-queue timer. Internal patches: ionic: remove missed doorbell per-queue timer ionic: add per-device doorbell timer ionic: tighter test for active napi ionic: platform doorbell timer setup Signed-off-by: Shannon Nelson --- README.md | 7 ++- drivers/linux/Makefile | 2 +- drivers/linux/eth/ionic/ionic.h | 1 + drivers/linux/eth/ionic/ionic_bus_pci.c | 4 ++ drivers/linux/eth/ionic/ionic_bus_platform.c | 4 ++ drivers/linux/eth/ionic/ionic_dev.c | 25 ++++++-- drivers/linux/eth/ionic/ionic_dev.h | 3 +- drivers/linux/eth/ionic/ionic_lif.c | 66 +++++++++++++------- drivers/linux/eth/ionic/ionic_lif.h | 2 +- drivers/linux/eth/ionic/ionic_txrx.c | 25 +++----- 10 files changed, 92 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 9c37191..f964393 100644 --- a/README.md +++ b/README.md @@ -195,12 +195,15 @@ As usual, if the Linux headers are elsewhere, add the appropriate -C magic: - fix 16bit math issue when PAGE_SIZE >= 64KB - restrict page-cache allocation to Rx queues -23-12-14 - driver update for 23.12.2-001 +2023-12-14 - driver update for 23.12.2-001 - updates from upstream kernel fixes - updates to FLR handling - added AER error handling -24-03-19 - driver update for 24.03.1-002 +2024-03-19 - driver update for 24.03.1-002 - Add XDP support - Refactor Tx and Rx fast paths for performance - Refactor struct sizes, layout, and usage for memory savings and performance + +2024-04-03 - driver update for 24.03.4-002 + - Fix to reduce impact of missed doorbell workaround diff --git a/drivers/linux/Makefile b/drivers/linux/Makefile index a255f86..d98fd56 100644 --- a/drivers/linux/Makefile +++ b/drivers/linux/Makefile @@ -69,7 +69,7 @@ ALL = eth endif ifeq ($(DVER),) - DVER = "24.03.1-002" + DVER = "24.03.4-002" endif KCFLAGS += -Ddrv_ver=\\\"$(DVER)\\\" diff --git a/drivers/linux/eth/ionic/ionic.h b/drivers/linux/eth/ionic/ionic.h index 06db8be..708efd2 100644 --- a/drivers/linux/eth/ionic/ionic.h +++ b/drivers/linux/eth/ionic/ionic.h @@ -80,6 +80,7 @@ struct ionic { struct rw_semaphore vf_op_lock; /* lock for VF operations */ struct ionic_vf *vfs; int num_vfs; + struct timer_list doorbell_timer; struct timer_list watchdog_timer; int watchdog_period; }; diff --git a/drivers/linux/eth/ionic/ionic_bus_pci.c b/drivers/linux/eth/ionic/ionic_bus_pci.c index 50b49c7..75e1262 100644 --- a/drivers/linux/eth/ionic/ionic_bus_pci.c +++ b/drivers/linux/eth/ionic/ionic_bus_pci.c @@ -438,6 +438,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_deregister_devlink; } + mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE); mod_timer(&ionic->watchdog_timer, round_jiffies(jiffies + ionic->watchdog_period)); @@ -470,6 +471,7 @@ static void ionic_remove(struct pci_dev *pdev) if (ionic->lif) set_bit(IONIC_LIF_F_IN_SHUTDOWN, ionic->lif->state); + del_timer_sync(&ionic->doorbell_timer); del_timer_sync(&ionic->watchdog_timer); if (ionic->lif) { @@ -509,6 +511,7 @@ void ionic_reset_prepare(struct pci_dev *pdev) * scheduled and render these del/cancel calls useless (i.e. don't mix * device triggered resets with userspace triggered resets). */ + del_timer_sync(&ionic->doorbell_timer); del_timer_sync(&ionic->watchdog_timer); mutex_lock(&lif->queue_lock); @@ -542,6 +545,7 @@ void ionic_reset_done(struct pci_dev *pdev) if (err) goto err_out; + mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE); mod_timer(&ionic->watchdog_timer, jiffies + 1); err_out: diff --git a/drivers/linux/eth/ionic/ionic_bus_platform.c b/drivers/linux/eth/ionic/ionic_bus_platform.c index c057a75..7c61fd2 100644 --- a/drivers/linux/eth/ionic/ionic_bus_platform.c +++ b/drivers/linux/eth/ionic/ionic_bus_platform.c @@ -222,6 +222,8 @@ static int ionic_mnic_dev_setup(struct ionic *ionic) return -EFAULT; ionic_init_devinfo(ionic); + + timer_setup(&ionic->doorbell_timer, ionic_doorbell_cb, 0); ionic_watchdog_init(ionic); idev->db_pages = ionic->bars[IONIC_DOORBELL_BAR].vaddr; @@ -403,6 +405,7 @@ int ionic_probe(struct platform_device *pfdev) goto err_out_deinit_lifs; } + mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE); mod_timer(&ionic->watchdog_timer, round_jiffies(jiffies + ionic->watchdog_period)); @@ -430,6 +433,7 @@ int ionic_remove(struct platform_device *pfdev) struct ionic *ionic = platform_get_drvdata(pfdev); if (ionic) { + del_timer_sync(&ionic->doorbell_timer); del_timer_sync(&ionic->watchdog_timer); ionic_lif_unregister(ionic->lif); ionic_lif_deinit(ionic->lif); diff --git a/drivers/linux/eth/ionic/ionic_dev.c b/drivers/linux/eth/ionic/ionic_dev.c index e212a57..01ca30d 100644 --- a/drivers/linux/eth/ionic/ionic_dev.c +++ b/drivers/linux/eth/ionic/ionic_dev.c @@ -73,6 +73,26 @@ void ionic_watchdog_init(struct ionic *ionic) ioread8(&idev->dev_info_regs->fw_status); } +void ionic_doorbell_cb(struct timer_list *timer) +{ + struct ionic *ionic = container_of(timer, struct ionic, doorbell_timer); + struct ionic_lif *lif = ionic->lif; + struct ionic_deferred_work *work; + + if (test_bit(IONIC_LIF_F_IN_SHUTDOWN, lif->state)) + return; + + if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) { + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (work) { + work->type = IONIC_DW_TYPE_DOORBELL; + ionic_lif_deferred_enqueue(&lif->deferred, work); + } + } + + mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE); +} + void ionic_init_devinfo(struct ionic *ionic) { struct ionic_dev *idev = &ionic->idev; @@ -137,6 +157,7 @@ int ionic_dev_setup(struct ionic *ionic) return -EFAULT; } + timer_setup(&ionic->doorbell_timer, ionic_doorbell_cb, 0); ionic_watchdog_init(ionic); idev->db_pages = bar->vaddr; @@ -724,10 +745,6 @@ void ionic_q_post(struct ionic_queue *q, bool ring_doorbell) q->dbval | q->head_idx); q->dbell_jiffies = jiffies; - - if (q_to_qcq(q)->napi_qcq) - mod_timer(&q_to_qcq(q)->napi_qcq->napi_deadline, - jiffies + IONIC_NAPI_DEADLINE); } } diff --git a/drivers/linux/eth/ionic/ionic_dev.h b/drivers/linux/eth/ionic/ionic_dev.h index 9f15d08..b4cbbb2 100644 --- a/drivers/linux/eth/ionic/ionic_dev.h +++ b/drivers/linux/eth/ionic/ionic_dev.h @@ -33,7 +33,7 @@ #define IONIC_DEV_INFO_REG_COUNT 32 #define IONIC_DEV_CMD_REG_COUNT 32 -#define IONIC_NAPI_DEADLINE (HZ / 200) /* 5ms */ +#define IONIC_NAPI_DEADLINE (HZ / 50) /* 20ms */ #define IONIC_ADMIN_DOORBELL_DEADLINE (HZ / 2) /* 500ms */ #define IONIC_TX_DOORBELL_DEADLINE (HZ / 100) /* 10ms */ #define IONIC_RX_MIN_DOORBELL_DEADLINE (HZ / 100) /* 10ms */ @@ -423,6 +423,7 @@ bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos); int ionic_heartbeat_check(struct ionic *ionic); bool ionic_is_fw_running(struct ionic_dev *idev); +void ionic_doorbell_cb(struct timer_list *timer); void ionic_watchdog_cb(struct timer_list *t); void ionic_watchdog_init(struct ionic *ionic); diff --git a/drivers/linux/eth/ionic/ionic_lif.c b/drivers/linux/eth/ionic/ionic_lif.c index 91454ef..2eaa01c 100644 --- a/drivers/linux/eth/ionic/ionic_lif.c +++ b/drivers/linux/eth/ionic/ionic_lif.c @@ -87,6 +87,42 @@ static void ionic_dim_work(struct work_struct *work) dim->state = DIM_START_MEASURE; } +static void ionic_doorbell_check(struct ionic_lif *lif) +{ + if (test_bit(IONIC_LIF_F_FW_RESET, lif->state) || + test_bit(IONIC_LIF_F_IN_SHUTDOWN, lif->state)) + return; + + mutex_lock(&lif->queue_lock); + + napi_schedule(&lif->adminqcq->napi); + + if (test_bit(IONIC_LIF_F_UP, lif->state)) { + int i; + + for (i = 0; i < lif->nxqs; i++) { + struct ionic_qcq *qcq; + + qcq = lif->txqcqs[i]; + if (qcq->flags & IONIC_QCQ_F_INTR) + napi_schedule(&qcq->napi); + + qcq = lif->rxqcqs[i]; + if (qcq->flags & IONIC_QCQ_F_INTR) + napi_schedule(&qcq->napi); + } + + if (lif->hwstamp_txq && + lif->hwstamp_txq->flags & IONIC_QCQ_F_INTR) + napi_schedule(&lif->hwstamp_txq->napi); + if (lif->hwstamp_rxq && + lif->hwstamp_rxq->flags & IONIC_QCQ_F_INTR) + napi_schedule(&lif->hwstamp_rxq->napi); + + } + mutex_unlock(&lif->queue_lock); +} + static void ionic_lif_deferred_work(struct work_struct *work) { struct ionic_lif *lif = container_of(work, struct ionic_lif, deferred.work); @@ -112,6 +148,9 @@ static void ionic_lif_deferred_work(struct work_struct *work) case IONIC_DW_TYPE_LINK_STATUS: ionic_link_status_check(lif); break; + case IONIC_DW_TYPE_DOORBELL: + ionic_doorbell_check(lif); + break; case IONIC_DW_TYPE_LIF_RESET: if (w->fw_status) { ionic_lif_handle_fw_up(lif); @@ -223,13 +262,6 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep) } } -static void ionic_napi_deadline(struct timer_list *timer) -{ - struct ionic_qcq *qcq = container_of(timer, struct ionic_qcq, napi_deadline); - - napi_schedule(&qcq->napi); -} - static irqreturn_t ionic_isr(int irq, void *data) { struct napi_struct *napi = data; @@ -347,7 +379,6 @@ static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int f if (qcq->napi.poll) { napi_disable(&qcq->napi); - del_timer_sync(&qcq->napi_deadline); synchronize_net(); } @@ -898,7 +929,6 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) { netif_napi_add(lif->netdev, &qcq->napi, ionic_tx_napi); qcq->napi_qcq = qcq; - timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0); } qcq->flags |= IONIC_QCQ_F_INITED; @@ -978,7 +1008,6 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) netif_napi_add(lif->netdev, &qcq->napi, ionic_txrx_napi); qcq->napi_qcq = qcq; - timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0); qcq->flags |= IONIC_QCQ_F_INITED; @@ -1234,7 +1263,6 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) struct ionic_dev *idev = &lif->ionic->idev; unsigned long irqflags; unsigned int flags = 0; - bool resched = false; int rx_work = 0; int tx_work = 0; int n_work = 0; @@ -1271,15 +1299,12 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) ionic_intr_credits(idev->intr_ctrl, intr->index, credits, flags); } - if (!a_work && ionic_adminq_poke_doorbell(&lif->adminqcq->q)) - resched = true; - if (lif->hwstamp_rxq && !rx_work && ionic_rxq_poke_doorbell(&lif->hwstamp_rxq->q)) - resched = true; - if (lif->hwstamp_txq && !tx_work && ionic_txq_poke_doorbell(&lif->hwstamp_txq->q)) - resched = true; - if (resched) - mod_timer(&lif->adminqcq->napi_deadline, - jiffies + IONIC_NAPI_DEADLINE); + if (!a_work) + ionic_adminq_poke_doorbell(&lif->adminqcq->q); + if (lif->hwstamp_rxq && !rx_work) + ionic_rxq_poke_doorbell(&lif->hwstamp_rxq->q); + if (lif->hwstamp_txq && !tx_work) + ionic_txq_poke_doorbell(&lif->hwstamp_txq->q); return work_done; } @@ -3761,7 +3786,6 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif) netif_napi_add(lif->netdev, &qcq->napi, ionic_adminq_napi); qcq->napi_qcq = qcq; - timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0); napi_enable(&qcq->napi); diff --git a/drivers/linux/eth/ionic/ionic_lif.h b/drivers/linux/eth/ionic/ionic_lif.h index 5e60539..1b869ce 100644 --- a/drivers/linux/eth/ionic/ionic_lif.h +++ b/drivers/linux/eth/ionic/ionic_lif.h @@ -120,7 +120,6 @@ struct ionic_qcq { u32 cmb_order; bool armed; struct dim dim; - struct timer_list napi_deadline; struct ionic_queue q; struct ionic_cq cq; struct napi_struct napi; @@ -142,6 +141,7 @@ enum ionic_deferred_work_type { IONIC_DW_TYPE_RX_MODE, IONIC_DW_TYPE_LINK_STATUS, IONIC_DW_TYPE_LIF_RESET, + IONIC_DW_TYPE_DOORBELL, }; struct ionic_deferred_work { diff --git a/drivers/linux/eth/ionic/ionic_txrx.c b/drivers/linux/eth/ionic/ionic_txrx.c index 503b632..808f7cf 100644 --- a/drivers/linux/eth/ionic/ionic_txrx.c +++ b/drivers/linux/eth/ionic/ionic_txrx.c @@ -1022,12 +1022,6 @@ void ionic_rx_fill(struct ionic_queue *q) ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type, q->dbval | q->head_idx); - - q->dbell_deadline = IONIC_RX_MIN_DOORBELL_DEADLINE; - q->dbell_jiffies = jiffies; - - mod_timer(&q_to_qcq(q)->napi_qcq->napi_deadline, - jiffies + IONIC_NAPI_DEADLINE); } void ionic_rx_empty(struct ionic_queue *q) @@ -1112,8 +1106,8 @@ int ionic_tx_napi(struct napi_struct *napi, int budget) work_done, flags); } - if (!work_done && ionic_txq_poke_doorbell(&qcq->q)) - mod_timer(&qcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE); + if (!work_done) + ionic_txq_poke_doorbell(&qcq->q); DEBUG_STATS_NAPI_POLL(qcq, work_done); @@ -1159,8 +1153,8 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) work_done, flags); } - if (!work_done && ionic_rxq_poke_doorbell(&qcq->q)) - mod_timer(&qcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE); + if (!work_done) + ionic_rxq_poke_doorbell(&qcq->q); DEBUG_STATS_NAPI_POLL(qcq, work_done); @@ -1175,7 +1169,6 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) struct ionic_qcq *txqcq; struct ionic_lif *lif; struct ionic_cq *txcq; - bool resched = false; u32 rx_work_done = 0; u32 tx_work_done = 0; u32 flags = 0; @@ -1210,12 +1203,10 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) DEBUG_STATS_NAPI_POLL(rxqcq, rx_work_done); DEBUG_STATS_NAPI_POLL(txqcq, tx_work_done); - if (!rx_work_done && ionic_rxq_poke_doorbell(&rxqcq->q)) - resched = true; - if (!tx_work_done && ionic_txq_poke_doorbell(&txqcq->q)) - resched = true; - if (resched) - mod_timer(&rxqcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE); + if (!rx_work_done) + ionic_rxq_poke_doorbell(&rxqcq->q); + if (!tx_work_done) + ionic_txq_poke_doorbell(&txqcq->q); return rx_work_done; } From 3690c6beeeffef4710d2eeb312ba7bac7ac3e762 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 16 Apr 2024 09:58:03 -0700 Subject: [PATCH 2/2] dsc-drivers: udpate ionic drivers to 24.03.4-003 A little bit of code cleanup, plus a fix to move the missed doorbell handling to the cpu last used by the AdminQ napi. Internal patches: ionic: fix up a few bits left from doorbell fix fix ionic: push work items to adminq CPU ionic: back off doorbell check timer Signed-off-by: Shannon Nelson --- README.md | 3 +++ drivers/linux/Makefile | 2 +- drivers/linux/eth/ionic/ionic_debugfs.c | 12 +++++++++++ drivers/linux/eth/ionic/ionic_dev.c | 8 +++---- drivers/linux/eth/ionic/ionic_lif.c | 28 +++++++++++++------------ drivers/linux/eth/ionic/ionic_lif.h | 5 +++-- drivers/linux/eth/ionic/ionic_main.c | 2 +- drivers/linux/eth/ionic/ionic_txrx.c | 3 +++ 8 files changed, 42 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index f964393..909149f 100644 --- a/README.md +++ b/README.md @@ -207,3 +207,6 @@ As usual, if the Linux headers are elsewhere, add the appropriate -C magic: 2024-04-03 - driver update for 24.03.4-002 - Fix to reduce impact of missed doorbell workaround + +24-04-16 - driver update for 24.03.4-003 + - Doorbell workaround now uses AdminQ's last used cpu diff --git a/drivers/linux/Makefile b/drivers/linux/Makefile index d98fd56..6bc26a4 100644 --- a/drivers/linux/Makefile +++ b/drivers/linux/Makefile @@ -69,7 +69,7 @@ ALL = eth endif ifeq ($(DVER),) - DVER = "24.03.4-002" + DVER = "24.03.4-003" endif KCFLAGS += -Ddrv_ver=\\\"$(DVER)\\\" diff --git a/drivers/linux/eth/ionic/ionic_debugfs.c b/drivers/linux/eth/ionic/ionic_debugfs.c index 4a3b568..cb0f08a 100644 --- a/drivers/linux/eth/ionic/ionic_debugfs.c +++ b/drivers/linux/eth/ionic/ionic_debugfs.c @@ -519,6 +519,16 @@ static int lif_n_txrx_alloc_show(struct seq_file *seq, void *v) } DEFINE_SHOW_ATTRIBUTE(lif_n_txrx_alloc); +static int lif_adminq_cpu_show(struct seq_file *seq, void *v) +{ + struct ionic_lif *lif = seq->private; + + seq_printf(seq, "%u\n", lif->adminq_cpu); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(lif_adminq_cpu); + void ionic_debugfs_add_lif(struct ionic_lif *lif) { struct dentry *lif_dentry; @@ -538,6 +548,8 @@ void ionic_debugfs_add_lif(struct ionic_lif *lif) lif, &lif_filters_fops); debugfs_create_file("txrx_alloc", 0400, lif->dentry, lif, &lif_n_txrx_alloc_fops); + debugfs_create_file("adminq_cpu", 0400, lif->dentry, + lif, &lif_adminq_cpu_fops); } void ionic_debugfs_del_lif(struct ionic_lif *lif) diff --git a/drivers/linux/eth/ionic/ionic_dev.c b/drivers/linux/eth/ionic/ionic_dev.c index 01ca30d..29f9948 100644 --- a/drivers/linux/eth/ionic/ionic_dev.c +++ b/drivers/linux/eth/ionic/ionic_dev.c @@ -48,7 +48,7 @@ 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, &lif->deferred, work); } } @@ -86,11 +86,11 @@ void ionic_doorbell_cb(struct timer_list *timer) work = kzalloc(sizeof(*work), GFP_ATOMIC); if (work) { work->type = IONIC_DW_TYPE_DOORBELL; - ionic_lif_deferred_enqueue(&lif->deferred, work); + ionic_lif_deferred_enqueue(lif, &lif->deferred, work); } } - mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE); + mod_timer(&ionic->doorbell_timer, jiffies + IONIC_ADMIN_DOORBELL_DEADLINE); } void ionic_init_devinfo(struct ionic *ionic) @@ -302,7 +302,7 @@ int ionic_heartbeat_check(struct ionic *ionic) 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, &lif->deferred, work); } } } diff --git a/drivers/linux/eth/ionic/ionic_lif.c b/drivers/linux/eth/ionic/ionic_lif.c index 2eaa01c..986106c 100644 --- a/drivers/linux/eth/ionic/ionic_lif.c +++ b/drivers/linux/eth/ionic/ionic_lif.c @@ -118,7 +118,6 @@ static void ionic_doorbell_check(struct ionic_lif *lif) if (lif->hwstamp_rxq && lif->hwstamp_rxq->flags & IONIC_QCQ_F_INTR) napi_schedule(&lif->hwstamp_rxq->napi); - } mutex_unlock(&lif->queue_lock); } @@ -173,13 +172,14 @@ 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 *def, 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); + schedule_work_on(lif->adminq_cpu, &def->work); } static void ionic_link_status_check(struct ionic_lif *lif) @@ -256,7 +256,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, &lif->deferred, work); } else { ionic_link_status_check(lif); } @@ -534,7 +534,6 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq, n_qcq->intr.vector = src_qcq->intr.vector; n_qcq->intr.index = src_qcq->intr.index; - n_qcq->napi_qcq = src_qcq->napi_qcq; } static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qcq) @@ -926,10 +925,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) q->dbell_deadline = IONIC_TX_DOORBELL_DEADLINE; q->dbell_jiffies = jiffies; - if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) { + if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) netif_napi_add(lif->netdev, &qcq->napi, ionic_tx_napi); - qcq->napi_qcq = qcq; - } qcq->flags |= IONIC_QCQ_F_INITED; @@ -1007,8 +1004,6 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) else netif_napi_add(lif->netdev, &qcq->napi, ionic_txrx_napi); - qcq->napi_qcq = qcq; - qcq->flags |= IONIC_QCQ_F_INITED; return 0; @@ -1306,6 +1301,8 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) if (lif->hwstamp_txq && !tx_work) ionic_txq_poke_doorbell(&lif->hwstamp_txq->q); + lif->adminq_cpu = smp_processor_id(); + return work_done; } @@ -1488,7 +1485,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, &lif->deferred, work); } static __le64 ionic_netdev_features_to_nic(netdev_features_t features) @@ -3785,8 +3782,6 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif) netif_napi_add(lif->netdev, &qcq->napi, ionic_adminq_napi); - qcq->napi_qcq = qcq; - napi_enable(&qcq->napi); if (qcq->flags & IONIC_QCQ_F_INTR) { @@ -3798,6 +3793,13 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif) qcq->flags |= IONIC_QCQ_F_INITED; + /* Start the tracking with the current cpu rather than the + * default 0 starting place. This helps spread the scheduled + * work item load when VFs are brought up on multiple PFs by + * userland commands that will be on various cpus. + */ + lif->adminq_cpu = smp_processor_id(); + return 0; } diff --git a/drivers/linux/eth/ionic/ionic_lif.h b/drivers/linux/eth/ionic/ionic_lif.h index 1b869ce..3bca6ee 100644 --- a/drivers/linux/eth/ionic/ionic_lif.h +++ b/drivers/linux/eth/ionic/ionic_lif.h @@ -123,7 +123,6 @@ struct ionic_qcq { struct ionic_queue q; struct ionic_cq cq; struct napi_struct napi; - struct ionic_qcq *napi_qcq; struct ionic_intr_info intr; #ifdef IONIC_DEBUG_STATS struct ionic_napi_stats napi_stats; @@ -270,6 +269,7 @@ struct ionic_lif { unsigned int index; unsigned int hw_index; unsigned int link_down_count; + unsigned int adminq_cpu; u8 rss_hash_key[IONIC_RSS_HASH_KEY_SIZE]; u8 *rss_ind_tbl; @@ -408,7 +408,8 @@ static inline bool ionic_txq_hwstamp_enabled(struct ionic_queue *q) return q->features & IONIC_TXQ_F_HWSTAMP; } -void ionic_lif_deferred_enqueue(struct ionic_deferred *def, +void ionic_lif_deferred_enqueue(struct ionic_lif *lif, + struct ionic_deferred *def, struct ionic_deferred_work *work); void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep); #ifdef HAVE_VOID_NDO_GET_STATS64 diff --git a/drivers/linux/eth/ionic/ionic_main.c b/drivers/linux/eth/ionic/ionic_main.c index a655b7f..4a71e82 100644 --- a/drivers/linux/eth/ionic/ionic_main.c +++ b/drivers/linux/eth/ionic/ionic_main.c @@ -324,7 +324,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, &lif->deferred, work); } } break; diff --git a/drivers/linux/eth/ionic/ionic_txrx.c b/drivers/linux/eth/ionic/ionic_txrx.c index 808f7cf..ef02b8f 100644 --- a/drivers/linux/eth/ionic/ionic_txrx.c +++ b/drivers/linux/eth/ionic/ionic_txrx.c @@ -1022,6 +1022,9 @@ void ionic_rx_fill(struct ionic_queue *q) ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type, q->dbval | q->head_idx); + + q->dbell_deadline = IONIC_RX_MIN_DOORBELL_DEADLINE; + q->dbell_jiffies = jiffies; } void ionic_rx_empty(struct ionic_queue *q)