Commit b9ecbfa4 authored by Keith Busch's avatar Keith Busch

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarChaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 44348870
......@@ -1388,7 +1388,7 @@ static void devm_apple_nvme_mempool_destroy(void *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 apple_nvme *anv;
......@@ -1396,7 +1396,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
if (!anv)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
anv->dev = get_device(dev);
anv->adminq.is_adminq = true;
......@@ -1516,10 +1516,26 @@ static int apple_nvme_probe(struct platform_device *pdev)
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);
if (IS_ERR(anv->ctrl.admin_q)) {
ret = -ENOMEM;
goto put_dev;
anv->ctrl.admin_q = NULL;
goto out_uninit_ctrl;
}
nvme_reset_ctrl(&anv->ctrl);
......@@ -1527,8 +1543,9 @@ static int apple_nvme_probe(struct platform_device *pdev)
return 0;
put_dev:
put_device(anv->dev);
out_uninit_ctrl:
nvme_uninit_ctrl(&anv->ctrl);
nvme_put_ctrl(&anv->ctrl);
return ret;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment