]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
soc: ti: Fix reference imbalance in knav_dma_probe
authorZhang Qilong <zhangqilong3@huawei.com>
Sun, 22 Nov 2020 03:22:37 +0000 (19:22 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Dec 2020 12:42:36 +0000 (13:42 +0100)
[ Upstream commit b4fa73358c306d747a2200aec6f7acb97e5750e6 ]

The patch fix two reference leak.

  1) pm_runtime_get_sync will increment pm usage counter even it
     failed. Forgetting to call put operation will result in
     reference leak.

  2) The pm_runtime_enable will increase power disable depth. Thus
     a pairing decrement is needed on the error handling path to
     keep it balanced.

We fix it by: 1) adding call pm_runtime_put_noidle or
pm_runtime_put_sync in error handling. 2) adding pm_runtime_disable
in error handling, to keep usage counter and disable depth balanced.

Fixes: 88139ed030583 ("soc: ti: add Keystone Navigator DMA support")
Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/soc/ti/knav_dma.c

index bc1b80ec6afe32a3ac6df7c0e238972531988764..838b87adf48bb8682ad8abceeb3d0dc243b9ca6b 100644 (file)
@@ -752,8 +752,9 @@ static int knav_dma_probe(struct platform_device *pdev)
        pm_runtime_enable(kdev->dev);
        ret = pm_runtime_get_sync(kdev->dev);
        if (ret < 0) {
+               pm_runtime_put_noidle(kdev->dev);
                dev_err(kdev->dev, "unable to enable pktdma, err %d\n", ret);
-               return ret;
+               goto err_pm_disable;
        }
 
        /* Initialise all packet dmas */
@@ -767,13 +768,21 @@ static int knav_dma_probe(struct platform_device *pdev)
 
        if (list_empty(&kdev->list)) {
                dev_err(dev, "no valid dma instance\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_put_sync;
        }
 
        debugfs_create_file("knav_dma", S_IFREG | S_IRUGO, NULL, NULL,
                            &knav_dma_debug_ops);
 
        return ret;
+
+err_put_sync:
+       pm_runtime_put_sync(kdev->dev);
+err_pm_disable:
+       pm_runtime_disable(kdev->dev);
+
+       return ret;
 }
 
 static int knav_dma_remove(struct platform_device *pdev)