From patchwork Mon Nov 9 08:09:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Qilong X-Patchwork-Id: 321729 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7145C4741F for ; Mon, 9 Nov 2020 08:05:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6299A21D93 for ; Mon, 9 Nov 2020 08:05:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729743AbgKIIFz (ORCPT ); Mon, 9 Nov 2020 03:05:55 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:7617 "EHLO szxga05-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729730AbgKIIFy (ORCPT ); Mon, 9 Nov 2020 03:05:54 -0500 Received: from DGGEMS411-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4CV3TJ3tqqzLty0; Mon, 9 Nov 2020 16:05:40 +0800 (CST) Received: from huawei.com (10.175.127.227) by DGGEMS411-HUB.china.huawei.com (10.3.19.211) with Microsoft SMTP Server id 14.3.487.0; Mon, 9 Nov 2020 16:05:49 +0800 From: Zhang Qilong To: , , , CC: , Subject: [PATCH 1/2] PM: runtime: Add a general runtime get sync operation to deal with usage counter Date: Mon, 9 Nov 2020 16:09:37 +0800 Message-ID: <20201109080938.4174745-2-zhangqilong3@huawei.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201109080938.4174745-1-zhangqilong3@huawei.com> References: <20201109080938.4174745-1-zhangqilong3@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org In many case, we need to check return value of pm_runtime_get_sync, but it brings a trouble to the usage counter processing. Many callers forget to decrease the usage counter when it failed. It has been discussed a lot[0][1]. So we add a function to deal with the usage counter for better coding. [0]https://lkml.org/lkml/2020/6/14/88 [1]https://patchwork.ozlabs.org/project/linux-tegra/patch/20200520095148.10995-1-dinghao.liu@zju.edu.cn/ Signed-off-by: Zhang Qilong --- include/linux/pm_runtime.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 4b708f4e8eed..2b0af5b1dffd 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -386,6 +386,38 @@ static inline int pm_runtime_get_sync(struct device *dev) return __pm_runtime_resume(dev, RPM_GET_PUT); } +/** + * gene_pm_runtime_get_sync - Bump up usage counter of a device and resume it. + * @dev: Target device. + * + * Increase runtime PM usage counter of @dev first, and carry out runtime-resume + * of it synchronously. If __pm_runtime_resume return negative value(device is in + * error state) or return positive value(the runtime of device is already active) + * with force is true, it need decrease the usage counter of the device when + * return. + * + * The possible return values of this function is zero or negative value. + * zero: + * - it means success and the status will store the resume operation status + * if needed, the runtime PM usage counter of @dev remains incremented. + * negative: + * - it means failure and the runtime PM usage counter of @dev has been + * decreased. + * positive: + * - it means the runtime of the device is already active before that. If + * caller set force to true, we still need to decrease the usage counter. + */ +static inline int gene_pm_runtime_get_sync(struct device *dev, bool force) +{ + int ret = 0; + + ret = __pm_runtime_resume(dev, RPM_GET_PUT); + if (ret < 0 || (ret > 0 && force)) + pm_runtime_put_noidle(dev); + + return ret; +} + /** * pm_runtime_put - Drop device usage counter and queue up "idle check" if 0. * @dev: Target device. From patchwork Mon Nov 9 08:09:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Qilong X-Patchwork-Id: 323426 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C2B8C4741F for ; Mon, 9 Nov 2020 08:06:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0D6721534 for ; Mon, 9 Nov 2020 08:05:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729092AbgKIIF7 (ORCPT ); Mon, 9 Nov 2020 03:05:59 -0500 Received: from szxga07-in.huawei.com ([45.249.212.35]:7435 "EHLO szxga07-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729730AbgKIIF7 (ORCPT ); Mon, 9 Nov 2020 03:05:59 -0500 Received: from DGGEMS411-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4CV3TT05hBz73nD; Mon, 9 Nov 2020 16:05:49 +0800 (CST) Received: from huawei.com (10.175.127.227) by DGGEMS411-HUB.china.huawei.com (10.3.19.211) with Microsoft SMTP Server id 14.3.487.0; Mon, 9 Nov 2020 16:05:50 +0800 From: Zhang Qilong To: , , , CC: , Subject: [PATCH 2/2] net: fec: Fix reference count leak in fec series ops Date: Mon, 9 Nov 2020 16:09:38 +0800 Message-ID: <20201109080938.4174745-3-zhangqilong3@huawei.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201109080938.4174745-1-zhangqilong3@huawei.com> References: <20201109080938.4174745-1-zhangqilong3@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org pm_runtime_get_sync() will increment pm usage at first and it will resume the device later. If runtime of the device has error or device is in inaccessible state(or other error state), resume operation will fail. If we do not call put operation to decrease the reference, it will result in reference count leak. Moreover, this device cannot enter the idle state and always stay busy or other non-idle state later. So we fixed it by replacing it with gene_pm_runtime_get_sync. Fixes: 8fff755e9f8d0 ("net: fec: Ensure clocks are enabled while using mdio bus") Signed-off-by: Zhang Qilong --- drivers/net/ethernet/freescale/fec_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d7919555250d..f3f632bf3676 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1808,7 +1808,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) int ret = 0, frame_start, frame_addr, frame_op; bool is_c45 = !!(regnum & MII_ADDR_C45); - ret = pm_runtime_get_sync(dev); + ret = gene_pm_runtime_get_sync(dev, false); if (ret < 0) return ret; @@ -1867,7 +1867,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, int ret, frame_start, frame_addr; bool is_c45 = !!(regnum & MII_ADDR_C45); - ret = pm_runtime_get_sync(dev); + ret = gene_pm_runtime_get_sync(dev, false); if (ret < 0) return ret; else @@ -2275,7 +2275,7 @@ static void fec_enet_get_regs(struct net_device *ndev, u32 i, off; int ret; - ret = pm_runtime_get_sync(dev); + ret = gene_pm_runtime_get_sync(dev, false); if (ret < 0) return; @@ -2976,7 +2976,7 @@ fec_enet_open(struct net_device *ndev) int ret; bool reset_again; - ret = pm_runtime_get_sync(&fep->pdev->dev); + ret = gene_pm_runtime_get_sync(&fep->pdev->dev, false); if (ret < 0) return ret; @@ -3770,7 +3770,7 @@ fec_drv_remove(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; int ret; - ret = pm_runtime_get_sync(&pdev->dev); + ret = gene_pm_runtime_get_sync(&pdev->dev, false); if (ret < 0) return ret;