All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	VMware Graphics <linux-graphics-maintainer@vmware.com>,
	Zack Rusin <zackr@vmware.com>, Dave Airlie <airlied@linux.ie>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	intel-gfx <intel-gfx@lists.freedesktop.org>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Greg KH <gregkh@linuxfoundation.org>,
	linux-kernel-mentees@lists.linuxfoundation.org
Subject: Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
Date: Thu, 22 Jul 2021 21:02:41 +0200	[thread overview]
Message-ID: <CAKMK7uGSc_YMf2e=oA23KeAvC8i_pqJBU82v8oRGfnwsT41WLQ@mail.gmail.com> (raw)
In-Reply-To: <YPmJEYrnB0j17cZV@boqun-archlinux>

On Thu, Jul 22, 2021 at 6:00 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> On Thu, Jul 22, 2021 at 12:38:10PM +0200, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:27PM +0800, Desmond Cheong Zhi Xi wrote:
> > > Inside drm_is_current_master, using the outer drm_device.master_mutex
> > > to protect reads of drm_file.master makes the function prone to creating
> > > lock hierarchy inversions. Instead, we can use the
> > > drm_file.master_lookup_lock that sits at the bottom of the lock
> > > hierarchy.
> > >
> > > Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> > > ---
> > >  drivers/gpu/drm/drm_auth.c | 9 +++++----
> > >  1 file changed, 5 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> > > index f00354bec3fb..9c24b8cc8e36 100644
> > > --- a/drivers/gpu/drm/drm_auth.c
> > > +++ b/drivers/gpu/drm/drm_auth.c
> > > @@ -63,8 +63,9 @@
> > >
> > >  static bool drm_is_current_master_locked(struct drm_file *fpriv)
> > >  {
> > > -   lockdep_assert_held_once(&fpriv->minor->dev->master_mutex);
> > > -
> > > +   /* Either drm_device.master_mutex or drm_file.master_lookup_lock
> > > +    * should be held here.
> > > +    */
> >
> > Disappointing that lockdep can't check or conditions for us, a
> > lockdep_assert_held_either would be really neat in some cases.
> >
>
> The implementation is not hard but I don't understand the usage, for
> example, if we have a global variable x, and two locks L1 and L2, and
> the function
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_either(L1, L2);
>                 x++;
>         }
>
> and two call sites:
>
>         void f(void)
>         {
>                 lock(L1);
>                 do_something_to_x();
>                 unlock(L1);
>         }
>
>         void g(void)
>         {
>                 lock(L2);
>                 do_something_to_x();
>                 unlock(L2);
>         }
>
> , wouldn't it be racy if f() and g() called by two threads at the same
> time? Usually I would expect there exists a third synchronazition
> mechanism (say M), which synchronizes the calls to f() and g(), and we
> put M in the lockdep_assert_held() check inside do_something_to_x()
> like:
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_once(M);
>                 x++;
>         }
>
> But of course, M may not be a lock, so we cannot put the assert there.
>
> My cscope failed to find ->master_lookup_lock in -rc2 and seems it's not
> introduced in the patchset either, could you point me the branch this
> patchset is based on, so that I could understand this better, and maybe
> come up with a solution? Thanks ;-)

The use case is essentially 2 nesting locks, and only the innermost is
used to update a field. So when you only read this field, it's safe if
either of these two locks are held. Essentially this is a read/write lock
type of thing, except for various reasons the two locks might not be of
the same type (like here where the write lock is a mutex, but the read
lock is a spinlock).

It's a bit like the rcu_derefence macro where it's ok to either be in a
rcu_read_lock() section, or holding the relevant lock that's used to
update the value. We do _not_ have two different locks that allow writing
to the same X.

Does that make it clearer what's the use-case here?

In an example:

void * interesting_pointer.

do_update_interesting_pointer()
{
	mutex_lock(A);
	/* do more stuff to prepare things */
	spin_lock(B);
	interesting_pointer = new_value;
	spin_unlock(B);
	mutex_unlock(A);
}

read_interesting_thing_locked()
{
	lockdep_assert_held_either(A, B);

	return interesting_pointer->thing;
}

read_interesting_thing()
{
	int thing;
	spin_lock(B);
	thing = interesting_pointer->thing;
	spin_unlock(B);

	return B;
}

spinlock might also be irqsafe here if this can be called from irq
context.

Cheers, Daniel

> Regards,
> Boqun
>
> > Adding lockdep folks, maybe they have ideas.
> >
> > On the patch:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > >     return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> > >  }
> > >
> > > @@ -82,9 +83,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
> > >  {
> > >     bool ret;
> > >
> > > -   mutex_lock(&fpriv->minor->dev->master_mutex);
> > > +   spin_lock(&fpriv->master_lookup_lock);
> > >     ret = drm_is_current_master_locked(fpriv);
> > > -   mutex_unlock(&fpriv->minor->dev->master_mutex);
> > > +   spin_unlock(&fpriv->master_lookup_lock);
> > >
> > >     return ret;
> > >  }
> > > --
> > > 2.25.1
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Vetter <daniel@ffwll.ch>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Greg KH <gregkh@linuxfoundation.org>,
	intel-gfx <intel-gfx@lists.freedesktop.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Maxime Ripard <mripard@kernel.org>,
	Dave Airlie <airlied@linux.ie>,
	VMware Graphics <linux-graphics-maintainer@vmware.com>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>,
	linux-kernel-mentees@lists.linuxfoundation.org,
	Zack Rusin <zackr@vmware.com>
Subject: Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
Date: Thu, 22 Jul 2021 21:02:41 +0200	[thread overview]
Message-ID: <CAKMK7uGSc_YMf2e=oA23KeAvC8i_pqJBU82v8oRGfnwsT41WLQ@mail.gmail.com> (raw)
In-Reply-To: <YPmJEYrnB0j17cZV@boqun-archlinux>

On Thu, Jul 22, 2021 at 6:00 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> On Thu, Jul 22, 2021 at 12:38:10PM +0200, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:27PM +0800, Desmond Cheong Zhi Xi wrote:
> > > Inside drm_is_current_master, using the outer drm_device.master_mutex
> > > to protect reads of drm_file.master makes the function prone to creating
> > > lock hierarchy inversions. Instead, we can use the
> > > drm_file.master_lookup_lock that sits at the bottom of the lock
> > > hierarchy.
> > >
> > > Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> > > ---
> > >  drivers/gpu/drm/drm_auth.c | 9 +++++----
> > >  1 file changed, 5 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> > > index f00354bec3fb..9c24b8cc8e36 100644
> > > --- a/drivers/gpu/drm/drm_auth.c
> > > +++ b/drivers/gpu/drm/drm_auth.c
> > > @@ -63,8 +63,9 @@
> > >
> > >  static bool drm_is_current_master_locked(struct drm_file *fpriv)
> > >  {
> > > -   lockdep_assert_held_once(&fpriv->minor->dev->master_mutex);
> > > -
> > > +   /* Either drm_device.master_mutex or drm_file.master_lookup_lock
> > > +    * should be held here.
> > > +    */
> >
> > Disappointing that lockdep can't check or conditions for us, a
> > lockdep_assert_held_either would be really neat in some cases.
> >
>
> The implementation is not hard but I don't understand the usage, for
> example, if we have a global variable x, and two locks L1 and L2, and
> the function
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_either(L1, L2);
>                 x++;
>         }
>
> and two call sites:
>
>         void f(void)
>         {
>                 lock(L1);
>                 do_something_to_x();
>                 unlock(L1);
>         }
>
>         void g(void)
>         {
>                 lock(L2);
>                 do_something_to_x();
>                 unlock(L2);
>         }
>
> , wouldn't it be racy if f() and g() called by two threads at the same
> time? Usually I would expect there exists a third synchronazition
> mechanism (say M), which synchronizes the calls to f() and g(), and we
> put M in the lockdep_assert_held() check inside do_something_to_x()
> like:
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_once(M);
>                 x++;
>         }
>
> But of course, M may not be a lock, so we cannot put the assert there.
>
> My cscope failed to find ->master_lookup_lock in -rc2 and seems it's not
> introduced in the patchset either, could you point me the branch this
> patchset is based on, so that I could understand this better, and maybe
> come up with a solution? Thanks ;-)

The use case is essentially 2 nesting locks, and only the innermost is
used to update a field. So when you only read this field, it's safe if
either of these two locks are held. Essentially this is a read/write lock
type of thing, except for various reasons the two locks might not be of
the same type (like here where the write lock is a mutex, but the read
lock is a spinlock).

It's a bit like the rcu_derefence macro where it's ok to either be in a
rcu_read_lock() section, or holding the relevant lock that's used to
update the value. We do _not_ have two different locks that allow writing
to the same X.

Does that make it clearer what's the use-case here?

In an example:

void * interesting_pointer.

do_update_interesting_pointer()
{
	mutex_lock(A);
	/* do more stuff to prepare things */
	spin_lock(B);
	interesting_pointer = new_value;
	spin_unlock(B);
	mutex_unlock(A);
}

read_interesting_thing_locked()
{
	lockdep_assert_held_either(A, B);

	return interesting_pointer->thing;
}

read_interesting_thing()
{
	int thing;
	spin_lock(B);
	thing = interesting_pointer->thing;
	spin_unlock(B);

	return B;
}

spinlock might also be irqsafe here if this can be called from irq
context.

Cheers, Daniel

> Regards,
> Boqun
>
> > Adding lockdep folks, maybe they have ideas.
> >
> > On the patch:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > >     return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> > >  }
> > >
> > > @@ -82,9 +83,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
> > >  {
> > >     bool ret;
> > >
> > > -   mutex_lock(&fpriv->minor->dev->master_mutex);
> > > +   spin_lock(&fpriv->master_lookup_lock);
> > >     ret = drm_is_current_master_locked(fpriv);
> > > -   mutex_unlock(&fpriv->minor->dev->master_mutex);
> > > +   spin_unlock(&fpriv->master_lookup_lock);
> > >
> > >     return ret;
> > >  }
> > > --
> > > 2.25.1
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Vetter <daniel@ffwll.ch>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	intel-gfx <intel-gfx@lists.freedesktop.org>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Maxime Ripard <mripard@kernel.org>,
	Dave Airlie <airlied@linux.ie>,
	VMware Graphics <linux-graphics-maintainer@vmware.com>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>,
	linux-kernel-mentees@lists.linuxfoundation.org,
	Zack Rusin <zackr@vmware.com>
Subject: Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
Date: Thu, 22 Jul 2021 21:02:41 +0200	[thread overview]
Message-ID: <CAKMK7uGSc_YMf2e=oA23KeAvC8i_pqJBU82v8oRGfnwsT41WLQ@mail.gmail.com> (raw)
In-Reply-To: <YPmJEYrnB0j17cZV@boqun-archlinux>

On Thu, Jul 22, 2021 at 6:00 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> On Thu, Jul 22, 2021 at 12:38:10PM +0200, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:27PM +0800, Desmond Cheong Zhi Xi wrote:
> > > Inside drm_is_current_master, using the outer drm_device.master_mutex
> > > to protect reads of drm_file.master makes the function prone to creating
> > > lock hierarchy inversions. Instead, we can use the
> > > drm_file.master_lookup_lock that sits at the bottom of the lock
> > > hierarchy.
> > >
> > > Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> > > ---
> > >  drivers/gpu/drm/drm_auth.c | 9 +++++----
> > >  1 file changed, 5 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> > > index f00354bec3fb..9c24b8cc8e36 100644
> > > --- a/drivers/gpu/drm/drm_auth.c
> > > +++ b/drivers/gpu/drm/drm_auth.c
> > > @@ -63,8 +63,9 @@
> > >
> > >  static bool drm_is_current_master_locked(struct drm_file *fpriv)
> > >  {
> > > -   lockdep_assert_held_once(&fpriv->minor->dev->master_mutex);
> > > -
> > > +   /* Either drm_device.master_mutex or drm_file.master_lookup_lock
> > > +    * should be held here.
> > > +    */
> >
> > Disappointing that lockdep can't check or conditions for us, a
> > lockdep_assert_held_either would be really neat in some cases.
> >
>
> The implementation is not hard but I don't understand the usage, for
> example, if we have a global variable x, and two locks L1 and L2, and
> the function
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_either(L1, L2);
>                 x++;
>         }
>
> and two call sites:
>
>         void f(void)
>         {
>                 lock(L1);
>                 do_something_to_x();
>                 unlock(L1);
>         }
>
>         void g(void)
>         {
>                 lock(L2);
>                 do_something_to_x();
>                 unlock(L2);
>         }
>
> , wouldn't it be racy if f() and g() called by two threads at the same
> time? Usually I would expect there exists a third synchronazition
> mechanism (say M), which synchronizes the calls to f() and g(), and we
> put M in the lockdep_assert_held() check inside do_something_to_x()
> like:
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_once(M);
>                 x++;
>         }
>
> But of course, M may not be a lock, so we cannot put the assert there.
>
> My cscope failed to find ->master_lookup_lock in -rc2 and seems it's not
> introduced in the patchset either, could you point me the branch this
> patchset is based on, so that I could understand this better, and maybe
> come up with a solution? Thanks ;-)

The use case is essentially 2 nesting locks, and only the innermost is
used to update a field. So when you only read this field, it's safe if
either of these two locks are held. Essentially this is a read/write lock
type of thing, except for various reasons the two locks might not be of
the same type (like here where the write lock is a mutex, but the read
lock is a spinlock).

It's a bit like the rcu_derefence macro where it's ok to either be in a
rcu_read_lock() section, or holding the relevant lock that's used to
update the value. We do _not_ have two different locks that allow writing
to the same X.

Does that make it clearer what's the use-case here?

In an example:

void * interesting_pointer.

do_update_interesting_pointer()
{
	mutex_lock(A);
	/* do more stuff to prepare things */
	spin_lock(B);
	interesting_pointer = new_value;
	spin_unlock(B);
	mutex_unlock(A);
}

read_interesting_thing_locked()
{
	lockdep_assert_held_either(A, B);

	return interesting_pointer->thing;
}

read_interesting_thing()
{
	int thing;
	spin_lock(B);
	thing = interesting_pointer->thing;
	spin_unlock(B);

	return B;
}

spinlock might also be irqsafe here if this can be called from irq
context.

Cheers, Daniel

> Regards,
> Boqun
>
> > Adding lockdep folks, maybe they have ideas.
> >
> > On the patch:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > >     return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> > >  }
> > >
> > > @@ -82,9 +83,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
> > >  {
> > >     bool ret;
> > >
> > > -   mutex_lock(&fpriv->minor->dev->master_mutex);
> > > +   spin_lock(&fpriv->master_lookup_lock);
> > >     ret = drm_is_current_master_locked(fpriv);
> > > -   mutex_unlock(&fpriv->minor->dev->master_mutex);
> > > +   spin_unlock(&fpriv->master_lookup_lock);
> > >
> > >     return ret;
> > >  }
> > > --
> > > 2.25.1
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Vetter <daniel@ffwll.ch>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Greg KH <gregkh@linuxfoundation.org>,
	intel-gfx <intel-gfx@lists.freedesktop.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Dave Airlie <airlied@linux.ie>,
	VMware Graphics <linux-graphics-maintainer@vmware.com>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>,
	linux-kernel-mentees@lists.linuxfoundation.org
Subject: Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
Date: Thu, 22 Jul 2021 21:02:41 +0200	[thread overview]
Message-ID: <CAKMK7uGSc_YMf2e=oA23KeAvC8i_pqJBU82v8oRGfnwsT41WLQ@mail.gmail.com> (raw)
In-Reply-To: <YPmJEYrnB0j17cZV@boqun-archlinux>

On Thu, Jul 22, 2021 at 6:00 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> On Thu, Jul 22, 2021 at 12:38:10PM +0200, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:27PM +0800, Desmond Cheong Zhi Xi wrote:
> > > Inside drm_is_current_master, using the outer drm_device.master_mutex
> > > to protect reads of drm_file.master makes the function prone to creating
> > > lock hierarchy inversions. Instead, we can use the
> > > drm_file.master_lookup_lock that sits at the bottom of the lock
> > > hierarchy.
> > >
> > > Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> > > ---
> > >  drivers/gpu/drm/drm_auth.c | 9 +++++----
> > >  1 file changed, 5 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> > > index f00354bec3fb..9c24b8cc8e36 100644
> > > --- a/drivers/gpu/drm/drm_auth.c
> > > +++ b/drivers/gpu/drm/drm_auth.c
> > > @@ -63,8 +63,9 @@
> > >
> > >  static bool drm_is_current_master_locked(struct drm_file *fpriv)
> > >  {
> > > -   lockdep_assert_held_once(&fpriv->minor->dev->master_mutex);
> > > -
> > > +   /* Either drm_device.master_mutex or drm_file.master_lookup_lock
> > > +    * should be held here.
> > > +    */
> >
> > Disappointing that lockdep can't check or conditions for us, a
> > lockdep_assert_held_either would be really neat in some cases.
> >
>
> The implementation is not hard but I don't understand the usage, for
> example, if we have a global variable x, and two locks L1 and L2, and
> the function
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_either(L1, L2);
>                 x++;
>         }
>
> and two call sites:
>
>         void f(void)
>         {
>                 lock(L1);
>                 do_something_to_x();
>                 unlock(L1);
>         }
>
>         void g(void)
>         {
>                 lock(L2);
>                 do_something_to_x();
>                 unlock(L2);
>         }
>
> , wouldn't it be racy if f() and g() called by two threads at the same
> time? Usually I would expect there exists a third synchronazition
> mechanism (say M), which synchronizes the calls to f() and g(), and we
> put M in the lockdep_assert_held() check inside do_something_to_x()
> like:
>
>         void do_something_to_x(void)
>         {
>                 lockdep_assert_held_once(M);
>                 x++;
>         }
>
> But of course, M may not be a lock, so we cannot put the assert there.
>
> My cscope failed to find ->master_lookup_lock in -rc2 and seems it's not
> introduced in the patchset either, could you point me the branch this
> patchset is based on, so that I could understand this better, and maybe
> come up with a solution? Thanks ;-)

The use case is essentially 2 nesting locks, and only the innermost is
used to update a field. So when you only read this field, it's safe if
either of these two locks are held. Essentially this is a read/write lock
type of thing, except for various reasons the two locks might not be of
the same type (like here where the write lock is a mutex, but the read
lock is a spinlock).

It's a bit like the rcu_derefence macro where it's ok to either be in a
rcu_read_lock() section, or holding the relevant lock that's used to
update the value. We do _not_ have two different locks that allow writing
to the same X.

Does that make it clearer what's the use-case here?

In an example:

void * interesting_pointer.

do_update_interesting_pointer()
{
	mutex_lock(A);
	/* do more stuff to prepare things */
	spin_lock(B);
	interesting_pointer = new_value;
	spin_unlock(B);
	mutex_unlock(A);
}

read_interesting_thing_locked()
{
	lockdep_assert_held_either(A, B);

	return interesting_pointer->thing;
}

read_interesting_thing()
{
	int thing;
	spin_lock(B);
	thing = interesting_pointer->thing;
	spin_unlock(B);

	return B;
}

spinlock might also be irqsafe here if this can be called from irq
context.

Cheers, Daniel

> Regards,
> Boqun
>
> > Adding lockdep folks, maybe they have ideas.
> >
> > On the patch:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > >     return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> > >  }
> > >
> > > @@ -82,9 +83,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
> > >  {
> > >     bool ret;
> > >
> > > -   mutex_lock(&fpriv->minor->dev->master_mutex);
> > > +   spin_lock(&fpriv->master_lookup_lock);
> > >     ret = drm_is_current_master_locked(fpriv);
> > > -   mutex_unlock(&fpriv->minor->dev->master_mutex);
> > > +   spin_unlock(&fpriv->master_lookup_lock);
> > >
> > >     return ret;
> > >  }
> > > --
> > > 2.25.1
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

  reply	other threads:[~2021-07-22 19:02 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-22  9:29 [PATCH 0/3] drm, drm/vmwgfx: fixes and updates related to drm_master Desmond Cheong Zhi Xi
2021-07-22  9:29 ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22  9:29 ` Desmond Cheong Zhi Xi
2021-07-22  9:29 ` Desmond Cheong Zhi Xi
2021-07-22  9:29 ` [PATCH 1/3] drm: use the lookup lock in drm_is_current_master Desmond Cheong Zhi Xi
2021-07-22  9:29   ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22 10:38   ` Daniel Vetter
2021-07-22 10:38     ` [Intel-gfx] " Daniel Vetter
2021-07-22 10:38     ` Daniel Vetter
2021-07-22 10:38     ` Daniel Vetter
2021-07-22 15:04     ` Boqun Feng
2021-07-22 15:04       ` [Intel-gfx] " Boqun Feng
2021-07-22 15:04       ` Boqun Feng
2021-07-22 19:02       ` Daniel Vetter [this message]
2021-07-22 19:02         ` Daniel Vetter
2021-07-22 19:02         ` Daniel Vetter
2021-07-22 19:02         ` [Intel-gfx] " Daniel Vetter
2021-07-23  7:16         ` Boqun Feng
2021-07-23  7:16           ` [Intel-gfx] " Boqun Feng
2021-07-23  7:16           ` Boqun Feng
2021-07-27 14:37     ` Peter Zijlstra
2021-07-27 14:37       ` [Intel-gfx] " Peter Zijlstra
2021-07-27 14:37       ` Peter Zijlstra
2021-07-29  7:00       ` Daniel Vetter
2021-07-29  7:00         ` Daniel Vetter
2021-07-29  7:00         ` Daniel Vetter
2021-07-29  7:00         ` [Intel-gfx] " Daniel Vetter
2021-07-29 14:32         ` Desmond Cheong Zhi Xi
2021-07-29 14:32           ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-29 14:32           ` Desmond Cheong Zhi Xi
2021-07-29 14:32           ` Desmond Cheong Zhi Xi
2021-07-29 14:45           ` [Intel-gfx] " Peter Zijlstra
2021-07-29 14:45             ` Peter Zijlstra
2021-07-29 14:45             ` Peter Zijlstra
2021-07-29 14:45             ` Peter Zijlstra
2021-07-22  9:29 ` [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields Desmond Cheong Zhi Xi
2021-07-22  9:29   ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22 10:35   ` Daniel Vetter
2021-07-22 10:35     ` [Intel-gfx] " Daniel Vetter
2021-07-22 10:35     ` Daniel Vetter
2021-07-22 10:35     ` Daniel Vetter
2021-07-22 13:02     ` Desmond Cheong Zhi Xi
2021-07-22 13:02       ` Desmond Cheong Zhi Xi
2021-07-22 13:02       ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22 13:02       ` Desmond Cheong Zhi Xi
2021-07-22 14:17       ` Daniel Vetter
2021-07-22 14:17         ` Daniel Vetter
2021-07-22 14:17         ` Daniel Vetter
2021-07-22 14:17         ` [Intel-gfx] " Daniel Vetter
2021-07-22  9:29 ` [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c Desmond Cheong Zhi Xi
2021-07-22  9:29   ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22  9:29   ` Desmond Cheong Zhi Xi
2021-07-22 10:39   ` Daniel Vetter
2021-07-22 10:39     ` [Intel-gfx] " Daniel Vetter
2021-07-22 10:39     ` Daniel Vetter
2021-07-22 10:39     ` Daniel Vetter
2021-07-22 19:17   ` Zack Rusin
2021-07-22 19:17     ` Zack Rusin
2021-07-22 19:17     ` Zack Rusin
2021-07-22 19:17     ` [Intel-gfx] " Zack Rusin
2021-07-23  6:44     ` Desmond Cheong Zhi Xi
2021-07-23  6:44       ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-23  6:44       ` Desmond Cheong Zhi Xi
2021-07-23  6:44       ` Desmond Cheong Zhi Xi
2021-07-22 14:05 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm, drm/vmwgfx: fixes and updates related to drm_master Patchwork
2021-07-22 14:34 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2021-07-27 17:42 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm, drm/vmwgfx: fixes and updates related to drm_master (rev2) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKMK7uGSc_YMf2e=oA23KeAvC8i_pqJBU82v8oRGfnwsT41WLQ@mail.gmail.com' \
    --to=daniel@ffwll.ch \
    --cc=airlied@linux.ie \
    --cc=boqun.feng@gmail.com \
    --cc=desmondcheongzx@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=linux-graphics-maintainer@vmware.com \
    --cc=linux-kernel-mentees@lists.linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=peterz@infradead.org \
    --cc=skhan@linuxfoundation.org \
    --cc=tzimmermann@suse.de \
    --cc=zackr@vmware.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.