Commit 4ded136c authored by Shannon Nelson's avatar Shannon Nelson Committed by Jakub Kicinski
Browse files

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: default avatarShannon Nelson <shannon.nelson@amd.com>
Link: https://lore.kernel.org/r/20240619003257.6138-5-shannon.nelson@amd.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9e25450d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct ionic {
	unsigned int nintrs;
	DECLARE_BITMAP(intrs, IONIC_INTR_CTRL_REGS_MAX);
	cpumask_var_t *affinity_masks;
	struct delayed_work doorbell_check_dwork;
	struct work_struct nb_work;
	struct notifier_block nb;
	struct rw_semaphore vf_op_lock;	/* lock for VF operations */
+2 −0
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	mod_timer(&ionic->watchdog_timer,
		  round_jiffies(jiffies + ionic->watchdog_period));
	ionic_queue_doorbell_check(ionic, IONIC_NAPI_DEADLINE);

	return 0;

@@ -411,6 +412,7 @@ static void ionic_remove(struct pci_dev *pdev)
		if (test_and_clear_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state))
			set_bit(IONIC_LIF_F_FW_STOPPING, ionic->lif->state);

		cancel_delayed_work_sync(&ionic->doorbell_check_dwork);
		ionic_lif_unregister(ionic->lif);
		ionic_devlink_unregister(ionic);
		ionic_lif_deinit(ionic->lif);
+66 −0
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -28,7 +28,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)		/* 1 sec */
#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 */
@@ -386,6 +386,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_queue_doorbell_check(struct ionic *ionic, int delay);

bool ionic_adminq_poke_doorbell(struct ionic_queue *q);
bool ionic_txq_poke_doorbell(struct ionic_queue *q);
+2 −0
Original line number Diff line number Diff line
@@ -1191,6 +1191,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
	if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED)
		a_work = ionic_cq_service(&lif->adminqcq->cq, budget,
					  ionic_adminq_service, NULL, NULL);

	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);

	if (lif->hwstamp_rxq)
@@ -3406,6 +3407,7 @@ int ionic_restart_lif(struct ionic_lif *lif)
	clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
	ionic_link_status_check_request(lif, CAN_SLEEP);
	netif_device_attach(lif->netdev);
	ionic_queue_doorbell_check(ionic, IONIC_NAPI_DEADLINE);

	return 0;