mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 08:43:31 +00:00
nvme: apple: fix device reference counting
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl. Split the allocation side out to make the error handling boundary easier to navigate. The apple driver had been doing this wrong, leaking the controller device memory on a tagset failure. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
parent
44348870de
commit
b9ecbfa455
1 changed files with 22 additions and 5 deletions
|
@ -1388,7 +1388,7 @@ static void devm_apple_nvme_mempool_destroy(void *data)
|
||||||
mempool_destroy(data);
|
mempool_destroy(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apple_nvme_probe(struct platform_device *pdev)
|
static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct apple_nvme *anv;
|
struct apple_nvme *anv;
|
||||||
|
@ -1396,7 +1396,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
|
anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
|
||||||
if (!anv)
|
if (!anv)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
anv->dev = get_device(dev);
|
anv->dev = get_device(dev);
|
||||||
anv->adminq.is_adminq = true;
|
anv->adminq.is_adminq = true;
|
||||||
|
@ -1516,10 +1516,26 @@ static int apple_nvme_probe(struct platform_device *pdev)
|
||||||
goto put_dev;
|
goto put_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return anv;
|
||||||
|
put_dev:
|
||||||
|
put_device(anv->dev);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apple_nvme_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct apple_nvme *anv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
anv = apple_nvme_alloc(pdev);
|
||||||
|
if (IS_ERR(anv))
|
||||||
|
return PTR_ERR(anv);
|
||||||
|
|
||||||
anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
|
anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
|
||||||
if (IS_ERR(anv->ctrl.admin_q)) {
|
if (IS_ERR(anv->ctrl.admin_q)) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto put_dev;
|
anv->ctrl.admin_q = NULL;
|
||||||
|
goto out_uninit_ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvme_reset_ctrl(&anv->ctrl);
|
nvme_reset_ctrl(&anv->ctrl);
|
||||||
|
@ -1527,8 +1543,9 @@ static int apple_nvme_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
put_dev:
|
out_uninit_ctrl:
|
||||||
put_device(anv->dev);
|
nvme_uninit_ctrl(&anv->ctrl);
|
||||||
|
nvme_put_ctrl(&anv->ctrl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue