Skip to content

Commit 61259fb

Browse files
axiqiavinodkoul
authored andcommitted
dmaengine: idxd: Add missing cleanup for early error out in idxd_setup_internals
The idxd_setup_internals() is missing some cleanup when things fail in the middle. Add the appropriate cleanup routines: - cleanup groups - cleanup enginces - cleanup wqs to make sure it exits gracefully. Fixes: defe49f ("dmaengine: idxd: fix group conf_dev lifetime") Cc: stable@vger.kernel.org Suggested-by: Fenghua Yu <fenghuay@nvidia.com> Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Fenghua Yu <fenghuay@nvidia.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/20250404120217.48772-5-xueshuai@linux.alibaba.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent aa6f4f9 commit 61259fb

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

drivers/dma/idxd/init.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,25 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd)
155155
pci_free_irq_vectors(pdev);
156156
}
157157

158+
static void idxd_clean_wqs(struct idxd_device *idxd)
159+
{
160+
struct idxd_wq *wq;
161+
struct device *conf_dev;
162+
int i;
163+
164+
for (i = 0; i < idxd->max_wqs; i++) {
165+
wq = idxd->wqs[i];
166+
if (idxd->hw.wq_cap.op_config)
167+
bitmap_free(wq->opcap_bmap);
168+
kfree(wq->wqcfg);
169+
conf_dev = wq_confdev(wq);
170+
put_device(conf_dev);
171+
kfree(wq);
172+
}
173+
bitmap_free(idxd->wq_enable_map);
174+
kfree(idxd->wqs);
175+
}
176+
158177
static int idxd_setup_wqs(struct idxd_device *idxd)
159178
{
160179
struct device *dev = &idxd->pdev->dev;
@@ -245,6 +264,21 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
245264
return rc;
246265
}
247266

267+
static void idxd_clean_engines(struct idxd_device *idxd)
268+
{
269+
struct idxd_engine *engine;
270+
struct device *conf_dev;
271+
int i;
272+
273+
for (i = 0; i < idxd->max_engines; i++) {
274+
engine = idxd->engines[i];
275+
conf_dev = engine_confdev(engine);
276+
put_device(conf_dev);
277+
kfree(engine);
278+
}
279+
kfree(idxd->engines);
280+
}
281+
248282
static int idxd_setup_engines(struct idxd_device *idxd)
249283
{
250284
struct idxd_engine *engine;
@@ -296,6 +330,19 @@ static int idxd_setup_engines(struct idxd_device *idxd)
296330
return rc;
297331
}
298332

333+
static void idxd_clean_groups(struct idxd_device *idxd)
334+
{
335+
struct idxd_group *group;
336+
int i;
337+
338+
for (i = 0; i < idxd->max_groups; i++) {
339+
group = idxd->groups[i];
340+
put_device(group_confdev(group));
341+
kfree(group);
342+
}
343+
kfree(idxd->groups);
344+
}
345+
299346
static int idxd_setup_groups(struct idxd_device *idxd)
300347
{
301348
struct device *dev = &idxd->pdev->dev;
@@ -410,7 +457,7 @@ static int idxd_init_evl(struct idxd_device *idxd)
410457
static int idxd_setup_internals(struct idxd_device *idxd)
411458
{
412459
struct device *dev = &idxd->pdev->dev;
413-
int rc, i;
460+
int rc;
414461

415462
init_waitqueue_head(&idxd->cmd_waitq);
416463

@@ -441,14 +488,11 @@ static int idxd_setup_internals(struct idxd_device *idxd)
441488
err_evl:
442489
destroy_workqueue(idxd->wq);
443490
err_wkq_create:
444-
for (i = 0; i < idxd->max_groups; i++)
445-
put_device(group_confdev(idxd->groups[i]));
491+
idxd_clean_groups(idxd);
446492
err_group:
447-
for (i = 0; i < idxd->max_engines; i++)
448-
put_device(engine_confdev(idxd->engines[i]));
493+
idxd_clean_engines(idxd);
449494
err_engine:
450-
for (i = 0; i < idxd->max_wqs; i++)
451-
put_device(wq_confdev(idxd->wqs[i]));
495+
idxd_clean_wqs(idxd);
452496
err_wqs:
453497
return rc;
454498
}

0 commit comments

Comments
 (0)