Re: [PATCH v4 14/79] media: am437x: fix pm_runtime_get_sync() usage count

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Em Fri, 30 Apr 2021 17:36:46 +0100
Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> escreveu:

> On Wed, 28 Apr 2021 16:51:35 +0200
> Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> wrote:
> 
> > The pm_runtime_get_sync() internally increments the
> > dev->power.usage_count without decrementing it, even on errors.
> > Replace it by the new pm_runtime_resume_and_get(), introduced by:
> > commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
> > in order to properly decrement the usage counter and avoid memory
> > leaks.
> > 
> > While here, ensure that the driver will check if PM runtime
> > resumed at vpfe_initialize_device().
> > 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>  
> 
> resume and suspend carrying regardless needs a comment I think.
> (see below)
> > ---
> >  drivers/media/platform/am437x/am437x-vpfe.c | 22 +++++++++++++++------
> >  1 file changed, 16 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
> > index 6cdc77dda0e4..bced526f30f2 100644
> > --- a/drivers/media/platform/am437x/am437x-vpfe.c
> > +++ b/drivers/media/platform/am437x/am437x-vpfe.c
> > @@ -1021,7 +1021,9 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe)
> >  	if (ret)
> >  		return ret;
> >  
> > -	pm_runtime_get_sync(vpfe->pdev);
> > +	ret = pm_runtime_resume_and_get(vpfe->pdev);
> > +	if (ret < 0)
> > +		return ret;
> >  
> >  	vpfe_config_enable(&vpfe->ccdc, 1);
> >  
> > @@ -2443,7 +2445,11 @@ static int vpfe_probe(struct platform_device *pdev)
> >  	pm_runtime_enable(&pdev->dev);
> >  
> >  	/* for now just enable it here instead of waiting for the open */
> > -	pm_runtime_get_sync(&pdev->dev);
> > +	ret = pm_runtime_resume_and_get(&pdev->dev);
> > +	if (ret < 0) {
> > +		vpfe_err(vpfe, "Unable to resume device.\n");
> > +		goto probe_out_v4l2_unregister;
> > +	}
> >  
> >  	vpfe_ccdc_config_defaults(ccdc);
> >  
> > @@ -2527,10 +2533,11 @@ static int vpfe_suspend(struct device *dev)
> >  {
> >  	struct vpfe_device *vpfe = dev_get_drvdata(dev);
> >  	struct vpfe_ccdc *ccdc = &vpfe->ccdc;
> > +	int ret;
> >  
> >  	/* only do full suspend if streaming has started */
> >  	if (vb2_start_streaming_called(&vpfe->buffer_queue)) {
> > -		pm_runtime_get_sync(dev);
> > +		ret = pm_runtime_resume_and_get(dev);  
> 
> Carrying on when you know the resume failed, seems interesting enough to
> deserve a comment in the code.  Not sure you can usefully do anything
> but it seems likely a lot of the calls that follow will fail.

This driver indeed has a different behavior. What most drivers do is to
either resume RPM when a V4L2 devnode is opened, or when the device
starts to stream. This one does, instead, at probing time. 

It even has a comment there which implies that this is something that may
require changes in the future:

    static int vpfe_probe(struct platform_device *pdev)
    {
...
	/* for now just enable it here instead of waiting for the open */
	ret = pm_runtime_resume_and_get(&pdev->dev);

After probe, the driver just assumes that RPM is not suspended during its 
entire lifetime (except suspend/resuume).

I can't even see a check at vpfe_open() or at vpfe_start_streaming()
that would cause the functions to fail if, for whatever reason, RPM is
suspended there[1], or if a command sent to the hardware failed.

[1] The only place where there's a check is at v4l2_subdev_call(),
    asking sensors to start streaming. If those are on a different
    power domain, a valid sensor answer call won't ensure that 
    am437x VPFE is operational.

Yet, suspend/resume only checks if videobuf2 started its streaming
logic. if streaming was started, suspend/resume logic tries ensure
that the hardware will be ready to be suspended, restoring it to
the previous state before at resume time, but neither one of those
has a check to see if the commands were succeeded, just like the
logic at vpfe_start_streaming().

-

In summary, I'll add a comment there, but fixing it would require 
adding error checks on several places (open, start_streaming,
resume and suspend).

Thanks,
Mauro



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux