Commit b8189eeb authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'pds_core-various-improvements-cleanups'

Brett Creeley says:

====================
pds_core: Various improvements/cleanups

This series contains various improvements and cleanups for the
pds_core driver. These patches were originally part of the following
net-next series:

https://lore.kernel.org/netdev/20240126174255.17052-1-brett.creeley@amd.com/

However, some of the patches from the above series were actually fixes,
so they were pushed and accepted to net. That series can be found here:

https://lore.kernel.org/netdev/20240129234035.69802-1-brett.creeley@amd.com/

Also, the Reviewed-by tags were left in place from the original net-next
reviews as the patches didn't change.
====================

Link: https://lore.kernel.org/r/20240202195911.65338-1-brett.creeley@amd.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 240fd405 792d36cc
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)
	unsigned long irqflags;
	int nq_work = 0;
	int aq_work = 0;
	int credits;

	/* Don't process AdminQ when it's not up */
	if (!pdsc_adminq_inc_if_up(pdsc)) {
@@ -128,10 +127,8 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)

credits:
	/* Return the interrupt credits, one for each completion */
	credits = nq_work + aq_work;
	if (credits)
	pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx],
				      credits,
			      nq_work + aq_work,
			      PDS_CORE_INTR_CRED_REARM);
	refcount_dec(&pdsc->adminq_refcnt);
}
@@ -157,7 +154,6 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data)

	qcq = &pdsc->adminqcq;
	queue_work(pdsc->wq, &qcq->work);
	pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR);
	refcount_dec(&pdsc->adminq_refcnt);

	return IRQ_HANDLED;
+45 −47
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ static int pdsc_qcq_intr_alloc(struct pdsc *pdsc, struct pdsc_qcq *qcq)
	if (index < 0)
		return index;
	qcq->intx = index;
	qcq->cq.bound_intr = &pdsc->intr_info[index];

	return 0;
}
@@ -222,7 +223,6 @@ int pdsc_qcq_alloc(struct pdsc *pdsc, unsigned int type, unsigned int index,
		goto err_out_free_irq;
	}

	qcq->cq.bound_intr = &pdsc->intr_info[qcq->intx];
	qcq->cq.num_descs = num_descs;
	qcq->cq.desc_size = cq_desc_size;
	qcq->cq.tail_idx = 0;
@@ -300,6 +300,17 @@ int pdsc_qcq_alloc(struct pdsc *pdsc, unsigned int type, unsigned int index,
	return err;
}

static void pdsc_core_uninit(struct pdsc *pdsc)
{
	pdsc_qcq_free(pdsc, &pdsc->notifyqcq);
	pdsc_qcq_free(pdsc, &pdsc->adminqcq);

	if (pdsc->kern_dbpage) {
		iounmap(pdsc->kern_dbpage);
		pdsc->kern_dbpage = NULL;
	}
}

static int pdsc_core_init(struct pdsc *pdsc)
{
	union pds_core_dev_comp comp = {};
@@ -310,9 +321,32 @@ static int pdsc_core_init(struct pdsc *pdsc)
	struct pds_core_dev_init_data_in cidi;
	u32 dbid_count;
	u32 dbpage_num;
	int numdescs;
	size_t sz;
	int err;

	/* Scale the descriptor ring length based on number of CPUs and VFs */
	numdescs = max_t(int, PDSC_ADMINQ_MIN_LENGTH, num_online_cpus());
	numdescs += 2 * pci_sriov_get_totalvfs(pdsc->pdev);
	numdescs = roundup_pow_of_two(numdescs);
	err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq",
			     PDS_CORE_QCQ_F_CORE | PDS_CORE_QCQ_F_INTR,
			     numdescs,
			     sizeof(union pds_core_adminq_cmd),
			     sizeof(union pds_core_adminq_comp),
			     0, &pdsc->adminqcq);
	if (err)
		return err;

	err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_NOTIFYQ, 0, "notifyq",
			     PDS_CORE_QCQ_F_NOTIFYQ,
			     PDSC_NOTIFYQ_LENGTH,
			     sizeof(struct pds_core_notifyq_cmd),
			     sizeof(union pds_core_notifyq_comp),
			     0, &pdsc->notifyqcq);
	if (err)
		goto err_out_uninit;

	cidi.adminq_q_base = cpu_to_le64(pdsc->adminqcq.q_base_pa);
	cidi.adminq_cq_base = cpu_to_le64(pdsc->adminqcq.cq_base_pa);
	cidi.notifyq_cq_base = cpu_to_le64(pdsc->notifyqcq.cq.base_pa);
@@ -336,7 +370,7 @@ static int pdsc_core_init(struct pdsc *pdsc)
	if (err) {
		dev_err(pdsc->dev, "Device init command failed: %pe\n",
			ERR_PTR(err));
		return err;
		goto err_out_uninit;
	}

	pdsc->hw_index = le32_to_cpu(cido.core_hw_index);
@@ -346,7 +380,8 @@ static int pdsc_core_init(struct pdsc *pdsc)
	pdsc->kern_dbpage = pdsc_map_dbpage(pdsc, dbpage_num);
	if (!pdsc->kern_dbpage) {
		dev_err(pdsc->dev, "Cannot map dbpage, aborting\n");
		return -ENOMEM;
		err = -ENOMEM;
		goto err_out_uninit;
	}

	pdsc->adminqcq.q.hw_type = cido.adminq_hw_type;
@@ -359,6 +394,10 @@ static int pdsc_core_init(struct pdsc *pdsc)

	pdsc->last_eid = 0;

	return 0;

err_out_uninit:
	pdsc_core_uninit(pdsc);
	return err;
}

@@ -401,38 +440,12 @@ static int pdsc_viftypes_init(struct pdsc *pdsc)

int pdsc_setup(struct pdsc *pdsc, bool init)
{
	int numdescs;
	int err;

	err = pdsc_dev_init(pdsc);
	if (err)
		return err;

	/* Scale the descriptor ring length based on number of CPUs and VFs */
	numdescs = max_t(int, PDSC_ADMINQ_MIN_LENGTH, num_online_cpus());
	numdescs += 2 * pci_sriov_get_totalvfs(pdsc->pdev);
	numdescs = roundup_pow_of_two(numdescs);
	err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq",
			     PDS_CORE_QCQ_F_CORE | PDS_CORE_QCQ_F_INTR,
			     numdescs,
			     sizeof(union pds_core_adminq_cmd),
			     sizeof(union pds_core_adminq_comp),
			     0, &pdsc->adminqcq);
	if (err)
		goto err_out_teardown;

	err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_NOTIFYQ, 0, "notifyq",
			     PDS_CORE_QCQ_F_NOTIFYQ,
			     PDSC_NOTIFYQ_LENGTH,
			     sizeof(struct pds_core_notifyq_cmd),
			     sizeof(union pds_core_notifyq_comp),
			     0, &pdsc->notifyqcq);
	if (err)
		goto err_out_teardown;

	/* NotifyQ rides on the AdminQ interrupt */
	pdsc->notifyqcq.intx = pdsc->adminqcq.intx;

	/* Set up the Core with the AdminQ and NotifyQ info */
	err = pdsc_core_init(pdsc);
	if (err)
@@ -458,35 +471,20 @@ int pdsc_setup(struct pdsc *pdsc, bool init)

void pdsc_teardown(struct pdsc *pdsc, bool removing)
{
	int i;

	if (!pdsc->pdev->is_virtfn)
		pdsc_devcmd_reset(pdsc);
	if (pdsc->adminqcq.work.func)
		cancel_work_sync(&pdsc->adminqcq.work);
	pdsc_qcq_free(pdsc, &pdsc->notifyqcq);
	pdsc_qcq_free(pdsc, &pdsc->adminqcq);

	pdsc_core_uninit(pdsc);

	if (removing) {
		kfree(pdsc->viftype_status);
		pdsc->viftype_status = NULL;
	}

	if (pdsc->intr_info) {
		for (i = 0; i < pdsc->nintrs; i++)
			pdsc_intr_free(pdsc, i);

		kfree(pdsc->intr_info);
		pdsc->intr_info = NULL;
		pdsc->nintrs = 0;
	}

	if (pdsc->kern_dbpage) {
		iounmap(pdsc->kern_dbpage);
		pdsc->kern_dbpage = NULL;
	}
	pdsc_dev_uninit(pdsc);

	pci_free_irq_vectors(pdsc->pdev);
	set_bit(PDSC_S_FW_DEAD, &pdsc->state);
}

+1 −0
Original line number Diff line number Diff line
@@ -282,6 +282,7 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
int pdsc_devcmd_init(struct pdsc *pdsc);
int pdsc_devcmd_reset(struct pdsc *pdsc);
int pdsc_dev_init(struct pdsc *pdsc);
void pdsc_dev_uninit(struct pdsc *pdsc);

void pdsc_reset_prepare(struct pci_dev *pdev);
void pdsc_reset_done(struct pci_dev *pdev);
+4 −4
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@ void pdsc_debugfs_del_dev(struct pdsc *pdsc)

static int identity_show(struct seq_file *seq, void *v)
{
	struct pdsc *pdsc = seq->private;
	struct pds_core_dev_identity *ident;
	struct pdsc *pdsc = seq->private;
	int vt;

	ident = &pdsc->dev_ident;
@@ -106,10 +106,8 @@ static const struct debugfs_reg32 intr_ctrl_regs[] = {

void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq)
{
	struct dentry *qcq_dentry, *q_dentry, *cq_dentry;
	struct dentry *intr_dentry;
	struct dentry *qcq_dentry, *q_dentry, *cq_dentry, *intr_dentry;
	struct debugfs_regset32 *intr_ctrl_regset;
	struct pdsc_intr_info *intr = &pdsc->intr_info[qcq->intx];
	struct pdsc_queue *q = &qcq->q;
	struct pdsc_cq *cq = &qcq->cq;

@@ -147,6 +145,8 @@ void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq)
	debugfs_create_u16("tail", 0400, cq_dentry, &cq->tail_idx);

	if (qcq->flags & PDS_CORE_QCQ_F_INTR) {
		struct pdsc_intr_info *intr = &pdsc->intr_info[qcq->intx];

		intr_dentry = debugfs_create_dir("intr", qcq->dentry);
		if (IS_ERR_OR_NULL(intr_dentry))
			return;
+18 −4
Original line number Diff line number Diff line
@@ -316,6 +316,22 @@ static int pdsc_identify(struct pdsc *pdsc)
	return 0;
}

void pdsc_dev_uninit(struct pdsc *pdsc)
{
	if (pdsc->intr_info) {
		int i;

		for (i = 0; i < pdsc->nintrs; i++)
			pdsc_intr_free(pdsc, i);

		kfree(pdsc->intr_info);
		pdsc->intr_info = NULL;
		pdsc->nintrs = 0;
	}

	pci_free_irq_vectors(pdsc->pdev);
}

int pdsc_dev_init(struct pdsc *pdsc)
{
	unsigned int nintrs;
@@ -341,10 +357,8 @@ int pdsc_dev_init(struct pdsc *pdsc)

	/* Get intr_info struct array for tracking */
	pdsc->intr_info = kcalloc(nintrs, sizeof(*pdsc->intr_info), GFP_KERNEL);
	if (!pdsc->intr_info) {
		err = -ENOMEM;
		goto err_out;
	}
	if (!pdsc->intr_info)
		return -ENOMEM;

	err = pci_alloc_irq_vectors(pdsc->pdev, nintrs, nintrs, PCI_IRQ_MSIX);
	if (err != nintrs) {