Skip to content

Commit 46a5cca

Browse files
axiqiavinodkoul
authored andcommitted
dmaengine: idxd: fix memory leak in error handling path of idxd_alloc
Memory allocated for idxd is not freed if an error occurs during idxd_alloc(). To fix it, free the allocated memory in the reverse order of allocation before exiting the function in case of an error. Fixes: a8563a3 ("dmanegine: idxd: reformat opcap output to match bitmap_parse() input") Cc: stable@vger.kernel.org Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Fenghua Yu <fenghuay@nvidia.com> Link: https://lore.kernel.org/r/20250404120217.48772-7-xueshuai@linux.alibaba.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 61d6515 commit 46a5cca

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

drivers/dma/idxd/init.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -604,28 +604,34 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
604604
idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type);
605605
idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL);
606606
if (idxd->id < 0)
607-
return NULL;
607+
goto err_ida;
608608

609609
idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
610-
if (!idxd->opcap_bmap) {
611-
ida_free(&idxd_ida, idxd->id);
612-
return NULL;
613-
}
610+
if (!idxd->opcap_bmap)
611+
goto err_opcap;
614612

615613
device_initialize(conf_dev);
616614
conf_dev->parent = dev;
617615
conf_dev->bus = &dsa_bus_type;
618616
conf_dev->type = idxd->data->dev_type;
619617
rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id);
620-
if (rc < 0) {
621-
put_device(conf_dev);
622-
return NULL;
623-
}
618+
if (rc < 0)
619+
goto err_name;
624620

625621
spin_lock_init(&idxd->dev_lock);
626622
spin_lock_init(&idxd->cmd_lock);
627623

628624
return idxd;
625+
626+
err_name:
627+
put_device(conf_dev);
628+
bitmap_free(idxd->opcap_bmap);
629+
err_opcap:
630+
ida_free(&idxd_ida, idxd->id);
631+
err_ida:
632+
kfree(idxd);
633+
634+
return NULL;
629635
}
630636

631637
static int idxd_enable_system_pasid(struct idxd_device *idxd)

0 commit comments

Comments
 (0)