Commit da32b28c authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul
Browse files

dmaengine: idxd: cleanup workqueue config after disabling



After disabling a device, we should clean up the internal state for
the wqs and zero out the configuration registers. Without doing so can cause
issues when the user reprogram the wqs.

Fixes: c52ca478 ("dmaengine: idxd: add configuration component of driver")
Reported-by: default avatarYixin Zhang <yixin.zhang@intel.com>
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Tested-by: default avatarYixin Zhang <yixin.zhang@intel.com>
Link: https://lore.kernel.org/r/159311264246.1198.11955791213681679428.stgit@djiang5-desk3.ch.intel.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 5b78fac4
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
	devm_iounmap(dev, wq->dportal);
}

void idxd_wq_disable_cleanup(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct device *dev = &idxd->pdev->dev;
	int i, wq_offset;

	lockdep_assert_held(&idxd->dev_lock);
	memset(&wq->wqcfg, 0, sizeof(wq->wqcfg));
	wq->type = IDXD_WQT_NONE;
	wq->size = 0;
	wq->group = NULL;
	wq->threshold = 0;
	wq->priority = 0;
	clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
	memset(wq->name, 0, WQ_NAME_SIZE);

	for (i = 0; i < 8; i++) {
		wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
		iowrite32(0, idxd->reg_base + wq_offset);
		dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
			wq->id, i, wq_offset,
			ioread32(idxd->reg_base + wq_offset));
	}
}

/* Device control bits */
static inline bool idxd_is_enabled(struct idxd_device *idxd)
{
+1 −0
Original line number Diff line number Diff line
@@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq);
int idxd_wq_disable(struct idxd_wq *wq);
int idxd_wq_map_portal(struct idxd_wq *wq);
void idxd_wq_unmap_portal(struct idxd_wq *wq);
void idxd_wq_disable_cleanup(struct idxd_wq *wq);

/* submission */
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
+5 −0
Original line number Diff line number Diff line
@@ -315,6 +315,11 @@ static int idxd_config_bus_remove(struct device *dev)
		idxd_unregister_dma_device(idxd);
		spin_lock_irqsave(&idxd->dev_lock, flags);
		rc = idxd_device_disable(idxd);
		for (i = 0; i < idxd->max_wqs; i++) {
			struct idxd_wq *wq = &idxd->wqs[i];

			idxd_wq_disable_cleanup(wq);
		}
		spin_unlock_irqrestore(&idxd->dev_lock, flags);
		module_put(THIS_MODULE);
		if (rc < 0)