> From: Zhang Qilong <zhangqilo...@huawei.com> Sent: Sunday, November 8, > 2020 5:53 PM > > 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 through adding > pm_runtime_put_noidle. > > > > Fixes: 8fff755e9f8d0 ("net: fec: Ensure clocks are enabled while using > > mdio bus") > > Signed-off-by: Zhang Qilong <zhangqilo...@huawei.com> > > From early discussion for the topic, Wolfram Sang wonder if such de-reference > can be better handled by pm runtime core code. > I have read the discussion just now, They didn't give a definite result. I agreed with introducing a new or help function to replace the pm_runtime_get_sync gradually. How do you think so ?
Regards, Zhang > https://lkml.org/lkml/2020/6/14/76 > > Regards, > Andy > > --- > > drivers/net/ethernet/freescale/fec_main.c | 22 ++++++++++++++++------ > > 1 file changed, 16 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/net/ethernet/freescale/fec_main.c > > b/drivers/net/ethernet/freescale/fec_main.c > > index d7919555250d..6c02f885c67e 100644 > > --- a/drivers/net/ethernet/freescale/fec_main.c > > +++ b/drivers/net/ethernet/freescale/fec_main.c > > @@ -1809,8 +1809,10 @@ static int fec_enet_mdio_read(struct mii_bus > > *bus, int mii_id, int regnum) > > bool is_c45 = !!(regnum & MII_ADDR_C45); > > > > ret = pm_runtime_get_sync(dev); > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put_noidle(dev); > > return ret; > > + } > > > > if (is_c45) { > > frame_start = FEC_MMFR_ST_C45; > > @@ -1868,10 +1870,12 @@ static int fec_enet_mdio_write(struct mii_bus > > *bus, int mii_id, int regnum, > > bool is_c45 = !!(regnum & MII_ADDR_C45); > > > > ret = pm_runtime_get_sync(dev); > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put_noidle(dev); > > return ret; > > - else > > + } else { > > ret = 0; > > + } > > > > if (is_c45) { > > frame_start = FEC_MMFR_ST_C45; > > @@ -2276,8 +2280,10 @@ static void fec_enet_get_regs(struct net_device > > *ndev, > > int ret; > > > > ret = pm_runtime_get_sync(dev); > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put_noidle(dev); > > return; > > + } > > > > regs->version = fec_enet_register_version; > > > > @@ -2977,8 +2983,10 @@ fec_enet_open(struct net_device *ndev) > > bool reset_again; > > > > ret = pm_runtime_get_sync(&fep->pdev->dev); > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put_noidle(&fep->pdev->dev); > > return ret; > > + } > > > > pinctrl_pm_select_default_state(&fep->pdev->dev); > > ret = fec_enet_clk_enable(ndev, true); @@ -3771,8 +3779,10 @@ > > fec_drv_remove(struct platform_device *pdev) > > int ret; > > > > ret = pm_runtime_get_sync(&pdev->dev); > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put_noidle(&pdev->dev); > > return ret; > > + } > > > > cancel_work_sync(&fep->tx_timeout_work); > > fec_ptp_stop(pdev); > > -- > > 2.25.4