diff options
| author | Shannon Nelson <shannon.nelson@amd.com> | 2024-06-18 17:32:53 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2024-06-19 18:31:48 -0700 |
| commit | 4ded136c78f8ae17d140b8aae3cd4459a6827577 (patch) | |
| tree | 174218ccd4d3b401b073a5655742e66bea281f47 /drivers/net/ethernet/pensando/ionic/ionic_dev.c | |
| parent | ionic: add private workqueue per-device (diff) | |
| download | linux-4ded136c78f8ae17d140b8aae3cd4459a6827577.tar.gz linux-4ded136c78f8ae17d140b8aae3cd4459a6827577.zip | |
ionic: add work item for missed-doorbell check
Add the first queued work for checking on the missed doorbell.
This is a delayed work item that reschedules itself every cycle
starting at probe.
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Link: https://lore.kernel.org/r/20240619003257.6138-5-shannon.nelson@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/pensando/ionic/ionic_dev.c')
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index 342863fd0b16..5d5990e7376e 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -47,6 +47,61 @@ static void ionic_watchdog_cb(struct timer_list *t) } } +static void ionic_napi_schedule_do_softirq(struct napi_struct *napi) +{ + local_bh_disable(); + napi_schedule(napi); + local_bh_enable(); +} + +static int ionic_get_preferred_cpu(struct ionic *ionic, + struct ionic_intr_info *intr) +{ + int cpu; + + cpu = cpumask_first_and(*intr->affinity_mask, cpu_online_mask); + if (cpu >= nr_cpu_ids) + cpu = cpumask_local_spread(0, dev_to_node(ionic->dev)); + + return cpu; +} + +static void ionic_doorbell_check_dwork(struct work_struct *work) +{ + struct ionic *ionic = container_of(work, struct ionic, + doorbell_check_dwork.work); + struct ionic_lif *lif = ionic->lif; + + mutex_lock(&lif->queue_lock); + + if (test_bit(IONIC_LIF_F_FW_STOPPING, lif->state) || + test_bit(IONIC_LIF_F_FW_RESET, lif->state)) { + mutex_unlock(&lif->queue_lock); + return; + } + + ionic_napi_schedule_do_softirq(&lif->adminqcq->napi); + + if (test_bit(IONIC_LIF_F_UP, lif->state)) { + int i; + + for (i = 0; i < lif->nxqs; i++) { + ionic_napi_schedule_do_softirq(&lif->txqcqs[i]->napi); + ionic_napi_schedule_do_softirq(&lif->rxqcqs[i]->napi); + } + + if (lif->hwstamp_txq && + lif->hwstamp_txq->flags & IONIC_QCQ_F_INTR) + ionic_napi_schedule_do_softirq(&lif->hwstamp_txq->napi); + if (lif->hwstamp_rxq && + lif->hwstamp_rxq->flags & IONIC_QCQ_F_INTR) + ionic_napi_schedule_do_softirq(&lif->hwstamp_rxq->napi); + } + mutex_unlock(&lif->queue_lock); + + ionic_queue_doorbell_check(ionic, IONIC_NAPI_DEADLINE); +} + static int ionic_watchdog_init(struct ionic *ionic) { struct ionic_dev *idev = &ionic->idev; @@ -70,10 +125,21 @@ static int ionic_watchdog_init(struct ionic *ionic) dev_err(ionic->dev, "alloc_workqueue failed"); return -ENOMEM; } + INIT_DELAYED_WORK(&ionic->doorbell_check_dwork, + ionic_doorbell_check_dwork); return 0; } +void ionic_queue_doorbell_check(struct ionic *ionic, int delay) +{ + int cpu; + + cpu = ionic_get_preferred_cpu(ionic, &ionic->lif->adminqcq->intr); + queue_delayed_work_on(cpu, ionic->wq, &ionic->doorbell_check_dwork, + delay); +} + void ionic_init_devinfo(struct ionic *ionic) { struct ionic_dev *idev = &ionic->idev; |
