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

ionic: add per-queue napi_schedule for doorbell check



Add a work item for each queue that will be run on the queue's
preferred cpu and will schedule another napi.  This napi is
run in case the device missed a doorbell and didn't process
a packet.  This is a problem for the Elba asic that happens
very rarely.

Signed-off-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Link: https://lore.kernel.org/r/20240619003257.6138-6-shannon.nelson@amd.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4ded136c
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -54,6 +54,13 @@ static void ionic_napi_schedule_do_softirq(struct napi_struct *napi)
	local_bh_enable();
}

void ionic_doorbell_napi_work(struct work_struct *work)
{
	struct ionic_qcq *qcq = container_of(work, struct ionic_qcq,
					     doorbell_napi_work);
	ionic_napi_schedule_do_softirq(&qcq->napi);
}

static int ionic_get_preferred_cpu(struct ionic *ionic,
				   struct ionic_intr_info *intr)
{
@@ -66,6 +73,18 @@ static int ionic_get_preferred_cpu(struct ionic *ionic,
	return cpu;
}

static void ionic_queue_dbell_napi_work(struct ionic *ionic,
					struct ionic_qcq *qcq)
{
	int cpu;

	if (!(qcq->flags & IONIC_QCQ_F_INTR))
		return;

	cpu = ionic_get_preferred_cpu(ionic, &qcq->intr);
	queue_work_on(cpu, ionic->wq, &qcq->doorbell_napi_work);
}

static void ionic_doorbell_check_dwork(struct work_struct *work)
{
	struct ionic *ionic = container_of(work, struct ionic,
@@ -86,8 +105,8 @@ static void ionic_doorbell_check_dwork(struct work_struct *work)
		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);
			ionic_queue_dbell_napi_work(ionic, lif->txqcqs[i]);
			ionic_queue_dbell_napi_work(ionic, lif->rxqcqs[i]);
		}

		if (lif->hwstamp_txq &&
+1 −0
Original line number Diff line number Diff line
@@ -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_doorbell_napi_work(struct work_struct *work);
void ionic_queue_doorbell_check(struct ionic *ionic, int delay);

bool ionic_adminq_poke_doorbell(struct ionic_queue *q);
+2 −0
Original line number Diff line number Diff line
@@ -344,6 +344,7 @@ static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int f
	if (qcq->flags & IONIC_QCQ_F_INTR) {
		struct ionic_dev *idev = &lif->ionic->idev;

		cancel_work_sync(&qcq->doorbell_napi_work);
		cancel_work_sync(&qcq->dim.work);
		ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
				IONIC_INTR_MASK_SET);
@@ -690,6 +691,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,

	INIT_WORK(&new->dim.work, ionic_dim_work);
	new->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE;
	INIT_WORK(&new->doorbell_napi_work, ionic_doorbell_napi_work);

	*qcq = new;

+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ struct ionic_qcq {
	struct ionic_cq cq;
	struct napi_struct napi;
	struct ionic_intr_info intr;
	struct work_struct doorbell_napi_work;
	struct dentry *dentry;
};