* [PATCH 0/6] dmaengine: idxd: More error handling fixes
@ 2026-10-12 21:38 Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
` (5 more replies)
0 siblings, 6 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes, Steve Wahl,
Bogdan Codres, Zhenzhong Duan
Mostly this series proposes fixes for issues in the error handling
paths of the idxd driver. Patches 1/6, 2/6 and 3/6 are for issues that
have been shown to happen in the real world.
Patch 6/6 is an exception, in the sense that it's not error path
related, it's an issue that I introduced (my scripts were removing
the idxd module after each dmatest run, so I didn't caught this).
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
Steve Wahl (2):
dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq
dmaengine: idxd: fix duplicate memory frees on initialization error path
Vinicius Costa Gomes (4):
dmaengine: idxd: Fix potential double free on probe error path
dmaengine: idxd: Fix unwind bounds in device registration error paths
dmaengine: idxd: Fix error code handling in idxd_cdev_open()
dmaengine: idxd: Do not release interrupt handles on terminate_all
drivers/dma/idxd/cdev.c | 8 ++++++--
drivers/dma/idxd/device.c | 11 ++++++++++-
drivers/dma/idxd/idxd.h | 1 +
drivers/dma/idxd/init.c | 21 ++++++---------------
drivers/dma/idxd/irq.c | 1 +
drivers/dma/idxd/sysfs.c | 9 +++++----
6 files changed, 29 insertions(+), 22 deletions(-)
---
base-commit: 42c31fec1ca76b8b5f7759def122d418dff2cd4b
change-id: 20260803-wt-idxd-fixes-1a06bb69b1e0
Best regards,
--
Vinicius
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
2026-10-13 14:55 ` Frank Li
2026-10-13 17:18 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path Vinicius Costa Gomes
` (4 subsequent siblings)
5 siblings, 2 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes, Steve Wahl
From: Steve Wahl <steve.wahl@hpe.com>
Error paths within idxd_pci_probe_alloc and related functions end up
calling destroy_workqueue with a null pointer, from
idxd_conf_device_release via put_device, because that allocation has
not yet occurred when the error is hit.
This was encountered running in a kexec'd kdump kernel with reduced
resources, causing the "Device is HALTED!" branch in
idxd_device_init_reset to be taken.
In idxd_conf_device_release, check that the workqueue has been
allocated before trying to destroy it.
Fixes: 3d33de353b1f ("dmaengine: idxd: Fix not releasing workqueue on .release()")
Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
drivers/dma/idxd/sysfs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 6d251095c350..d5ffc641c856 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -1836,7 +1836,8 @@ static void idxd_conf_device_release(struct device *dev)
{
struct idxd_device *idxd = confdev_to_idxd(dev);
- destroy_workqueue(idxd->wq);
+ if (idxd->wq)
+ destroy_workqueue(idxd->wq);
kfree(idxd->groups);
bitmap_free(idxd->wq_enable_map);
kfree(idxd->wqs);
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
2026-10-13 14:57 ` Frank Li
2026-10-13 17:21 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe " Vinicius Costa Gomes
` (3 subsequent siblings)
5 siblings, 2 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes, Steve Wahl, Bogdan Codres
From: Steve Wahl <steve.wahl@hpe.com>
Error paths within idxd_pci_probe_alloc and related functions end up
attempting to free memory already freed from idxd_conf_device_release
via put_device.
This was encountered running in a kexec'd kdump kernel with reduced
resources, causing the "Device is HALTED!" branch in
idxd_device_init_reset to be taken.
[ 18.628791] idxd 0000:00:01.0: Device is HALTED!
[ 18.631447] idxd 0000:00:01.0: Intel(R) IDXD DMA Engine init failed
[ 18.631450] ------------[ cut here ]------------
[ 18.631451] ida_free called for id=0 which is not allocated.
[ 18.631462] WARNING: CPU: 0 PID: 11 at lib/idr.c:525 ida_free+0xd3/0x130
[ 18.631474] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.12.0-1-rt-amd64 #1
[ 18.631477] Hardware name: Dell Inc. PowerEdge XR8720t/0J91KV, BIOS 1.1.3 02/03/2026
[ 18.631478] Workqueue: events work_for_cpu_fn
[ 18.631480] RIP: 0010:ida_free+0xd3/0x130
[ 18.631492] Call Trace:
[ 18.631494] <TASK>
[ 18.631495] idxd_pci_probe+0x1b0/0x1860 [idxd]
[ 18.631506] local_pci_probe+0x43/0xa0
[ 18.631508] work_for_cpu_fn+0x13/0x20
[ 18.631510] process_one_work+0x179/0x390
[ 18.631512] worker_thread+0x237/0x340
[ 18.631517] kthread+0xc6/0x100
[ 18.631520] ret_from_fork+0x2d/0x50
[ 18.631524] ret_from_fork_asm+0x1a/0x30
[ 18.631526] </TASK>
In idxd_free and idxd_alloc, do not attempt to free allocations that
will already have been freed.
Fixes: 90022b3a6981 ("dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe")
Fixes: 46a5cca76c76 ("dmaengine: idxd: fix memory leak in error handling path of idxd_alloc")
Reported-by: Bogdan Codres <bogdan.codres@windriver.com>
Link: https://lore.kernel.org/all/akLBL7b2h73pK0AC@ilogsc-qemu.local/
Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
---
drivers/dma/idxd/init.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 4b827a329756..4adb3f3bcd01 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -581,9 +581,6 @@ static void idxd_free(struct idxd_device *idxd)
return;
put_device(idxd_confdev(idxd));
- bitmap_free(idxd->opcap_bmap);
- ida_free(&idxd_ida, idxd->id);
- kfree(idxd);
}
static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
@@ -623,8 +620,13 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
return idxd;
err_name:
+ /*
+ * once device_initialize(conf_dev) is called,
+ * put_device(conf_dev) will end up calling
+ * idxd_conf_device_release() which will free the rest.
+ */
put_device(conf_dev);
- bitmap_free(idxd->opcap_bmap);
+ return NULL;
err_opcap:
ida_free(&idxd_ida, idxd->id);
err_ida:
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe error path
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
2026-10-13 17:30 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 4/6] dmaengine: idxd: Fix unwind bounds in device registration error paths Vinicius Costa Gomes
` (2 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes
On the probe error path the device is released via put_device() ->
idxd_conf_device_release(), which frees idxd->wq and the idxd->wqs,
idxd->engines, idxd->groups and idxd->wq_enable_map arrays. The
idxd_clean_*() helpers and the idxd_setup_*() error unwind paths free
the same objects, so they get freed twice.
With commit ec2d428b2e32 ("dmaengine: idxd: fix double free of wq,
engine, and group structs") we made use of the kobject lifetime to
keep track of device memory allocations. These deallocations were left
behind. Remove them as idxd_conf_device_release() is already taking
care of that.
Fixes: 3d33de353b1f ("dmaengine: idxd: Fix not releasing workqueue on .release()")
Link: https://lore.kernel.org/all/20260615103932.61828-1-bogdan.codres@windriver.com/
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
drivers/dma/idxd/init.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 4adb3f3bcd01..8cf478c5b26d 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -166,8 +166,6 @@ static void idxd_clean_wqs(struct idxd_device *idxd)
conf_dev = wq_confdev(idxd->wqs[i]);
put_device(conf_dev);
}
- bitmap_free(idxd->wq_enable_map);
- kfree(idxd->wqs);
}
static int idxd_setup_wqs(struct idxd_device *idxd)
@@ -245,11 +243,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
conf_dev = wq_confdev(idxd->wqs[i]);
put_device(conf_dev);
}
- bitmap_free(idxd->wq_enable_map);
err_free_wqs:
- kfree(idxd->wqs);
-
return rc;
}
@@ -262,7 +257,6 @@ static void idxd_clean_engines(struct idxd_device *idxd)
conf_dev = engine_confdev(idxd->engines[i]);
put_device(conf_dev);
}
- kfree(idxd->engines);
}
static int idxd_setup_engines(struct idxd_device *idxd)
@@ -308,7 +302,6 @@ static int idxd_setup_engines(struct idxd_device *idxd)
conf_dev = engine_confdev(idxd->engines[i]);
put_device(conf_dev);
}
- kfree(idxd->engines);
return rc;
}
@@ -320,7 +313,6 @@ static void idxd_clean_groups(struct idxd_device *idxd)
for (i = 0; i < idxd->max_groups; i++) {
put_device(group_confdev(idxd->groups[i]));
}
- kfree(idxd->groups);
}
static int idxd_setup_groups(struct idxd_device *idxd)
@@ -378,7 +370,6 @@ static int idxd_setup_groups(struct idxd_device *idxd)
group = idxd->groups[i];
put_device(group_confdev(group));
}
- kfree(idxd->groups);
return rc;
}
@@ -388,7 +379,6 @@ static void idxd_cleanup_internals(struct idxd_device *idxd)
idxd_clean_groups(idxd);
idxd_clean_engines(idxd);
idxd_clean_wqs(idxd);
- destroy_workqueue(idxd->wq);
}
static int idxd_init_evl(struct idxd_device *idxd)
@@ -459,7 +449,6 @@ static int idxd_setup_internals(struct idxd_device *idxd)
return 0;
err_evl:
- destroy_workqueue(idxd->wq);
err_wkq_create:
idxd_clean_groups(idxd);
err_group:
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] dmaengine: idxd: Fix unwind bounds in device registration error paths
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
` (2 preceding siblings ...)
2026-10-12 21:38 ` [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe " Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 5/6] dmaengine: idxd: Fix error code handling in idxd_cdev_open() Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 6/6] dmaengine: idxd: Do not release interrupt handles on terminate_all Vinicius Costa Gomes
5 siblings, 0 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes
When registering the per-idxd wq, engine, or group devices, a failure
partway through must roll back exactly the devices already added, i.e.
the range [0, i) when device_add() fails at index i.
idxd_register_{wq,engine,group}_devices() get this range wrong: each
seeds the "while (j--)" rollback loop with j = i - 1 instead of j = i.
This skips one device (leaking it), and when the very first device
fails (i == 0) the index underflows to -1 and the loop walks off the
front of the array.
Start the rollback at i.
Fixes: 7c5dd23e57c1 ("dmaengine: idxd: fix wq conf_dev 'struct device' lifetime")
Fixes: 75b911309060 ("dmaengine: idxd: fix engine conf_dev lifetime")
Fixes: defe49f96012 ("dmaengine: idxd: fix group conf_dev lifetime")
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
drivers/dma/idxd/sysfs.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index d5ffc641c856..e828292e5fb8 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -1876,7 +1876,7 @@ static int idxd_register_engine_devices(struct idxd_device *idxd)
return 0;
cleanup:
- j = i - 1;
+ j = i;
for (; i < idxd->max_engines; i++) {
engine = idxd->engines[i];
put_device(engine_confdev(engine));
@@ -1904,7 +1904,7 @@ static int idxd_register_group_devices(struct idxd_device *idxd)
return 0;
cleanup:
- j = i - 1;
+ j = i;
for (; i < idxd->max_groups; i++) {
group = idxd->groups[i];
put_device(group_confdev(group));
@@ -1932,7 +1932,7 @@ static int idxd_register_wq_devices(struct idxd_device *idxd)
return 0;
cleanup:
- j = i - 1;
+ j = i;
for (; i < idxd->max_wqs; i++) {
wq = idxd->wqs[i];
put_device(wq_confdev(wq));
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/6] dmaengine: idxd: Fix error code handling in idxd_cdev_open()
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
` (3 preceding siblings ...)
2026-10-12 21:38 ` [PATCH 4/6] dmaengine: idxd: Fix unwind bounds in device registration error paths Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 6/6] dmaengine: idxd: Do not release interrupt handles on terminate_all Vinicius Costa Gomes
5 siblings, 0 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes
idxd_cdev_open() mishandles rc on two error paths:
- On ida_alloc() failure it jumps to failed_ida without setting rc,
returning the leftover 0 from the earlier successful xa_insert(), so
open() falsely reports success.
- When a PASID entry already exists, xa_insert() returns -EBUSY. This
is non-fatal and only warned about, but rc is left negative and can
leak out for a shared wq (which skips the idxd_wq_set_pasid() branch
that would reset it).
Set rc to the ida_alloc() error before unwinding, and reset rc to 0
after the "PASID already exists" (Fixed the "exist -> exists" typo
while at it) warning.
Fixes: e6fd6d7e5f0f ("dmaengine: idxd: add a device to represent the file opened")
Fixes: b022f59725f0 ("dmaengine: idxd: add idxd_copy_cr() to copy user completion record during page fault handling")
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
drivers/dma/idxd/cdev.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
index 82b07cf942ef..abbab9bdd06c 100644
--- a/drivers/dma/idxd/cdev.c
+++ b/drivers/dma/idxd/cdev.c
@@ -264,8 +264,11 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
mutex_lock(&wq->uc_lock);
rc = xa_insert(&wq->upasid_xa, pasid, ctx, GFP_KERNEL);
mutex_unlock(&wq->uc_lock);
- if (rc < 0)
- dev_warn(dev, "PASID entry already exist in xarray.\n");
+ if (rc < 0) {
+ /* An existing entry is harmless, warn and continue */
+ dev_warn(dev, "PASID entry already exists in xarray.\n");
+ rc = 0;
+ }
if (wq_dedicated(wq)) {
rc = idxd_wq_set_pasid(wq, pasid);
@@ -279,6 +282,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
idxd_cdev = wq->idxd_cdev;
ctx->id = ida_alloc(&file_ida, GFP_KERNEL);
if (ctx->id < 0) {
+ rc = ctx->id;
dev_warn(dev, "ida alloc failure\n");
goto failed_ida;
}
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/6] dmaengine: idxd: Do not release interrupt handles on terminate_all
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
` (4 preceding siblings ...)
2026-10-12 21:38 ` [PATCH 5/6] dmaengine: idxd: Fix error code handling in idxd_cdev_open() Vinicius Costa Gomes
@ 2026-10-12 21:38 ` Vinicius Costa Gomes
5 siblings, 0 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-12 21:38 UTC (permalink / raw)
To: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Vinicius Costa Gomes, Zhenzhong Duan
idxd_wq_flush_descs() is called from the dmaengine .device_terminate_all
path, but besides flushing the pending descriptors it also releases the
interrupt handle. As the workqueue stays enabled, the handle is never
re-armed, and any subsequent submission uses an invalid handle and never
completes.
This only shows up when the same workqueue is used more than once: the
first run leaves the handle released on terminate_all, so any later run
times out on every descriptor. dmatest reproduces it by running twice.
Split the interrupt handle teardown into idxd_wq_release_int_handle() so
that terminate_all only flushes descriptors. The FLR path still needs
both, so call them together there.
Fixes: 2a93f5747d0e ("dmaengine: idxd: Flush all pending descriptors")
Reported-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
drivers/dma/idxd/device.c | 11 ++++++++++-
drivers/dma/idxd/idxd.h | 1 +
drivers/dma/idxd/irq.c | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 131138483b87..06299f40f531 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -1349,6 +1349,16 @@ void idxd_wq_free_irq(struct idxd_wq *wq)
}
void idxd_wq_flush_descs(struct idxd_wq *wq)
+{
+ guard(mutex)(&wq->wq_lock);
+
+ if (wq->state != IDXD_WQ_ENABLED || wq->type != IDXD_WQT_KERNEL)
+ return;
+
+ idxd_flush_pending_descs(&wq->ie);
+}
+
+void idxd_wq_release_int_handle(struct idxd_wq *wq)
{
struct idxd_irq_entry *ie = &wq->ie;
struct idxd_device *idxd = wq->idxd;
@@ -1358,7 +1368,6 @@ void idxd_wq_flush_descs(struct idxd_wq *wq)
if (wq->state != IDXD_WQ_ENABLED || wq->type != IDXD_WQT_KERNEL)
return;
- idxd_flush_pending_descs(ie);
if (idxd->request_int_handles)
idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
idxd_device_clear_perm_entry(idxd, ie);
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index ce78b9a7c641..f4aed90560e0 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -804,6 +804,7 @@ int idxd_wq_init_percpu_ref(struct idxd_wq *wq);
void idxd_wq_free_irq(struct idxd_wq *wq);
int idxd_wq_request_irq(struct idxd_wq *wq);
void idxd_wq_flush_descs(struct idxd_wq *wq);
+void idxd_wq_release_int_handle(struct idxd_wq *wq);
/* submission */
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
index 6a25e1fd0e62..26d75d744797 100644
--- a/drivers/dma/idxd/irq.c
+++ b/drivers/dma/idxd/irq.c
@@ -405,6 +405,7 @@ static void idxd_wqs_flush_descs(struct idxd_device *idxd)
struct idxd_wq *wq = idxd->wqs[i];
idxd_wq_flush_descs(wq);
+ idxd_wq_release_int_handle(wq);
}
}
--
2.56.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
@ 2026-10-13 14:55 ` Frank Li
2026-10-13 17:18 ` Dave Jiang
1 sibling, 0 replies; 13+ messages in thread
From: Frank Li @ 2026-10-13 14:55 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue,
dmaengine, linux-kernel, Steve Wahl
On Mon, Oct 12, 2026 at 02:38:04PM -0700, Vinicius Costa Gomes wrote:
> From: Steve Wahl <steve.wahl@hpe.com>
>
> Error paths within idxd_pci_probe_alloc and related functions end up
> calling destroy_workqueue with a null pointer, from
all funciton need (), include subject.
destroy_workqueue()
Frank
> idxd_conf_device_release via put_device, because that allocation has
> not yet occurred when the error is hit.
>
> This was encountered running in a kexec'd kdump kernel with reduced
> resources, causing the "Device is HALTED!" branch in
> idxd_device_init_reset to be taken.
>
> In idxd_conf_device_release, check that the workqueue has been
> allocated before trying to destroy it.
>
> Fixes: 3d33de353b1f ("dmaengine: idxd: Fix not releasing workqueue on .release()")
> Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
> Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
> ---
> drivers/dma/idxd/sysfs.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
> index 6d251095c350..d5ffc641c856 100644
> --- a/drivers/dma/idxd/sysfs.c
> +++ b/drivers/dma/idxd/sysfs.c
> @@ -1836,7 +1836,8 @@ static void idxd_conf_device_release(struct device *dev)
> {
> struct idxd_device *idxd = confdev_to_idxd(dev);
>
> - destroy_workqueue(idxd->wq);
> + if (idxd->wq)
> + destroy_workqueue(idxd->wq);
> kfree(idxd->groups);
> bitmap_free(idxd->wq_enable_map);
> kfree(idxd->wqs);
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path
2026-10-12 21:38 ` [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path Vinicius Costa Gomes
@ 2026-10-13 14:57 ` Frank Li
2026-10-13 22:31 ` Vinicius Costa Gomes
2026-10-13 17:21 ` Dave Jiang
1 sibling, 1 reply; 13+ messages in thread
From: Frank Li @ 2026-10-13 14:57 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue,
dmaengine, linux-kernel, Steve Wahl, Bogdan Codres
On Mon, Oct 12, 2026 at 02:38:05PM -0700, Vinicius Costa Gomes wrote:
> From: Steve Wahl <steve.wahl@hpe.com>
>
> Error paths within idxd_pci_probe_alloc and related functions end
idxd_pci_probe_alloc(), check other commit message.
Frank
> attempting to free memory already freed from idxd_conf_device_release
> via put_device.
>
> This was encountered running in a kexec'd kdump kernel with reduced
> resources, causing the "Device is HALTED!" branch in
> idxd_device_init_reset to be taken.
>
> [ 18.628791] idxd 0000:00:01.0: Device is HALTED!
> [ 18.631447] idxd 0000:00:01.0: Intel(R) IDXD DMA Engine init failed
> [ 18.631450] ------------[ cut here ]------------
> [ 18.631451] ida_free called for id=0 which is not allocated.
> [ 18.631462] WARNING: CPU: 0 PID: 11 at lib/idr.c:525 ida_free+0xd3/0x130
> [ 18.631474] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.12.0-1-rt-amd64 #1
> [ 18.631477] Hardware name: Dell Inc. PowerEdge XR8720t/0J91KV, BIOS 1.1.3 02/03/2026
> [ 18.631478] Workqueue: events work_for_cpu_fn
> [ 18.631480] RIP: 0010:ida_free+0xd3/0x130
> [ 18.631492] Call Trace:
> [ 18.631494] <TASK>
> [ 18.631495] idxd_pci_probe+0x1b0/0x1860 [idxd]
> [ 18.631506] local_pci_probe+0x43/0xa0
> [ 18.631508] work_for_cpu_fn+0x13/0x20
> [ 18.631510] process_one_work+0x179/0x390
> [ 18.631512] worker_thread+0x237/0x340
> [ 18.631517] kthread+0xc6/0x100
> [ 18.631520] ret_from_fork+0x2d/0x50
> [ 18.631524] ret_from_fork_asm+0x1a/0x30
> [ 18.631526] </TASK>
>
> In idxd_free and idxd_alloc, do not attempt to free allocations that
> will already have been freed.
>
> Fixes: 90022b3a6981 ("dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe")
> Fixes: 46a5cca76c76 ("dmaengine: idxd: fix memory leak in error handling path of idxd_alloc")
> Reported-by: Bogdan Codres <bogdan.codres@windriver.com>
> Link: https://lore.kernel.org/all/akLBL7b2h73pK0AC@ilogsc-qemu.local/
> Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
> ---
> drivers/dma/idxd/init.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
> index 4b827a329756..4adb3f3bcd01 100644
> --- a/drivers/dma/idxd/init.c
> +++ b/drivers/dma/idxd/init.c
> @@ -581,9 +581,6 @@ static void idxd_free(struct idxd_device *idxd)
> return;
>
> put_device(idxd_confdev(idxd));
> - bitmap_free(idxd->opcap_bmap);
> - ida_free(&idxd_ida, idxd->id);
> - kfree(idxd);
> }
>
> static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
> @@ -623,8 +620,13 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
> return idxd;
>
> err_name:
> + /*
> + * once device_initialize(conf_dev) is called,
> + * put_device(conf_dev) will end up calling
> + * idxd_conf_device_release() which will free the rest.
> + */
> put_device(conf_dev);
> - bitmap_free(idxd->opcap_bmap);
> + return NULL;
> err_opcap:
> ida_free(&idxd_ida, idxd->id);
> err_ida:
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
2026-10-13 14:55 ` Frank Li
@ 2026-10-13 17:18 ` Dave Jiang
1 sibling, 0 replies; 13+ messages in thread
From: Dave Jiang @ 2026-10-13 17:18 UTC (permalink / raw)
To: Vinicius Costa Gomes, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Steve Wahl
On 10/12/26 2:38 PM, Vinicius Costa Gomes wrote:
> From: Steve Wahl <steve.wahl@hpe.com>
>
> Error paths within idxd_pci_probe_alloc and related functions end up
> calling destroy_workqueue with a null pointer, from
> idxd_conf_device_release via put_device, because that allocation has
> not yet occurred when the error is hit.
>
> This was encountered running in a kexec'd kdump kernel with reduced
> resources, causing the "Device is HALTED!" branch in
> idxd_device_init_reset to be taken.
>
> In idxd_conf_device_release, check that the workqueue has been
> allocated before trying to destroy it.
>
> Fixes: 3d33de353b1f ("dmaengine: idxd: Fix not releasing workqueue on .release()")
> Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
> Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
^ needs a sign off rather than an ack since you posted his patch?
With Frank's comment addressed,
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/dma/idxd/sysfs.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
> index 6d251095c350..d5ffc641c856 100644
> --- a/drivers/dma/idxd/sysfs.c
> +++ b/drivers/dma/idxd/sysfs.c
> @@ -1836,7 +1836,8 @@ static void idxd_conf_device_release(struct device *dev)
> {
> struct idxd_device *idxd = confdev_to_idxd(dev);
>
> - destroy_workqueue(idxd->wq);
> + if (idxd->wq)
> + destroy_workqueue(idxd->wq);
> kfree(idxd->groups);
> bitmap_free(idxd->wq_enable_map);
> kfree(idxd->wqs);
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path
2026-10-12 21:38 ` [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path Vinicius Costa Gomes
2026-10-13 14:57 ` Frank Li
@ 2026-10-13 17:21 ` Dave Jiang
1 sibling, 0 replies; 13+ messages in thread
From: Dave Jiang @ 2026-10-13 17:21 UTC (permalink / raw)
To: Vinicius Costa Gomes, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel, Steve Wahl, Bogdan Codres
On 10/12/26 2:38 PM, Vinicius Costa Gomes wrote:
> From: Steve Wahl <steve.wahl@hpe.com>
>
> Error paths within idxd_pci_probe_alloc and related functions end up
> attempting to free memory already freed from idxd_conf_device_release
> via put_device.
>
> This was encountered running in a kexec'd kdump kernel with reduced
> resources, causing the "Device is HALTED!" branch in
> idxd_device_init_reset to be taken.
>
> [ 18.628791] idxd 0000:00:01.0: Device is HALTED!
> [ 18.631447] idxd 0000:00:01.0: Intel(R) IDXD DMA Engine init failed
> [ 18.631450] ------------[ cut here ]------------
> [ 18.631451] ida_free called for id=0 which is not allocated.
> [ 18.631462] WARNING: CPU: 0 PID: 11 at lib/idr.c:525 ida_free+0xd3/0x130
> [ 18.631474] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.12.0-1-rt-amd64 #1
> [ 18.631477] Hardware name: Dell Inc. PowerEdge XR8720t/0J91KV, BIOS 1.1.3 02/03/2026
> [ 18.631478] Workqueue: events work_for_cpu_fn
> [ 18.631480] RIP: 0010:ida_free+0xd3/0x130
> [ 18.631492] Call Trace:
> [ 18.631494] <TASK>
> [ 18.631495] idxd_pci_probe+0x1b0/0x1860 [idxd]
> [ 18.631506] local_pci_probe+0x43/0xa0
> [ 18.631508] work_for_cpu_fn+0x13/0x20
> [ 18.631510] process_one_work+0x179/0x390
> [ 18.631512] worker_thread+0x237/0x340
> [ 18.631517] kthread+0xc6/0x100
> [ 18.631520] ret_from_fork+0x2d/0x50
> [ 18.631524] ret_from_fork_asm+0x1a/0x30
> [ 18.631526] </TASK>
>
> In idxd_free and idxd_alloc, do not attempt to free allocations that
> will already have been freed.
>
> Fixes: 90022b3a6981 ("dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe")
> Fixes: 46a5cca76c76 ("dmaengine: idxd: fix memory leak in error handling path of idxd_alloc")
> Reported-by: Bogdan Codres <bogdan.codres@windriver.com>
> Link: https://lore.kernel.org/all/akLBL7b2h73pK0AC@ilogsc-qemu.local/
> Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
Missing Vinicius sign off
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/dma/idxd/init.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
> index 4b827a329756..4adb3f3bcd01 100644
> --- a/drivers/dma/idxd/init.c
> +++ b/drivers/dma/idxd/init.c
> @@ -581,9 +581,6 @@ static void idxd_free(struct idxd_device *idxd)
> return;
>
> put_device(idxd_confdev(idxd));
> - bitmap_free(idxd->opcap_bmap);
> - ida_free(&idxd_ida, idxd->id);
> - kfree(idxd);
> }
>
> static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
> @@ -623,8 +620,13 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
> return idxd;
>
> err_name:
> + /*
> + * once device_initialize(conf_dev) is called,
> + * put_device(conf_dev) will end up calling
> + * idxd_conf_device_release() which will free the rest.
> + */
> put_device(conf_dev);
> - bitmap_free(idxd->opcap_bmap);
> + return NULL;
> err_opcap:
> ida_free(&idxd_ida, idxd->id);
> err_ida:
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe error path
2026-10-12 21:38 ` [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe " Vinicius Costa Gomes
@ 2026-10-13 17:30 ` Dave Jiang
0 siblings, 0 replies; 13+ messages in thread
From: Dave Jiang @ 2026-10-13 17:30 UTC (permalink / raw)
To: Vinicius Costa Gomes, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue
Cc: dmaengine, linux-kernel
On 10/12/26 2:38 PM, Vinicius Costa Gomes wrote:
> On the probe error path the device is released via put_device() ->
> idxd_conf_device_release(), which frees idxd->wq and the idxd->wqs,
> idxd->engines, idxd->groups and idxd->wq_enable_map arrays. The
> idxd_clean_*() helpers and the idxd_setup_*() error unwind paths free
> the same objects, so they get freed twice.
>
> With commit ec2d428b2e32 ("dmaengine: idxd: fix double free of wq,
> engine, and group structs") we made use of the kobject lifetime to
> keep track of device memory allocations. These deallocations were left
> behind. Remove them as idxd_conf_device_release() is already taking
> care of that.
>
> Fixes: 3d33de353b1f ("dmaengine: idxd: Fix not releasing workqueue on .release()")
> Link: https://lore.kernel.org/all/20260615103932.61828-1-bogdan.codres@windriver.com/
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/dma/idxd/init.c | 11 -----------
> 1 file changed, 11 deletions(-)
>
> diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
> index 4adb3f3bcd01..8cf478c5b26d 100644
> --- a/drivers/dma/idxd/init.c
> +++ b/drivers/dma/idxd/init.c
> @@ -166,8 +166,6 @@ static void idxd_clean_wqs(struct idxd_device *idxd)
> conf_dev = wq_confdev(idxd->wqs[i]);
> put_device(conf_dev);
> }
> - bitmap_free(idxd->wq_enable_map);
> - kfree(idxd->wqs);
> }
>
> static int idxd_setup_wqs(struct idxd_device *idxd)
> @@ -245,11 +243,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
> conf_dev = wq_confdev(idxd->wqs[i]);
> put_device(conf_dev);
> }
> - bitmap_free(idxd->wq_enable_map);
>
> err_free_wqs:
> - kfree(idxd->wqs);
> -
> return rc;
> }
>
> @@ -262,7 +257,6 @@ static void idxd_clean_engines(struct idxd_device *idxd)
> conf_dev = engine_confdev(idxd->engines[i]);
> put_device(conf_dev);
> }
> - kfree(idxd->engines);
> }
>
> static int idxd_setup_engines(struct idxd_device *idxd)
> @@ -308,7 +302,6 @@ static int idxd_setup_engines(struct idxd_device *idxd)
> conf_dev = engine_confdev(idxd->engines[i]);
> put_device(conf_dev);
> }
> - kfree(idxd->engines);
>
> return rc;
> }
> @@ -320,7 +313,6 @@ static void idxd_clean_groups(struct idxd_device *idxd)
> for (i = 0; i < idxd->max_groups; i++) {
> put_device(group_confdev(idxd->groups[i]));
> }
> - kfree(idxd->groups);
> }
>
> static int idxd_setup_groups(struct idxd_device *idxd)
> @@ -378,7 +370,6 @@ static int idxd_setup_groups(struct idxd_device *idxd)
> group = idxd->groups[i];
> put_device(group_confdev(group));
> }
> - kfree(idxd->groups);
>
> return rc;
> }
> @@ -388,7 +379,6 @@ static void idxd_cleanup_internals(struct idxd_device *idxd)
> idxd_clean_groups(idxd);
> idxd_clean_engines(idxd);
> idxd_clean_wqs(idxd);
> - destroy_workqueue(idxd->wq);
> }
>
> static int idxd_init_evl(struct idxd_device *idxd)
> @@ -459,7 +449,6 @@ static int idxd_setup_internals(struct idxd_device *idxd)
> return 0;
>
> err_evl:
> - destroy_workqueue(idxd->wq);
> err_wkq_create:
> idxd_clean_groups(idxd);
> err_group:
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path
2026-10-13 14:57 ` Frank Li
@ 2026-10-13 22:31 ` Vinicius Costa Gomes
0 siblings, 0 replies; 13+ messages in thread
From: Vinicius Costa Gomes @ 2026-10-13 22:31 UTC (permalink / raw)
To: Frank Li
Cc: Dave Jiang, Vinod Koul, Frank Li, Fenghua Yu, Shuai Xue,
dmaengine, linux-kernel, Steve Wahl, Bogdan Codres
Frank Li <Frank.li@oss.nxp.com> writes:
> On Mon, Oct 12, 2026 at 02:38:05PM -0700, Vinicius Costa Gomes wrote:
>> From: Steve Wahl <steve.wahl@hpe.com>
>>
>> Error paths within idxd_pci_probe_alloc and related functions end
>
> idxd_pci_probe_alloc(), check other commit message.
>
Sure. Will fix those.
Cheers,
--
Vinicius
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-10-13 22:31 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 21:38 [PATCH 0/6] dmaengine: idxd: More error handling fixes Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 1/6] dmaengine: idxd: Do not call destroy_workqueue with null idxd->wq Vinicius Costa Gomes
2026-10-13 14:55 ` Frank Li
2026-10-13 17:18 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 2/6] dmaengine: idxd: fix duplicate memory frees on initialization error path Vinicius Costa Gomes
2026-10-13 14:57 ` Frank Li
2026-10-13 22:31 ` Vinicius Costa Gomes
2026-10-13 17:21 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 3/6] dmaengine: idxd: Fix potential double free on probe " Vinicius Costa Gomes
2026-10-13 17:30 ` Dave Jiang
2026-10-12 21:38 ` [PATCH 4/6] dmaengine: idxd: Fix unwind bounds in device registration error paths Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 5/6] dmaengine: idxd: Fix error code handling in idxd_cdev_open() Vinicius Costa Gomes
2026-10-12 21:38 ` [PATCH 6/6] dmaengine: idxd: Do not release interrupt handles on terminate_all Vinicius Costa Gomes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®