summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKeith Busch <kbusch@kernel.org>2024-11-26 15:46:57 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-09 10:31:42 +0100
commitf7d9a18572fcd7130459b7691bd19ee2a2e951ad (patch)
tree0c7fb9cced98e0c1826d15fd622cecac3beed165 /drivers
parent3820b0fac7732a653bcc6f6ac20c1d72e697f8f6 (diff)
downloadlinux-f7d9a18572fcd7130459b7691bd19ee2a2e951ad.tar.gz
linux-f7d9a18572fcd7130459b7691bd19ee2a2e951ad.tar.bz2
linux-f7d9a18572fcd7130459b7691bd19ee2a2e951ad.zip
nvme: apple: fix device reference counting
[ Upstream commit b9ecbfa45516182cd062fecd286db7907ba84210 ] 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> [ Resolve minor conflicts ] Signed-off-by: Bin Lan <bin.lan.cn@windriver.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvme/host/apple.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
index 596bb11eeba5..396eb9437659 100644
--- a/drivers/nvme/host/apple.c
+++ b/drivers/nvme/host/apple.c
@@ -1387,7 +1387,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;
@@ -1395,7 +1395,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;
@@ -1515,10 +1515,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_init_queue(&anv->admin_tagset);
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);
@@ -1526,8 +1542,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;
}