[PATCH 1/2] drm/radeon: Make sure CS mutex is held across GPU reset.
Michel Dänzer
michel at daenzer.net
Fri Sep 16 01:40:23 PDT 2011
On Fre, 2011-09-16 at 04:31 -0400, Konrad Rzeszutek Wilk wrote:
> On Thu, Sep 15, 2011 at 08:21:00PM +0200, Michel Dänzer wrote:
> > From: Michel Dänzer <michel.daenzer at amd.com>
> >
> > This was only the case if the GPU reset was triggered from the CS ioctl,
> > otherwise other processes could happily enter the CS ioctl and wreak havoc
> > during the GPU reset.
> >
> > This is a little complicated because the GPU reset can be triggered from the
> > CS ioctl, in which case we're already holding the mutex, or from other call
> > paths, in which case we need to lock the mutex. AFAICT the mutex API doesn't
> > allow nested locking or finding out the mutex owner, so we need to handle this
> > with some helper functions.
> >
> > Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
> > ---
> > drivers/gpu/drm/radeon/radeon.h | 60 ++++++++++++++++++++++++++++++++
> > drivers/gpu/drm/radeon/radeon_cs.c | 14 ++++----
> > drivers/gpu/drm/radeon/radeon_device.c | 16 ++++++++
> > 3 files changed, 83 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> > index ef0e0e0..89304d9 100644
> > --- a/drivers/gpu/drm/radeon/radeon.h
> > +++ b/drivers/gpu/drm/radeon/radeon.h
> > @@ -1203,6 +1203,8 @@ struct radeon_device {
> > struct radeon_pm pm;
> > uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
> > struct mutex cs_mutex;
> > + struct task_struct *cs_mutex_owner;
> > + struct mutex cs_mutex_owner_mutex;
>
> That is a bit of 'mutex.. mutex'. What about just having the same
> name as before?
What do you mean? This adds a second mutex protecting the owner field.
Though now you got me thinking... Maybe the second mutex isn't necessary
at all. Let me try that.
> > +/*
> > + * Check if this process locked the CS mutex already; if it didn't, lock it.
> > + *
> > + * Returns:
> > + * true: This function locked the mutex.
> > + * false: This function didn't lock the mutex (this process already locked it
> > + * before), so the caller probably shouldn't unlock it.
> > + */
> > +static inline int cs_mutex_ensure_locked(struct radeon_device *rdev)
> > +{
> > + int took_mutex;
> > + int have_mutex;
>
> I think you meant 'bool'?
>
> > +
> > + mutex_lock(&rdev->cs_mutex_owner_mutex);
> > + took_mutex = mutex_trylock(&rdev->cs_mutex);
> > + if (took_mutex) {
> > + /* The mutex was unlocked before, so it's ours now */
> > + rdev->cs_mutex_owner = current;
> > + have_mutex = true;
>
> consider you set that here..
> > + } else {
> > + /* Somebody already locked the mutex. Was it this process? */
> > + have_mutex = (rdev->cs_mutex_owner == current);
> > + }
> > + mutex_unlock(&rdev->cs_mutex_owner_mutex);
> > +
> > + if (!have_mutex) {
> > + /* Another process locked the mutex, take it */
> > + cs_mutex_lock(rdev);
> > + took_mutex = true;
> > + }
> > +
> > + return took_mutex;
>
> and if it is really going to be bool, you might as well change the
> return signature and make it the function decleration return bool
> instead of int.
Yeah, I can change that. I'll send a v2 patch.
--
Earthling Michel Dänzer | http://www.amd.com
Libre software enthusiast | Debian, X and DRI developer
More information about the dri-devel
mailing list