[Intel-xe] [PATCH 1/2] drm/xe/pm: Wrap pm_runtime_suspended with power.lock
Gupta, Anshuman
anshuman.gupta at intel.com
Mon Jun 19 11:18:03 UTC 2023
> -----Original Message-----
> From: Brost, Matthew <matthew.brost at intel.com>
> Sent: Saturday, June 17, 2023 1:35 AM
> To: Gupta, Anshuman <anshuman.gupta at intel.com>
> Cc: intel-xe at lists.freedesktop.org; Nilawar, Badal
> <badal.nilawar at intel.com>; Vivi, Rodrigo <rodrigo.vivi at intel.com>; Tauro,
> Riana <riana.tauro at intel.com>; Sundaresan, Sujaritha
> <sujaritha.sundaresan at intel.com>
> Subject: Re: [PATCH 1/2] drm/xe/pm: Wrap pm_runtime_suspended with
> power.lock
>
> On Fri, Jun 16, 2023 at 07:41:14PM +0530, Anshuman Gupta wrote:
> > pm_runtime_suspended() doc has requirement to use it with PM lock of
> > @dev to get the trusted value.
> > Wrap pm_runtime_suspended within xe_pm_runtime_suspended() with
> proper
> > locking.
> >
> > Signed-off-by: Anshuman Gupta <anshuman.gupta at intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_pm.c | 16 ++++++++++++++--
> > 1 file changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
> > index b7b57f10ba25..04c5353ba870 100644
> > --- a/drivers/gpu/drm/xe/xe_pm.c
> > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > @@ -210,11 +210,23 @@ int xe_pm_runtime_put(struct xe_device *xe)
> > return pm_runtime_put_autosuspend(xe->drm.dev);
> > }
> >
> > +static bool xe_pm_runtime_suspended(struct xe_device *xe) {
> > + unsigned long flags;
> > + bool suspended;
> > +
> > + spin_lock_irqsave(&xe->drm.dev->power.lock, flags);
> > + suspended = pm_runtime_suspended(xe->drm.dev);
> > + spin_unlock_irqrestore(&xe->drm.dev->power.lock, flags);
>
> A few things.
>
> First, you probably can make this spin_lock_irq / spin_unlock_irq as IRQ
> contexts are not really used in Xe it is doubtful this function would ever be
> called from an unknown context.
Thanks for review , I will fix this.
>
> Second, I have questions if this patch is actually doing anything useful. Yes, I
> can see doc which indicates that pm_runtime_suspended can only be
> trusted if the lock is held but looking at the code paths where
> xe_pm_runtime_suspended is called unsure how this lock helps.
>
> e.g. How is this better?
This is helpful in case, when pm_runtime_suspended() returns status is RPM_SUSPENDING and it will be going to change to RPM_SUPENDED,
rpm_suspend() changes the runtime status from RPM_ACTIVE -> RPM_SUSPENDING -> driver->runtime_suspend() callback -> RPM_SUSPENDED
https://elixir.bootlin.com/linux/latest/source/drivers/base/power/runtime.c#L558
rpm_suspend() caller has already grabbed the lock and RPM status changed to RPM_SUSPENDING, therefore Xe has to wait to grab the lock to get the trusted value, which is RPM_SUSPENDED.
Without a proper lock, the xe driver may access the vram while the device was runtime suspended, which is a violation of PCIe specs.> if (trusted value)
> now the trusted value can change, do something
The other way around is if Xe has grabbed the lock first then the possible runtime status is either RPM_ACTIVE or RUNTIME_SUPENDED for both Xe is increasing usage
ref count explicitly to make sure the device is in an active state.
Thanks ,
Anshuman Gupta.
>
>
> Than?
> if (untrusted value)
> do something
> Also if you look all over kernel pm_runtime_suspended is called frequently
> dev->power.lock.
>
> Matt
>
> > +
> > + return suspended;
> > +}
> > +
> > /* Return true if resume operation happened and usage count was
> > increased */ bool xe_pm_runtime_resume_if_suspended(struct
> xe_device
> > *xe) {
> > /* In case we are suspended we need to immediately wake up */
> > - if (pm_runtime_suspended(xe->drm.dev))
> > + if (xe_pm_runtime_suspended(xe))
> > return !pm_runtime_resume_and_get(xe->drm.dev);
> >
> > return false;
> > @@ -222,6 +234,6 @@ bool xe_pm_runtime_resume_if_suspended(struct
> > xe_device *xe)
> >
> > int xe_pm_runtime_get_if_active(struct xe_device *xe) {
> > - WARN_ON(pm_runtime_suspended(xe->drm.dev));
> > + WARN_ON(xe_pm_runtime_suspended(xe));
> > return pm_runtime_get_if_active(xe->drm.dev, true); }
> > --
> > 2.38.0
> >
More information about the Intel-xe
mailing list