> 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

Reply via email to