summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/init.c
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2021-12-13 21:51:23 +0300
committerVinod Koul <vkoul@kernel.org>2022-01-05 10:41:21 +0300
commitec0d64231615e50539d83516b974e7947d45fbce (patch)
tree1a54597ad9c7edd145ec117dd0bd55e04030b43c /drivers/dma/idxd/init.c
parent26e9baa849a262f75b781c7292c36f4fdfbbf03b (diff)
downloadlinux-ec0d64231615e50539d83516b974e7947d45fbce.tar.xz
dmaengine: idxd: embed irq_entry in idxd_wq struct
With irq_entry already being associated with the wq in a 1:1 relationship, embed the irq_entry in the idxd_wq struct and remove back pointers for idxe_wq and idxd_device. In the process of this work, clean up the interrupt handle assignment so that there's no decision to be made during submit call on where interrupt handle value comes from. Set the interrupt handle during irq request initialization time. irq_entry 0 is designated as special and is tied to the device itself. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/163942148362.2412839.12055447853311267866.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.c119
1 files changed, 47 insertions, 72 deletions
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 8b3afce9ea67..29c732a94027 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -72,7 +72,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
{
struct pci_dev *pdev = idxd->pdev;
struct device *dev = &pdev->dev;
- struct idxd_irq_entry *irq_entry;
+ struct idxd_irq_entry *ie;
int i, msixcnt;
int rc = 0;
@@ -90,72 +90,54 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
}
dev_dbg(dev, "Enabled %d msix vectors\n", msixcnt);
- /*
- * We implement 1 completion list per MSI-X entry except for
- * entry 0, which is for errors and others.
- */
- idxd->irq_entries = kcalloc_node(msixcnt, sizeof(struct idxd_irq_entry),
- GFP_KERNEL, dev_to_node(dev));
- if (!idxd->irq_entries) {
- rc = -ENOMEM;
- goto err_irq_entries;
- }
-
- 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);
- }
-
idxd_msix_perm_setup(idxd);
- irq_entry = &idxd->irq_entries[0];
- rc = request_threaded_irq(irq_entry->vector, NULL, idxd_misc_thread,
- 0, "idxd-misc", irq_entry);
+ ie = idxd_get_ie(idxd, 0);
+ ie->vector = pci_irq_vector(pdev, 0);
+ rc = request_threaded_irq(ie->vector, NULL, idxd_misc_thread, 0, "idxd-misc", ie);
if (rc < 0) {
dev_err(dev, "Failed to allocate misc interrupt.\n");
goto err_misc_irq;
}
- dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n", irq_entry->vector);
+ dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n", ie->vector);
- /* first MSI-X entry is not for wq interrupts */
- idxd->num_wq_irqs = msixcnt - 1;
+ for (i = 0; i < idxd->max_wqs; i++) {
+ int msix_idx = i + 1;
+
+ ie = idxd_get_ie(idxd, msix_idx);
- for (i = 1; i < msixcnt; i++) {
- irq_entry = &idxd->irq_entries[i];
+ /* MSIX vector 0 special, wq irq entry starts at 1 */
+ ie->id = msix_idx;
+ ie->vector = pci_irq_vector(pdev, msix_idx);
+ ie->int_handle = INVALID_INT_HANDLE;
+ if (device_pasid_enabled(idxd) && i > 0)
+ ie->pasid = idxd->pasid;
+ else
+ ie->pasid = INVALID_IOASID;
+ spin_lock_init(&ie->list_lock);
+ init_llist_head(&ie->pending_llist);
+ INIT_LIST_HEAD(&ie->work_list);
- init_llist_head(&idxd->irq_entries[i].pending_llist);
- INIT_LIST_HEAD(&idxd->irq_entries[i].work_list);
- rc = request_threaded_irq(irq_entry->vector, NULL,
- idxd_wq_thread, 0, "idxd-portal", irq_entry);
+ rc = request_threaded_irq(ie->vector, NULL, idxd_wq_thread, 0, "idxd-portal", ie);
if (rc < 0) {
- dev_err(dev, "Failed to allocate irq %d.\n", irq_entry->vector);
+ dev_err(dev, "Failed to allocate irq %d.\n", ie->vector);
goto err_wq_irqs;
}
- dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, irq_entry->vector);
+ dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, ie->vector);
if (idxd->request_int_handles) {
- rc = idxd_device_request_int_handle(idxd, i, &irq_entry->int_handle,
+ rc = idxd_device_request_int_handle(idxd, i, &ie->int_handle,
IDXD_IRQ_MSIX);
if (rc < 0) {
- free_irq(irq_entry->vector, irq_entry);
+ free_irq(ie->vector, ie);
goto err_wq_irqs;
}
- dev_dbg(dev, "int handle requested: %u\n", irq_entry->int_handle);
+ dev_dbg(dev, "int handle requested: %u\n", ie->int_handle);
+ } else {
+ ie->int_handle = msix_idx;
}
+
}
idxd_unmask_error_interrupts(idxd);
@@ -163,23 +145,19 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
err_wq_irqs:
while (--i >= 0) {
- irq_entry = &idxd->irq_entries[i];
- free_irq(irq_entry->vector, irq_entry);
- 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;
+ ie = &idxd->wqs[i]->ie;
+ free_irq(ie->vector, ie);
+ if (ie->int_handle != INVALID_INT_HANDLE) {
+ idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
+ ie->int_handle = INVALID_INT_HANDLE;
+ ie->pasid = INVALID_IOASID;
}
- irq_entry->vector = -1;
- irq_entry->wq = NULL;
- irq_entry->idxd = NULL;
+ ie->vector = -1;
}
err_misc_irq:
/* Disable error interrupt generation */
idxd_mask_error_interrupts(idxd);
idxd_msix_perm_clear(idxd);
- err_irq_entries:
pci_free_irq_vectors(pdev);
dev_err(dev, "No usable interrupts\n");
return rc;
@@ -188,21 +166,18 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
static void idxd_cleanup_interrupts(struct idxd_device *idxd)
{
struct pci_dev *pdev = idxd->pdev;
- struct idxd_irq_entry *irq_entry;
+ struct idxd_irq_entry *ie;
int i;
for (i = 0; i < idxd->irq_cnt; i++) {
- irq_entry = &idxd->irq_entries[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;
+ ie = idxd_get_ie(idxd, i);
+ if (ie->int_handle != INVALID_INT_HANDLE) {
+ idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
+ ie->int_handle = INVALID_INT_HANDLE;
+ ie->pasid = INVALID_IOASID;
}
- irq_entry->vector = -1;
- irq_entry->wq = NULL;
- irq_entry->idxd = NULL;
- free_irq(irq_entry->vector, irq_entry);
+ free_irq(ie->vector, ie);
+ ie->vector = -1;
}
idxd_mask_error_interrupts(idxd);
@@ -755,7 +730,7 @@ static void idxd_release_int_handles(struct idxd_device *idxd)
int i, rc;
for (i = 1; i < idxd->irq_cnt; i++) {
- struct idxd_irq_entry *ie = &idxd->irq_entries[i];
+ struct idxd_irq_entry *ie = idxd_get_ie(idxd, i);
if (ie->int_handle != INVALID_INT_HANDLE) {
rc = idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
@@ -783,7 +758,7 @@ static void idxd_shutdown(struct pci_dev *pdev)
idxd_mask_error_interrupts(idxd);
for (i = 0; i < msixcnt; i++) {
- irq_entry = &idxd->irq_entries[i];
+ irq_entry = idxd_get_ie(idxd, i);
synchronize_irq(irq_entry->vector);
if (i == 0)
continue;
@@ -815,7 +790,7 @@ static void idxd_remove(struct pci_dev *pdev)
idxd_disable_system_pasid(idxd);
for (i = 0; i < msixcnt; i++) {
- irq_entry = &idxd->irq_entries[i];
+ irq_entry = idxd_get_ie(idxd, i);
free_irq(irq_entry->vector, irq_entry);
}
idxd_msix_perm_clear(idxd);