summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/init.c
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2021-10-27 00:36:10 +0300
committerVinod Koul <vkoul@kernel.org>2021-11-22 08:51:26 +0300
commit8b67426e05584e956775f4b134596b56bc0d35e0 (patch)
tree6277368110ff1dfc2ee2d80edaf659e1d8859962 /drivers/dma/idxd/init.c
parent5d78abb6fbc974d601dd365b9ce39f320fb5ba79 (diff)
downloadlinux-8b67426e05584e956775f4b134596b56bc0d35e0.tar.xz
dmaengine: idxd: int handle management refactoring
Attach int_handle to irq_entry. This removes the separate management of int handles and reduces the confusion of interating through int handles that is off by 1 count. Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/163528417065.3925689.11505755433684476288.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd/init.c')
-rw-r--r--drivers/dma/idxd/init.c86
1 files changed, 45 insertions, 41 deletions
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 4373b48cdc91..2dbff722e207 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -81,6 +81,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
dev_err(dev, "Not MSI-X interrupt capable.\n");
return -ENOSPC;
}
+ idxd->irq_cnt = msixcnt;
rc = pci_alloc_irq_vectors(pdev, msixcnt, msixcnt, PCI_IRQ_MSIX);
if (rc != msixcnt) {
@@ -103,7 +104,18 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
for (i = 0; i < msixcnt; i++) {
idxd->irq_entries[i].id = i;
idxd->irq_entries[i].idxd = idxd;
+ /*
+ * Association of WQ should be assigned starting with irq_entry 1.
+ * irq_entry 0 is for misc interrupts and has no wq association
+ */
+ if (i > 0)
+ idxd->irq_entries[i].wq = idxd->wqs[i - 1];
idxd->irq_entries[i].vector = pci_irq_vector(pdev, i);
+ idxd->irq_entries[i].int_handle = INVALID_INT_HANDLE;
+ if (device_pasid_enabled(idxd) && i > 0)
+ idxd->irq_entries[i].pasid = idxd->pasid;
+ else
+ idxd->irq_entries[i].pasid = INVALID_IOASID;
spin_lock_init(&idxd->irq_entries[i].list_lock);
}
@@ -135,22 +147,14 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
}
dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, irq_entry->vector);
- if (idxd->hw.cmd_cap & BIT(IDXD_CMD_REQUEST_INT_HANDLE)) {
- /*
- * The MSIX vector enumeration starts at 1 with vector 0 being the
- * misc interrupt that handles non I/O completion events. The
- * interrupt handles are for IMS enumeration on guest. The misc
- * interrupt vector does not require a handle and therefore we start
- * the int_handles at index 0. Since 'i' starts at 1, the first
- * int_handles index will be 0.
- */
- rc = idxd_device_request_int_handle(idxd, i, &idxd->int_handles[i - 1],
+ if (idxd->request_int_handles) {
+ rc = idxd_device_request_int_handle(idxd, i, &irq_entry->int_handle,
IDXD_IRQ_MSIX);
if (rc < 0) {
free_irq(irq_entry->vector, irq_entry);
goto err_wq_irqs;
}
- dev_dbg(dev, "int handle requested: %u\n", idxd->int_handles[i - 1]);
+ dev_dbg(dev, "int handle requested: %u\n", irq_entry->int_handle);
}
}
@@ -161,9 +165,15 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
while (--i >= 0) {
irq_entry = &idxd->irq_entries[i];
free_irq(irq_entry->vector, irq_entry);
- if (i != 0)
- idxd_device_release_int_handle(idxd,
- idxd->int_handles[i], IDXD_IRQ_MSIX);
+ if (irq_entry->int_handle != INVALID_INT_HANDLE) {
+ idxd_device_release_int_handle(idxd, irq_entry->int_handle,
+ IDXD_IRQ_MSIX);
+ irq_entry->int_handle = INVALID_INT_HANDLE;
+ irq_entry->pasid = INVALID_IOASID;
+ }
+ irq_entry->vector = -1;
+ irq_entry->wq = NULL;
+ irq_entry->idxd = NULL;
}
err_misc_irq:
/* Disable error interrupt generation */
@@ -179,21 +189,19 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd)
{
struct pci_dev *pdev = idxd->pdev;
struct idxd_irq_entry *irq_entry;
- int i, msixcnt;
-
- msixcnt = pci_msix_vec_count(pdev);
- if (msixcnt <= 0)
- return;
-
- irq_entry = &idxd->irq_entries[0];
- free_irq(irq_entry->vector, irq_entry);
-
- for (i = 1; i < msixcnt; i++) {
+ int i;
+ for (i = 0; i < idxd->irq_cnt; i++) {
irq_entry = &idxd->irq_entries[i];
- if (idxd->hw.cmd_cap & BIT(IDXD_CMD_RELEASE_INT_HANDLE))
- idxd_device_release_int_handle(idxd, idxd->int_handles[i],
+ if (irq_entry->int_handle != INVALID_INT_HANDLE) {
+ idxd_device_release_int_handle(idxd, irq_entry->int_handle,
IDXD_IRQ_MSIX);
+ irq_entry->int_handle = INVALID_INT_HANDLE;
+ irq_entry->pasid = INVALID_IOASID;
+ }
+ irq_entry->vector = -1;
+ irq_entry->wq = NULL;
+ irq_entry->idxd = NULL;
free_irq(irq_entry->vector, irq_entry);
}
@@ -379,13 +387,6 @@ static int idxd_setup_internals(struct idxd_device *idxd)
init_waitqueue_head(&idxd->cmd_waitq);
- if (idxd->hw.cmd_cap & BIT(IDXD_CMD_REQUEST_INT_HANDLE)) {
- idxd->int_handles = kcalloc_node(idxd->max_wqs, sizeof(int), GFP_KERNEL,
- dev_to_node(dev));
- if (!idxd->int_handles)
- return -ENOMEM;
- }
-
rc = idxd_setup_wqs(idxd);
if (rc < 0)
goto err_wqs;
@@ -416,7 +417,6 @@ static int idxd_setup_internals(struct idxd_device *idxd)
for (i = 0; i < idxd->max_wqs; i++)
put_device(wq_confdev(idxd->wqs[i]));
err_wqs:
- kfree(idxd->int_handles);
return rc;
}
@@ -451,6 +451,10 @@ static void idxd_read_caps(struct idxd_device *idxd)
dev_dbg(dev, "cmd_cap: %#x\n", idxd->hw.cmd_cap);
}
+ /* reading command capabilities */
+ if (idxd->hw.cmd_cap & BIT(IDXD_CMD_REQUEST_INT_HANDLE))
+ idxd->request_int_handles = true;
+
idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift;
dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes);
idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift;
@@ -748,15 +752,15 @@ static void idxd_release_int_handles(struct idxd_device *idxd)
struct device *dev = &idxd->pdev->dev;
int i, rc;
- for (i = 0; i < idxd->num_wq_irqs; i++) {
- if (idxd->hw.cmd_cap & BIT(IDXD_CMD_RELEASE_INT_HANDLE)) {
- rc = idxd_device_release_int_handle(idxd, idxd->int_handles[i],
- IDXD_IRQ_MSIX);
+ for (i = 1; i < idxd->irq_cnt; i++) {
+ struct idxd_irq_entry *ie = &idxd->irq_entries[i];
+
+ if (ie->int_handle != INVALID_INT_HANDLE) {
+ rc = idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
if (rc < 0)
- dev_warn(dev, "irq handle %d release failed\n",
- idxd->int_handles[i]);
+ dev_warn(dev, "irq handle %d release failed\n", ie->int_handle);
else
- dev_dbg(dev, "int handle requested: %u\n", idxd->int_handles[i]);
+ dev_dbg(dev, "int handle released: %u\n", ie->int_handle);
}
}
}