All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] drm, drm/vmwgfx: fixes and updates related to drm_master
@ 2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx, skhan,
	gregkh, linux-kernel-mentees

Hi,

This series contains some improvements that Daniel Vetter proposed following a discussion on a recent series:
https://lore.kernel.org/lkml/20210712043508.11584-1-desmondcheongzx@gmail.com/

While preparing these patches, I also noticed some unprotected uses of drm_master in the vmwgfx driver that can be addressed by new functions from the previous series.

This series is thus broken up into three patches:

1. Switch from the outer drm_device.master_mutex to the inner drm_file.master_lookup_lock in drm_is_current_master.

2. Update the kerneldoc for lease fields in drm_master to clarify lifetime/locking rules.

3. Prevent potential use-after-free bugs by replacing calls to drm_master_get with drm_file_get_master in vmwgfx_surface.c.

Best wishes,
Desmond

Desmond Cheong Zhi Xi (3):
  drm: use the lookup lock in drm_is_current_master
  drm: clarify lifetime/locking for drm_master's lease fields
  drm/vmwgfx: fix potential UAF in vmwgfx_surface.c

 drivers/gpu/drm/drm_auth.c              |  9 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |  4 +-
 include/drm/drm_auth.h                  | 62 ++++++++++++++++++++-----
 3 files changed, 58 insertions(+), 17 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 0/3] drm, drm/vmwgfx: fixes and updates related to drm_master
@ 2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, Desmond Cheong Zhi Xi,
	linux-kernel-mentees

Hi,

This series contains some improvements that Daniel Vetter proposed following a discussion on a recent series:
https://lore.kernel.org/lkml/20210712043508.11584-1-desmondcheongzx@gmail.com/

While preparing these patches, I also noticed some unprotected uses of drm_master in the vmwgfx driver that can be addressed by new functions from the previous series.

This series is thus broken up into three patches:

1. Switch from the outer drm_device.master_mutex to the inner drm_file.master_lookup_lock in drm_is_current_master.

2. Update the kerneldoc for lease fields in drm_master to clarify lifetime/locking rules.

3. Prevent potential use-after-free bugs by replacing calls to drm_master_get with drm_file_get_master in vmwgfx_surface.c.

Best wishes,
Desmond

Desmond Cheong Zhi Xi (3):
  drm: use the lookup lock in drm_is_current_master
  drm: clarify lifetime/locking for drm_master's lease fields
  drm/vmwgfx: fix potential UAF in vmwgfx_surface.c

 drivers/gpu/drm/drm_auth.c              |  9 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |  4 +-
 include/drm/drm_auth.h                  | 62 ++++++++++++++++++++-----
 3 files changed, 58 insertions(+), 17 deletions(-)

-- 
2.25.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 0/3] drm, drm/vmwgfx: fixes and updates related to drm_master
@ 2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

Hi,

This series contains some improvements that Daniel Vetter proposed following a discussion on a recent series:
https://lore.kernel.org/lkml/20210712043508.11584-1-desmondcheongzx@gmail.com/

While preparing these patches, I also noticed some unprotected uses of drm_master in the vmwgfx driver that can be addressed by new functions from the previous series.

This series is thus broken up into three patches:

1. Switch from the outer drm_device.master_mutex to the inner drm_file.master_lookup_lock in drm_is_current_master.

2. Update the kerneldoc for lease fields in drm_master to clarify lifetime/locking rules.

3. Prevent potential use-after-free bugs by replacing calls to drm_master_get with drm_file_get_master in vmwgfx_surface.c.

Best wishes,
Desmond

Desmond Cheong Zhi Xi (3):
  drm: use the lookup lock in drm_is_current_master
  drm: clarify lifetime/locking for drm_master's lease fields
  drm/vmwgfx: fix potential UAF in vmwgfx_surface.c

 drivers/gpu/drm/drm_auth.c              |  9 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |  4 +-
 include/drm/drm_auth.h                  | 62 ++++++++++++++++++++-----
 3 files changed, 58 insertions(+), 17 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [Intel-gfx] [PATCH 0/3] drm, drm/vmwgfx: fixes and updates related to drm_master
@ 2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

Hi,

This series contains some improvements that Daniel Vetter proposed following a discussion on a recent series:
https://lore.kernel.org/lkml/20210712043508.11584-1-desmondcheongzx@gmail.com/

While preparing these patches, I also noticed some unprotected uses of drm_master in the vmwgfx driver that can be addressed by new functions from the previous series.

This series is thus broken up into three patches:

1. Switch from the outer drm_device.master_mutex to the inner drm_file.master_lookup_lock in drm_is_current_master.

2. Update the kerneldoc for lease fields in drm_master to clarify lifetime/locking rules.

3. Prevent potential use-after-free bugs by replacing calls to drm_master_get with drm_file_get_master in vmwgfx_surface.c.

Best wishes,
Desmond

Desmond Cheong Zhi Xi (3):
  drm: use the lookup lock in drm_is_current_master
  drm: clarify lifetime/locking for drm_master's lease fields
  drm/vmwgfx: fix potential UAF in vmwgfx_surface.c

 drivers/gpu/drm/drm_auth.c              |  9 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |  4 +-
 include/drm/drm_auth.h                  | 62 ++++++++++++++++++++-----
 3 files changed, 58 insertions(+), 17 deletions(-)

-- 
2.25.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx, skhan,
	gregkh, linux-kernel-mentees, Daniel Vetter

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.
+	 */
 	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


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, Daniel Vetter,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

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.
+	 */
 	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

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, Daniel Vetter, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

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.
+	 */
 	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


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, Daniel Vetter, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

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.
+	 */
 	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx, skhan,
	gregkh, linux-kernel-mentees

In particular, we make it clear that &drm_device.mode_config.idr_mutex
protects the lease idr and list structures for drm_master. The lessor
field itself doesn't need to be protected as it doesn't change after
it's set in drm_lease_create.

Additionally, we add descriptions for the lifetime of lessors and
leases to make it easier to reason about them.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index f99d3417f304..c978c85464fa 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -58,12 +58,6 @@ struct drm_lock_data {
  * @refcount: Refcount for this master object.
  * @dev: Link back to the DRM device
  * @driver_priv: Pointer to driver-private information.
- * @lessor: Lease holder
- * @lessee_id: id for lessees. Owners always have id 0
- * @lessee_list: other lessees of the same master
- * @lessees: drm_masters leasing from this one
- * @leases: Objects leased to this drm_master.
- * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
  *
  * Note that master structures are only relevant for the legacy/primary device
  * nodes, hence there can only be one per device, not one per drm_minor.
@@ -88,17 +82,63 @@ struct drm_master {
 	struct idr magic_map;
 	void *driver_priv;
 
-	/* Tree of display resource leases, each of which is a drm_master struct
-	 * All of these get activated simultaneously, so drm_device master points
-	 * at the top of the tree (for which lessor is NULL). Protected by
-	 * &drm_device.mode_config.idr_mutex.
+	/**
+	 * @lessor:
+	 *
+	 * Lease holder. The lessor does not change once it's set in
+	 * drm_lease_create(). Each lessee holds a reference to its lessor that
+	 * it releases upon being destroyed in drm_lease_destroy().
+	 *
+	 * Display resource leases form a tree of &struct drm_master. All of
+	 * these get activated simultaneously, so &drm_device.master
+	 * points at the top of the tree (for which lessor is NULL).
 	 */
-
 	struct drm_master *lessor;
+
+	/**
+	 * @lessee_id:
+	 *
+	 * ID for lessees. Owners always have ID 0. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	int	lessee_id;
+
+	/**
+	 * @lessee_list:
+	 *
+	 * List of lessees of the same master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct list_head lessee_list;
+
+	/**
+	 * @lessees:
+	 *
+	 * List of drm_masters leasing from this one. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * This master cannot be destroyed unless this list is empty as lessors
+	 * are referenced by all their lessees.
+	 */
 	struct list_head lessees;
+
+	/**
+	 * @leases:
+	 *
+	 * Objects leased to this drm_master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * Objects are leased all together in drm_lease_create(), and are
+	 * removed all together when the lease is revoked.
+	 */
 	struct idr leases;
+
+	/**
+	 * @lessee_idr:
+	 *
+	 * All lessees under this owner (only used where lessor is NULL).
+	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct idr lessee_idr;
 	/* private: */
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, Desmond Cheong Zhi Xi,
	linux-kernel-mentees

In particular, we make it clear that &drm_device.mode_config.idr_mutex
protects the lease idr and list structures for drm_master. The lessor
field itself doesn't need to be protected as it doesn't change after
it's set in drm_lease_create.

Additionally, we add descriptions for the lifetime of lessors and
leases to make it easier to reason about them.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index f99d3417f304..c978c85464fa 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -58,12 +58,6 @@ struct drm_lock_data {
  * @refcount: Refcount for this master object.
  * @dev: Link back to the DRM device
  * @driver_priv: Pointer to driver-private information.
- * @lessor: Lease holder
- * @lessee_id: id for lessees. Owners always have id 0
- * @lessee_list: other lessees of the same master
- * @lessees: drm_masters leasing from this one
- * @leases: Objects leased to this drm_master.
- * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
  *
  * Note that master structures are only relevant for the legacy/primary device
  * nodes, hence there can only be one per device, not one per drm_minor.
@@ -88,17 +82,63 @@ struct drm_master {
 	struct idr magic_map;
 	void *driver_priv;
 
-	/* Tree of display resource leases, each of which is a drm_master struct
-	 * All of these get activated simultaneously, so drm_device master points
-	 * at the top of the tree (for which lessor is NULL). Protected by
-	 * &drm_device.mode_config.idr_mutex.
+	/**
+	 * @lessor:
+	 *
+	 * Lease holder. The lessor does not change once it's set in
+	 * drm_lease_create(). Each lessee holds a reference to its lessor that
+	 * it releases upon being destroyed in drm_lease_destroy().
+	 *
+	 * Display resource leases form a tree of &struct drm_master. All of
+	 * these get activated simultaneously, so &drm_device.master
+	 * points at the top of the tree (for which lessor is NULL).
 	 */
-
 	struct drm_master *lessor;
+
+	/**
+	 * @lessee_id:
+	 *
+	 * ID for lessees. Owners always have ID 0. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	int	lessee_id;
+
+	/**
+	 * @lessee_list:
+	 *
+	 * List of lessees of the same master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct list_head lessee_list;
+
+	/**
+	 * @lessees:
+	 *
+	 * List of drm_masters leasing from this one. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * This master cannot be destroyed unless this list is empty as lessors
+	 * are referenced by all their lessees.
+	 */
 	struct list_head lessees;
+
+	/**
+	 * @leases:
+	 *
+	 * Objects leased to this drm_master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * Objects are leased all together in drm_lease_create(), and are
+	 * removed all together when the lease is revoked.
+	 */
 	struct idr leases;
+
+	/**
+	 * @lessee_idr:
+	 *
+	 * All lessees under this owner (only used where lessor is NULL).
+	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct idr lessee_idr;
 	/* private: */
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
-- 
2.25.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

In particular, we make it clear that &drm_device.mode_config.idr_mutex
protects the lease idr and list structures for drm_master. The lessor
field itself doesn't need to be protected as it doesn't change after
it's set in drm_lease_create.

Additionally, we add descriptions for the lifetime of lessors and
leases to make it easier to reason about them.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index f99d3417f304..c978c85464fa 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -58,12 +58,6 @@ struct drm_lock_data {
  * @refcount: Refcount for this master object.
  * @dev: Link back to the DRM device
  * @driver_priv: Pointer to driver-private information.
- * @lessor: Lease holder
- * @lessee_id: id for lessees. Owners always have id 0
- * @lessee_list: other lessees of the same master
- * @lessees: drm_masters leasing from this one
- * @leases: Objects leased to this drm_master.
- * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
  *
  * Note that master structures are only relevant for the legacy/primary device
  * nodes, hence there can only be one per device, not one per drm_minor.
@@ -88,17 +82,63 @@ struct drm_master {
 	struct idr magic_map;
 	void *driver_priv;
 
-	/* Tree of display resource leases, each of which is a drm_master struct
-	 * All of these get activated simultaneously, so drm_device master points
-	 * at the top of the tree (for which lessor is NULL). Protected by
-	 * &drm_device.mode_config.idr_mutex.
+	/**
+	 * @lessor:
+	 *
+	 * Lease holder. The lessor does not change once it's set in
+	 * drm_lease_create(). Each lessee holds a reference to its lessor that
+	 * it releases upon being destroyed in drm_lease_destroy().
+	 *
+	 * Display resource leases form a tree of &struct drm_master. All of
+	 * these get activated simultaneously, so &drm_device.master
+	 * points at the top of the tree (for which lessor is NULL).
 	 */
-
 	struct drm_master *lessor;
+
+	/**
+	 * @lessee_id:
+	 *
+	 * ID for lessees. Owners always have ID 0. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	int	lessee_id;
+
+	/**
+	 * @lessee_list:
+	 *
+	 * List of lessees of the same master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct list_head lessee_list;
+
+	/**
+	 * @lessees:
+	 *
+	 * List of drm_masters leasing from this one. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * This master cannot be destroyed unless this list is empty as lessors
+	 * are referenced by all their lessees.
+	 */
 	struct list_head lessees;
+
+	/**
+	 * @leases:
+	 *
+	 * Objects leased to this drm_master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * Objects are leased all together in drm_lease_create(), and are
+	 * removed all together when the lease is revoked.
+	 */
 	struct idr leases;
+
+	/**
+	 * @lessee_idr:
+	 *
+	 * All lessees under this owner (only used where lessor is NULL).
+	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct idr lessee_idr;
 	/* private: */
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [Intel-gfx] [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

In particular, we make it clear that &drm_device.mode_config.idr_mutex
protects the lease idr and list structures for drm_master. The lessor
field itself doesn't need to be protected as it doesn't change after
it's set in drm_lease_create.

Additionally, we add descriptions for the lifetime of lessors and
leases to make it easier to reason about them.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index f99d3417f304..c978c85464fa 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -58,12 +58,6 @@ struct drm_lock_data {
  * @refcount: Refcount for this master object.
  * @dev: Link back to the DRM device
  * @driver_priv: Pointer to driver-private information.
- * @lessor: Lease holder
- * @lessee_id: id for lessees. Owners always have id 0
- * @lessee_list: other lessees of the same master
- * @lessees: drm_masters leasing from this one
- * @leases: Objects leased to this drm_master.
- * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
  *
  * Note that master structures are only relevant for the legacy/primary device
  * nodes, hence there can only be one per device, not one per drm_minor.
@@ -88,17 +82,63 @@ struct drm_master {
 	struct idr magic_map;
 	void *driver_priv;
 
-	/* Tree of display resource leases, each of which is a drm_master struct
-	 * All of these get activated simultaneously, so drm_device master points
-	 * at the top of the tree (for which lessor is NULL). Protected by
-	 * &drm_device.mode_config.idr_mutex.
+	/**
+	 * @lessor:
+	 *
+	 * Lease holder. The lessor does not change once it's set in
+	 * drm_lease_create(). Each lessee holds a reference to its lessor that
+	 * it releases upon being destroyed in drm_lease_destroy().
+	 *
+	 * Display resource leases form a tree of &struct drm_master. All of
+	 * these get activated simultaneously, so &drm_device.master
+	 * points at the top of the tree (for which lessor is NULL).
 	 */
-
 	struct drm_master *lessor;
+
+	/**
+	 * @lessee_id:
+	 *
+	 * ID for lessees. Owners always have ID 0. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	int	lessee_id;
+
+	/**
+	 * @lessee_list:
+	 *
+	 * List of lessees of the same master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct list_head lessee_list;
+
+	/**
+	 * @lessees:
+	 *
+	 * List of drm_masters leasing from this one. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * This master cannot be destroyed unless this list is empty as lessors
+	 * are referenced by all their lessees.
+	 */
 	struct list_head lessees;
+
+	/**
+	 * @leases:
+	 *
+	 * Objects leased to this drm_master. Protected by
+	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 *
+	 * Objects are leased all together in drm_lease_create(), and are
+	 * removed all together when the lease is revoked.
+	 */
 	struct idr leases;
+
+	/**
+	 * @lessee_idr:
+	 *
+	 * All lessees under this owner (only used where lessor is NULL).
+	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
+	 */
 	struct idr lessee_idr;
 	/* private: */
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
-- 
2.25.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx, skhan,
	gregkh, linux-kernel-mentees

drm_file.master should be protected by either drm_device.master_mutex
or drm_file.master_lookup_lock when being dereferenced. However,
drm_master_get is called on unprotected file_priv->master pointers in
vmw_surface_define_ioctl and vmw_gb_surface_define_internal.

This is fixed by replacing drm_master_get with drm_file_get_master.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 0eba47762bed..5d53a5f9d123 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	user_srf->prime.base.shareable = false;
 	user_srf->prime.base.tfile = NULL;
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	/**
 	 * From this point, the generic resource management functions
@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
 
 	user_srf = container_of(srf, struct vmw_user_surface, srf);
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	res = &user_srf->srf.res;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, Desmond Cheong Zhi Xi,
	linux-kernel-mentees

drm_file.master should be protected by either drm_device.master_mutex
or drm_file.master_lookup_lock when being dereferenced. However,
drm_master_get is called on unprotected file_priv->master pointers in
vmw_surface_define_ioctl and vmw_gb_surface_define_internal.

This is fixed by replacing drm_master_get with drm_file_get_master.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 0eba47762bed..5d53a5f9d123 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	user_srf->prime.base.shareable = false;
 	user_srf->prime.base.tfile = NULL;
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	/**
 	 * From this point, the generic resource management functions
@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
 
 	user_srf = container_of(srf, struct vmw_user_surface, srf);
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	res = &user_srf->srf.res;
 
-- 
2.25.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

drm_file.master should be protected by either drm_device.master_mutex
or drm_file.master_lookup_lock when being dereferenced. However,
drm_master_get is called on unprotected file_priv->master pointers in
vmw_surface_define_ioctl and vmw_gb_surface_define_internal.

This is fixed by replacing drm_master_get with drm_file_get_master.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 0eba47762bed..5d53a5f9d123 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	user_srf->prime.base.shareable = false;
 	user_srf->prime.base.tfile = NULL;
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	/**
 	 * From this point, the generic resource management functions
@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
 
 	user_srf = container_of(srf, struct vmw_user_surface, srf);
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	res = &user_srf->srf.res;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [Intel-gfx] [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22  9:29 UTC (permalink / raw)
  To: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

drm_file.master should be protected by either drm_device.master_mutex
or drm_file.master_lookup_lock when being dereferenced. However,
drm_master_get is called on unprotected file_priv->master pointers in
vmw_surface_define_ioctl and vmw_gb_surface_define_internal.

This is fixed by replacing drm_master_get with drm_file_get_master.

Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 0eba47762bed..5d53a5f9d123 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	user_srf->prime.base.shareable = false;
 	user_srf->prime.base.tfile = NULL;
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	/**
 	 * From this point, the generic resource management functions
@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
 
 	user_srf = container_of(srf, struct vmw_user_surface, srf);
 	if (drm_is_primary_client(file_priv))
-		user_srf->master = drm_master_get(file_priv->master);
+		user_srf->master = drm_file_get_master(file_priv);
 
 	res = &user_srf->srf.res;
 
-- 
2.25.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
  2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22 10:35     ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:35 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann, dri-devel, linux-kernel,
	intel-gfx, skhan, gregkh, linux-kernel-mentees

On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> protects the lease idr and list structures for drm_master. The lessor
> field itself doesn't need to be protected as it doesn't change after
> it's set in drm_lease_create.
> 
> Additionally, we add descriptions for the lifetime of lessors and
> leases to make it easier to reason about them.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> ---
>  include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 51 insertions(+), 11 deletions(-)
> 
> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> index f99d3417f304..c978c85464fa 100644
> --- a/include/drm/drm_auth.h
> +++ b/include/drm/drm_auth.h
> @@ -58,12 +58,6 @@ struct drm_lock_data {
>   * @refcount: Refcount for this master object.
>   * @dev: Link back to the DRM device
>   * @driver_priv: Pointer to driver-private information.
> - * @lessor: Lease holder
> - * @lessee_id: id for lessees. Owners always have id 0
> - * @lessee_list: other lessees of the same master
> - * @lessees: drm_masters leasing from this one
> - * @leases: Objects leased to this drm_master.
> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>   *
>   * Note that master structures are only relevant for the legacy/primary device
>   * nodes, hence there can only be one per device, not one per drm_minor.
> @@ -88,17 +82,63 @@ struct drm_master {
>  	struct idr magic_map;
>  	void *driver_priv;
>  
> -	/* Tree of display resource leases, each of which is a drm_master struct
> -	 * All of these get activated simultaneously, so drm_device master points
> -	 * at the top of the tree (for which lessor is NULL). Protected by
> -	 * &drm_device.mode_config.idr_mutex.
> +	/**
> +	 * @lessor:
> +	 *
> +	 * Lease holder. The lessor does not change once it's set in

Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
clarify this with

"Lease grantor, only set if this struct drm_master represents a lessee
holding a lease of objects from @lessor. Full owners of the device have
this set to NULL."

> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that

I also figured it'd be a good idea to link to the drm_lease docs here to
explain the concepts, but alas we don't have those :-( Hence at least
define what we mean with lessor, lessee, lease and owner.

> +	 * it releases upon being destroyed in drm_lease_destroy().
> +	 *
> +	 * Display resource leases form a tree of &struct drm_master. All of

For now we've limited the tree to a depth of 1, you can't create another
lease if yourself are a lease. I guess another reason to update the
drm_lease.c docs.

So maybe add "Currently the lease tree depth is limited to 1."

> +	 * these get activated simultaneously, so &drm_device.master
> +	 * points at the top of the tree (for which lessor is NULL).
>  	 */
> -
>  	struct drm_master *lessor;
> +
> +	/**
> +	 * @lessee_id:
> +	 *
> +	 * ID for lessees. Owners always have ID 0. Protected by

Maybe clarify to "Owners (i.e. @lessor is NULL) ..."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	int	lessee_id;
> +
> +	/**
> +	 * @lessee_list:
> +	 *
> +	 * List of lessees of the same master. Protected by

We try to distinguis between list entries and the list, even though it's
the same struct. So maybe

"List entry of lessees of @lessor, where they are linked to @lessee. Not
use for owners."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.

> +	 */
>  	struct list_head lessee_list;
> +
> +	/**
> +	 * @lessees:
> +	 *
> +	 * List of drm_masters leasing from this one. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * This master cannot be destroyed unless this list is empty as lessors
> +	 * are referenced by all their lessees.

Maybe add "this list is empty of no leases have been granted."

> +	 */
>  	struct list_head lessees;
> +
> +	/**
> +	 * @leases:
> +	 *
> +	 * Objects leased to this drm_master. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * Objects are leased all together in drm_lease_create(), and are
> +	 * removed all together when the lease is revoked.
> +	 */
>  	struct idr leases;
> +
> +	/**
> +	 * @lessee_idr:
> +	 *
> +	 * All lessees under this owner (only used where lessor is NULL).

@lessor so it's highlighted correctly

> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	struct idr lessee_idr;
>  	/* private: */

With the nits addressed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Thanks for updating the docs!
-Daniel

>  #if IS_ENABLED(CONFIG_DRM_LEGACY)
> -- 
> 2.25.1
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 10:35     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:35 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, intel-gfx, maarten.lankhorst, linux-kernel,
	mripard, linux-graphics-maintainer, dri-devel, daniel,
	linux-kernel-mentees, zackr

On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> protects the lease idr and list structures for drm_master. The lessor
> field itself doesn't need to be protected as it doesn't change after
> it's set in drm_lease_create.
> 
> Additionally, we add descriptions for the lifetime of lessors and
> leases to make it easier to reason about them.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> ---
>  include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 51 insertions(+), 11 deletions(-)
> 
> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> index f99d3417f304..c978c85464fa 100644
> --- a/include/drm/drm_auth.h
> +++ b/include/drm/drm_auth.h
> @@ -58,12 +58,6 @@ struct drm_lock_data {
>   * @refcount: Refcount for this master object.
>   * @dev: Link back to the DRM device
>   * @driver_priv: Pointer to driver-private information.
> - * @lessor: Lease holder
> - * @lessee_id: id for lessees. Owners always have id 0
> - * @lessee_list: other lessees of the same master
> - * @lessees: drm_masters leasing from this one
> - * @leases: Objects leased to this drm_master.
> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>   *
>   * Note that master structures are only relevant for the legacy/primary device
>   * nodes, hence there can only be one per device, not one per drm_minor.
> @@ -88,17 +82,63 @@ struct drm_master {
>  	struct idr magic_map;
>  	void *driver_priv;
>  
> -	/* Tree of display resource leases, each of which is a drm_master struct
> -	 * All of these get activated simultaneously, so drm_device master points
> -	 * at the top of the tree (for which lessor is NULL). Protected by
> -	 * &drm_device.mode_config.idr_mutex.
> +	/**
> +	 * @lessor:
> +	 *
> +	 * Lease holder. The lessor does not change once it's set in

Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
clarify this with

"Lease grantor, only set if this struct drm_master represents a lessee
holding a lease of objects from @lessor. Full owners of the device have
this set to NULL."

> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that

I also figured it'd be a good idea to link to the drm_lease docs here to
explain the concepts, but alas we don't have those :-( Hence at least
define what we mean with lessor, lessee, lease and owner.

> +	 * it releases upon being destroyed in drm_lease_destroy().
> +	 *
> +	 * Display resource leases form a tree of &struct drm_master. All of

For now we've limited the tree to a depth of 1, you can't create another
lease if yourself are a lease. I guess another reason to update the
drm_lease.c docs.

So maybe add "Currently the lease tree depth is limited to 1."

> +	 * these get activated simultaneously, so &drm_device.master
> +	 * points at the top of the tree (for which lessor is NULL).
>  	 */
> -
>  	struct drm_master *lessor;
> +
> +	/**
> +	 * @lessee_id:
> +	 *
> +	 * ID for lessees. Owners always have ID 0. Protected by

Maybe clarify to "Owners (i.e. @lessor is NULL) ..."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	int	lessee_id;
> +
> +	/**
> +	 * @lessee_list:
> +	 *
> +	 * List of lessees of the same master. Protected by

We try to distinguis between list entries and the list, even though it's
the same struct. So maybe

"List entry of lessees of @lessor, where they are linked to @lessee. Not
use for owners."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.

> +	 */
>  	struct list_head lessee_list;
> +
> +	/**
> +	 * @lessees:
> +	 *
> +	 * List of drm_masters leasing from this one. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * This master cannot be destroyed unless this list is empty as lessors
> +	 * are referenced by all their lessees.

Maybe add "this list is empty of no leases have been granted."

> +	 */
>  	struct list_head lessees;
> +
> +	/**
> +	 * @leases:
> +	 *
> +	 * Objects leased to this drm_master. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * Objects are leased all together in drm_lease_create(), and are
> +	 * removed all together when the lease is revoked.
> +	 */
>  	struct idr leases;
> +
> +	/**
> +	 * @lessee_idr:
> +	 *
> +	 * All lessees under this owner (only used where lessor is NULL).

@lessor so it's highlighted correctly

> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	struct idr lessee_idr;
>  	/* private: */

With the nits addressed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Thanks for updating the docs!
-Daniel

>  #if IS_ENABLED(CONFIG_DRM_LEGACY)
> -- 
> 2.25.1
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 10:35     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:35 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> protects the lease idr and list structures for drm_master. The lessor
> field itself doesn't need to be protected as it doesn't change after
> it's set in drm_lease_create.
> 
> Additionally, we add descriptions for the lifetime of lessors and
> leases to make it easier to reason about them.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> ---
>  include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 51 insertions(+), 11 deletions(-)
> 
> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> index f99d3417f304..c978c85464fa 100644
> --- a/include/drm/drm_auth.h
> +++ b/include/drm/drm_auth.h
> @@ -58,12 +58,6 @@ struct drm_lock_data {
>   * @refcount: Refcount for this master object.
>   * @dev: Link back to the DRM device
>   * @driver_priv: Pointer to driver-private information.
> - * @lessor: Lease holder
> - * @lessee_id: id for lessees. Owners always have id 0
> - * @lessee_list: other lessees of the same master
> - * @lessees: drm_masters leasing from this one
> - * @leases: Objects leased to this drm_master.
> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>   *
>   * Note that master structures are only relevant for the legacy/primary device
>   * nodes, hence there can only be one per device, not one per drm_minor.
> @@ -88,17 +82,63 @@ struct drm_master {
>  	struct idr magic_map;
>  	void *driver_priv;
>  
> -	/* Tree of display resource leases, each of which is a drm_master struct
> -	 * All of these get activated simultaneously, so drm_device master points
> -	 * at the top of the tree (for which lessor is NULL). Protected by
> -	 * &drm_device.mode_config.idr_mutex.
> +	/**
> +	 * @lessor:
> +	 *
> +	 * Lease holder. The lessor does not change once it's set in

Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
clarify this with

"Lease grantor, only set if this struct drm_master represents a lessee
holding a lease of objects from @lessor. Full owners of the device have
this set to NULL."

> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that

I also figured it'd be a good idea to link to the drm_lease docs here to
explain the concepts, but alas we don't have those :-( Hence at least
define what we mean with lessor, lessee, lease and owner.

> +	 * it releases upon being destroyed in drm_lease_destroy().
> +	 *
> +	 * Display resource leases form a tree of &struct drm_master. All of

For now we've limited the tree to a depth of 1, you can't create another
lease if yourself are a lease. I guess another reason to update the
drm_lease.c docs.

So maybe add "Currently the lease tree depth is limited to 1."

> +	 * these get activated simultaneously, so &drm_device.master
> +	 * points at the top of the tree (for which lessor is NULL).
>  	 */
> -
>  	struct drm_master *lessor;
> +
> +	/**
> +	 * @lessee_id:
> +	 *
> +	 * ID for lessees. Owners always have ID 0. Protected by

Maybe clarify to "Owners (i.e. @lessor is NULL) ..."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	int	lessee_id;
> +
> +	/**
> +	 * @lessee_list:
> +	 *
> +	 * List of lessees of the same master. Protected by

We try to distinguis between list entries and the list, even though it's
the same struct. So maybe

"List entry of lessees of @lessor, where they are linked to @lessee. Not
use for owners."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.

> +	 */
>  	struct list_head lessee_list;
> +
> +	/**
> +	 * @lessees:
> +	 *
> +	 * List of drm_masters leasing from this one. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * This master cannot be destroyed unless this list is empty as lessors
> +	 * are referenced by all their lessees.

Maybe add "this list is empty of no leases have been granted."

> +	 */
>  	struct list_head lessees;
> +
> +	/**
> +	 * @leases:
> +	 *
> +	 * Objects leased to this drm_master. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * Objects are leased all together in drm_lease_create(), and are
> +	 * removed all together when the lease is revoked.
> +	 */
>  	struct idr leases;
> +
> +	/**
> +	 * @lessee_idr:
> +	 *
> +	 * All lessees under this owner (only used where lessor is NULL).

@lessor so it's highlighted correctly

> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	struct idr lessee_idr;
>  	/* private: */

With the nits addressed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Thanks for updating the docs!
-Daniel

>  #if IS_ENABLED(CONFIG_DRM_LEGACY)
> -- 
> 2.25.1
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 10:35     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:35 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel, mripard,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees, zackr

On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> protects the lease idr and list structures for drm_master. The lessor
> field itself doesn't need to be protected as it doesn't change after
> it's set in drm_lease_create.
> 
> Additionally, we add descriptions for the lifetime of lessors and
> leases to make it easier to reason about them.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> ---
>  include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 51 insertions(+), 11 deletions(-)
> 
> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> index f99d3417f304..c978c85464fa 100644
> --- a/include/drm/drm_auth.h
> +++ b/include/drm/drm_auth.h
> @@ -58,12 +58,6 @@ struct drm_lock_data {
>   * @refcount: Refcount for this master object.
>   * @dev: Link back to the DRM device
>   * @driver_priv: Pointer to driver-private information.
> - * @lessor: Lease holder
> - * @lessee_id: id for lessees. Owners always have id 0
> - * @lessee_list: other lessees of the same master
> - * @lessees: drm_masters leasing from this one
> - * @leases: Objects leased to this drm_master.
> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>   *
>   * Note that master structures are only relevant for the legacy/primary device
>   * nodes, hence there can only be one per device, not one per drm_minor.
> @@ -88,17 +82,63 @@ struct drm_master {
>  	struct idr magic_map;
>  	void *driver_priv;
>  
> -	/* Tree of display resource leases, each of which is a drm_master struct
> -	 * All of these get activated simultaneously, so drm_device master points
> -	 * at the top of the tree (for which lessor is NULL). Protected by
> -	 * &drm_device.mode_config.idr_mutex.
> +	/**
> +	 * @lessor:
> +	 *
> +	 * Lease holder. The lessor does not change once it's set in

Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
clarify this with

"Lease grantor, only set if this struct drm_master represents a lessee
holding a lease of objects from @lessor. Full owners of the device have
this set to NULL."

> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that

I also figured it'd be a good idea to link to the drm_lease docs here to
explain the concepts, but alas we don't have those :-( Hence at least
define what we mean with lessor, lessee, lease and owner.

> +	 * it releases upon being destroyed in drm_lease_destroy().
> +	 *
> +	 * Display resource leases form a tree of &struct drm_master. All of

For now we've limited the tree to a depth of 1, you can't create another
lease if yourself are a lease. I guess another reason to update the
drm_lease.c docs.

So maybe add "Currently the lease tree depth is limited to 1."

> +	 * these get activated simultaneously, so &drm_device.master
> +	 * points at the top of the tree (for which lessor is NULL).
>  	 */
> -
>  	struct drm_master *lessor;
> +
> +	/**
> +	 * @lessee_id:
> +	 *
> +	 * ID for lessees. Owners always have ID 0. Protected by

Maybe clarify to "Owners (i.e. @lessor is NULL) ..."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	int	lessee_id;
> +
> +	/**
> +	 * @lessee_list:
> +	 *
> +	 * List of lessees of the same master. Protected by

We try to distinguis between list entries and the list, even though it's
the same struct. So maybe

"List entry of lessees of @lessor, where they are linked to @lessee. Not
use for owners."

> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.

> +	 */
>  	struct list_head lessee_list;
> +
> +	/**
> +	 * @lessees:
> +	 *
> +	 * List of drm_masters leasing from this one. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * This master cannot be destroyed unless this list is empty as lessors
> +	 * are referenced by all their lessees.

Maybe add "this list is empty of no leases have been granted."

> +	 */
>  	struct list_head lessees;
> +
> +	/**
> +	 * @leases:
> +	 *
> +	 * Objects leased to this drm_master. Protected by
> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 *
> +	 * Objects are leased all together in drm_lease_create(), and are
> +	 * removed all together when the lease is revoked.
> +	 */
>  	struct idr leases;
> +
> +	/**
> +	 * @lessee_idr:
> +	 *
> +	 * All lessees under this owner (only used where lessor is NULL).

@lessor so it's highlighted correctly

> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> +	 */
>  	struct idr lessee_idr;
>  	/* private: */

With the nits addressed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Thanks for updating the docs!
-Daniel

>  #if IS_ENABLED(CONFIG_DRM_LEGACY)
> -- 
> 2.25.1
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22 10:38     ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:38 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML, Peter Zijlstra
  Cc: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann, dri-devel, linux-kernel,
	intel-gfx, skhan, gregkh, linux-kernel-mentees, Daniel Vetter

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.

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 10:38     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:38 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML, Peter Zijlstra
  Cc: tzimmermann, airlied, intel-gfx, maarten.lankhorst, linux-kernel,
	mripard, Daniel Vetter, linux-graphics-maintainer, dri-devel,
	daniel, linux-kernel-mentees, zackr

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.

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
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 10:38     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:38 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML, Peter Zijlstra
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel,
	Daniel Vetter, linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees

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.

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 10:38     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:38 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML, Peter Zijlstra
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel, mripard,
	Daniel Vetter, linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees, zackr

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.

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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
  2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22 10:39     ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:39 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: linux-graphics-maintainer, zackr, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann, dri-devel, linux-kernel,
	intel-gfx, skhan, gregkh, linux-kernel-mentees

On Thu, Jul 22, 2021 at 05:29:29PM +0800, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I'll let Zack take a look at this and expect him to push this patch to
drm-misc.git.
-Daniel

> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> index 0eba47762bed..5d53a5f9d123 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> @@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
>  	user_srf->prime.base.shareable = false;
>  	user_srf->prime.base.tfile = NULL;
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	/**
>  	 * From this point, the generic resource management functions
> @@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
>  
>  	user_srf = container_of(srf, struct vmw_user_surface, srf);
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	res = &user_srf->srf.res;
>  
> -- 
> 2.25.1
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 10:39     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:39 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, intel-gfx, maarten.lankhorst, linux-kernel,
	mripard, linux-graphics-maintainer, dri-devel, daniel,
	linux-kernel-mentees, zackr

On Thu, Jul 22, 2021 at 05:29:29PM +0800, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I'll let Zack take a look at this and expect him to push this patch to
drm-misc.git.
-Daniel

> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> index 0eba47762bed..5d53a5f9d123 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> @@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
>  	user_srf->prime.base.shareable = false;
>  	user_srf->prime.base.tfile = NULL;
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	/**
>  	 * From this point, the generic resource management functions
> @@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
>  
>  	user_srf = container_of(srf, struct vmw_user_surface, srf);
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	res = &user_srf->srf.res;
>  
> -- 
> 2.25.1
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 10:39     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:39 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 05:29:29PM +0800, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I'll let Zack take a look at this and expect him to push this patch to
drm-misc.git.
-Daniel

> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> index 0eba47762bed..5d53a5f9d123 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> @@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
>  	user_srf->prime.base.shareable = false;
>  	user_srf->prime.base.tfile = NULL;
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	/**
>  	 * From this point, the generic resource management functions
> @@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
>  
>  	user_srf = container_of(srf, struct vmw_user_surface, srf);
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	res = &user_srf->srf.res;
>  
> -- 
> 2.25.1
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 10:39     ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 10:39 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, intel-gfx, linux-kernel, mripard,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees, zackr

On Thu, Jul 22, 2021 at 05:29:29PM +0800, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I'll let Zack take a look at this and expect him to push this patch to
drm-misc.git.
-Daniel

> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> index 0eba47762bed..5d53a5f9d123 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
> @@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
>  	user_srf->prime.base.shareable = false;
>  	user_srf->prime.base.tfile = NULL;
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	/**
>  	 * From this point, the generic resource management functions
> @@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
>  
>  	user_srf = container_of(srf, struct vmw_user_surface, srf);
>  	if (drm_is_primary_client(file_priv))
> -		user_srf->master = drm_master_get(file_priv->master);
> +		user_srf->master = drm_file_get_master(file_priv);
>  
>  	res = &user_srf->srf.res;
>  
> -- 
> 2.25.1
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
  2021-07-22 10:35     ` Daniel Vetter
  (?)
  (?)
@ 2021-07-22 13:02       ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22 13:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, linux-kernel, intel-gfx, skhan,
	gregkh, linux-kernel-mentees

On 22/7/21 6:35 pm, Daniel Vetter wrote:
> On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
>> In particular, we make it clear that &drm_device.mode_config.idr_mutex
>> protects the lease idr and list structures for drm_master. The lessor
>> field itself doesn't need to be protected as it doesn't change after
>> it's set in drm_lease_create.
>>
>> Additionally, we add descriptions for the lifetime of lessors and
>> leases to make it easier to reason about them.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
>> ---
>>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 51 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
>> index f99d3417f304..c978c85464fa 100644
>> --- a/include/drm/drm_auth.h
>> +++ b/include/drm/drm_auth.h
>> @@ -58,12 +58,6 @@ struct drm_lock_data {
>>    * @refcount: Refcount for this master object.
>>    * @dev: Link back to the DRM device
>>    * @driver_priv: Pointer to driver-private information.
>> - * @lessor: Lease holder
>> - * @lessee_id: id for lessees. Owners always have id 0
>> - * @lessee_list: other lessees of the same master
>> - * @lessees: drm_masters leasing from this one
>> - * @leases: Objects leased to this drm_master.
>> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>>    *
>>    * Note that master structures are only relevant for the legacy/primary device
>>    * nodes, hence there can only be one per device, not one per drm_minor.
>> @@ -88,17 +82,63 @@ struct drm_master {
>>   	struct idr magic_map;
>>   	void *driver_priv;
>>   
>> -	/* Tree of display resource leases, each of which is a drm_master struct
>> -	 * All of these get activated simultaneously, so drm_device master points
>> -	 * at the top of the tree (for which lessor is NULL). Protected by
>> -	 * &drm_device.mode_config.idr_mutex.
>> +	/**
>> +	 * @lessor:
>> +	 *
>> +	 * Lease holder. The lessor does not change once it's set in
> 
> Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> clarify this with
> 
> "Lease grantor, only set if this struct drm_master represents a lessee
> holding a lease of objects from @lessor. Full owners of the device have
> this set to NULL."
> 
>> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that
> 
> I also figured it'd be a good idea to link to the drm_lease docs here to
> explain the concepts, but alas we don't have those :-( Hence at least
> define what we mean with lessor, lessee, lease and owner.
> 

Thanks for the suggestions, Daniel. I'll incorporate them in a v2.

Regarding the missing drm_lease docs... any reason we can't just add it 
in? Seems like most of the comments in drm_lease.c are almost correctly 
formatted too. I could clean them up, define the terms in a preamble, 
then add it to the v2 patch.

>> +	 * it releases upon being destroyed in drm_lease_destroy().
>> +	 *
>> +	 * Display resource leases form a tree of &struct drm_master. All of
> 
> For now we've limited the tree to a depth of 1, you can't create another
> lease if yourself are a lease. I guess another reason to update the
> drm_lease.c docs.
> 
> So maybe add "Currently the lease tree depth is limited to 1."
> 
>> +	 * these get activated simultaneously, so &drm_device.master
>> +	 * points at the top of the tree (for which lessor is NULL).
>>   	 */
>> -
>>   	struct drm_master *lessor;
>> +
>> +	/**
>> +	 * @lessee_id:
>> +	 *
>> +	 * ID for lessees. Owners always have ID 0. Protected by
> 
> Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	int	lessee_id;
>> +
>> +	/**
>> +	 * @lessee_list:
>> +	 *
>> +	 * List of lessees of the same master. Protected by
> 
> We try to distinguis between list entries and the list, even though it's
> the same struct. So maybe
> 
> "List entry of lessees of @lessor, where they are linked to @lessee. Not
> use for owners."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> 
>> +	 */
>>   	struct list_head lessee_list;
>> +
>> +	/**
>> +	 * @lessees:
>> +	 *
>> +	 * List of drm_masters leasing from this one. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * This master cannot be destroyed unless this list is empty as lessors
>> +	 * are referenced by all their lessees.
> 
> Maybe add "this list is empty of no leases have been granted."
> 
>> +	 */
>>   	struct list_head lessees;
>> +
>> +	/**
>> +	 * @leases:
>> +	 *
>> +	 * Objects leased to this drm_master. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * Objects are leased all together in drm_lease_create(), and are
>> +	 * removed all together when the lease is revoked.
>> +	 */
>>   	struct idr leases;
>> +
>> +	/**
>> +	 * @lessee_idr:
>> +	 *
>> +	 * All lessees under this owner (only used where lessor is NULL).
> 
> @lessor so it's highlighted correctly
> 
>> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	struct idr lessee_idr;
>>   	/* private: */
> 
> With the nits addressed:
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Thanks for updating the docs!
> -Daniel
> 
>>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
>> -- 
>> 2.25.1
>>
> 


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 13:02       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22 13:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: airlied, intel-gfx, maarten.lankhorst, linux-kernel, mripard,
	linux-graphics-maintainer, dri-devel, tzimmermann,
	linux-kernel-mentees, zackr

On 22/7/21 6:35 pm, Daniel Vetter wrote:
> On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
>> In particular, we make it clear that &drm_device.mode_config.idr_mutex
>> protects the lease idr and list structures for drm_master. The lessor
>> field itself doesn't need to be protected as it doesn't change after
>> it's set in drm_lease_create.
>>
>> Additionally, we add descriptions for the lifetime of lessors and
>> leases to make it easier to reason about them.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
>> ---
>>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 51 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
>> index f99d3417f304..c978c85464fa 100644
>> --- a/include/drm/drm_auth.h
>> +++ b/include/drm/drm_auth.h
>> @@ -58,12 +58,6 @@ struct drm_lock_data {
>>    * @refcount: Refcount for this master object.
>>    * @dev: Link back to the DRM device
>>    * @driver_priv: Pointer to driver-private information.
>> - * @lessor: Lease holder
>> - * @lessee_id: id for lessees. Owners always have id 0
>> - * @lessee_list: other lessees of the same master
>> - * @lessees: drm_masters leasing from this one
>> - * @leases: Objects leased to this drm_master.
>> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>>    *
>>    * Note that master structures are only relevant for the legacy/primary device
>>    * nodes, hence there can only be one per device, not one per drm_minor.
>> @@ -88,17 +82,63 @@ struct drm_master {
>>   	struct idr magic_map;
>>   	void *driver_priv;
>>   
>> -	/* Tree of display resource leases, each of which is a drm_master struct
>> -	 * All of these get activated simultaneously, so drm_device master points
>> -	 * at the top of the tree (for which lessor is NULL). Protected by
>> -	 * &drm_device.mode_config.idr_mutex.
>> +	/**
>> +	 * @lessor:
>> +	 *
>> +	 * Lease holder. The lessor does not change once it's set in
> 
> Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> clarify this with
> 
> "Lease grantor, only set if this struct drm_master represents a lessee
> holding a lease of objects from @lessor. Full owners of the device have
> this set to NULL."
> 
>> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that
> 
> I also figured it'd be a good idea to link to the drm_lease docs here to
> explain the concepts, but alas we don't have those :-( Hence at least
> define what we mean with lessor, lessee, lease and owner.
> 

Thanks for the suggestions, Daniel. I'll incorporate them in a v2.

Regarding the missing drm_lease docs... any reason we can't just add it 
in? Seems like most of the comments in drm_lease.c are almost correctly 
formatted too. I could clean them up, define the terms in a preamble, 
then add it to the v2 patch.

>> +	 * it releases upon being destroyed in drm_lease_destroy().
>> +	 *
>> +	 * Display resource leases form a tree of &struct drm_master. All of
> 
> For now we've limited the tree to a depth of 1, you can't create another
> lease if yourself are a lease. I guess another reason to update the
> drm_lease.c docs.
> 
> So maybe add "Currently the lease tree depth is limited to 1."
> 
>> +	 * these get activated simultaneously, so &drm_device.master
>> +	 * points at the top of the tree (for which lessor is NULL).
>>   	 */
>> -
>>   	struct drm_master *lessor;
>> +
>> +	/**
>> +	 * @lessee_id:
>> +	 *
>> +	 * ID for lessees. Owners always have ID 0. Protected by
> 
> Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	int	lessee_id;
>> +
>> +	/**
>> +	 * @lessee_list:
>> +	 *
>> +	 * List of lessees of the same master. Protected by
> 
> We try to distinguis between list entries and the list, even though it's
> the same struct. So maybe
> 
> "List entry of lessees of @lessor, where they are linked to @lessee. Not
> use for owners."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> 
>> +	 */
>>   	struct list_head lessee_list;
>> +
>> +	/**
>> +	 * @lessees:
>> +	 *
>> +	 * List of drm_masters leasing from this one. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * This master cannot be destroyed unless this list is empty as lessors
>> +	 * are referenced by all their lessees.
> 
> Maybe add "this list is empty of no leases have been granted."
> 
>> +	 */
>>   	struct list_head lessees;
>> +
>> +	/**
>> +	 * @leases:
>> +	 *
>> +	 * Objects leased to this drm_master. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * Objects are leased all together in drm_lease_create(), and are
>> +	 * removed all together when the lease is revoked.
>> +	 */
>>   	struct idr leases;
>> +
>> +	/**
>> +	 * @lessee_idr:
>> +	 *
>> +	 * All lessees under this owner (only used where lessor is NULL).
> 
> @lessor so it's highlighted correctly
> 
>> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	struct idr lessee_idr;
>>   	/* private: */
> 
> With the nits addressed:
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Thanks for updating the docs!
> -Daniel
> 
>>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
>> -- 
>> 2.25.1
>>
> 

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 13:02       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22 13:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: airlied, gregkh, intel-gfx, linux-kernel,
	linux-graphics-maintainer, dri-devel, tzimmermann, skhan,
	linux-kernel-mentees

On 22/7/21 6:35 pm, Daniel Vetter wrote:
> On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
>> In particular, we make it clear that &drm_device.mode_config.idr_mutex
>> protects the lease idr and list structures for drm_master. The lessor
>> field itself doesn't need to be protected as it doesn't change after
>> it's set in drm_lease_create.
>>
>> Additionally, we add descriptions for the lifetime of lessors and
>> leases to make it easier to reason about them.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
>> ---
>>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 51 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
>> index f99d3417f304..c978c85464fa 100644
>> --- a/include/drm/drm_auth.h
>> +++ b/include/drm/drm_auth.h
>> @@ -58,12 +58,6 @@ struct drm_lock_data {
>>    * @refcount: Refcount for this master object.
>>    * @dev: Link back to the DRM device
>>    * @driver_priv: Pointer to driver-private information.
>> - * @lessor: Lease holder
>> - * @lessee_id: id for lessees. Owners always have id 0
>> - * @lessee_list: other lessees of the same master
>> - * @lessees: drm_masters leasing from this one
>> - * @leases: Objects leased to this drm_master.
>> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>>    *
>>    * Note that master structures are only relevant for the legacy/primary device
>>    * nodes, hence there can only be one per device, not one per drm_minor.
>> @@ -88,17 +82,63 @@ struct drm_master {
>>   	struct idr magic_map;
>>   	void *driver_priv;
>>   
>> -	/* Tree of display resource leases, each of which is a drm_master struct
>> -	 * All of these get activated simultaneously, so drm_device master points
>> -	 * at the top of the tree (for which lessor is NULL). Protected by
>> -	 * &drm_device.mode_config.idr_mutex.
>> +	/**
>> +	 * @lessor:
>> +	 *
>> +	 * Lease holder. The lessor does not change once it's set in
> 
> Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> clarify this with
> 
> "Lease grantor, only set if this struct drm_master represents a lessee
> holding a lease of objects from @lessor. Full owners of the device have
> this set to NULL."
> 
>> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that
> 
> I also figured it'd be a good idea to link to the drm_lease docs here to
> explain the concepts, but alas we don't have those :-( Hence at least
> define what we mean with lessor, lessee, lease and owner.
> 

Thanks for the suggestions, Daniel. I'll incorporate them in a v2.

Regarding the missing drm_lease docs... any reason we can't just add it 
in? Seems like most of the comments in drm_lease.c are almost correctly 
formatted too. I could clean them up, define the terms in a preamble, 
then add it to the v2 patch.

>> +	 * it releases upon being destroyed in drm_lease_destroy().
>> +	 *
>> +	 * Display resource leases form a tree of &struct drm_master. All of
> 
> For now we've limited the tree to a depth of 1, you can't create another
> lease if yourself are a lease. I guess another reason to update the
> drm_lease.c docs.
> 
> So maybe add "Currently the lease tree depth is limited to 1."
> 
>> +	 * these get activated simultaneously, so &drm_device.master
>> +	 * points at the top of the tree (for which lessor is NULL).
>>   	 */
>> -
>>   	struct drm_master *lessor;
>> +
>> +	/**
>> +	 * @lessee_id:
>> +	 *
>> +	 * ID for lessees. Owners always have ID 0. Protected by
> 
> Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	int	lessee_id;
>> +
>> +	/**
>> +	 * @lessee_list:
>> +	 *
>> +	 * List of lessees of the same master. Protected by
> 
> We try to distinguis between list entries and the list, even though it's
> the same struct. So maybe
> 
> "List entry of lessees of @lessor, where they are linked to @lessee. Not
> use for owners."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> 
>> +	 */
>>   	struct list_head lessee_list;
>> +
>> +	/**
>> +	 * @lessees:
>> +	 *
>> +	 * List of drm_masters leasing from this one. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * This master cannot be destroyed unless this list is empty as lessors
>> +	 * are referenced by all their lessees.
> 
> Maybe add "this list is empty of no leases have been granted."
> 
>> +	 */
>>   	struct list_head lessees;
>> +
>> +	/**
>> +	 * @leases:
>> +	 *
>> +	 * Objects leased to this drm_master. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * Objects are leased all together in drm_lease_create(), and are
>> +	 * removed all together when the lease is revoked.
>> +	 */
>>   	struct idr leases;
>> +
>> +	/**
>> +	 * @lessee_idr:
>> +	 *
>> +	 * All lessees under this owner (only used where lessor is NULL).
> 
> @lessor so it's highlighted correctly
> 
>> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	struct idr lessee_idr;
>>   	/* private: */
> 
> With the nits addressed:
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Thanks for updating the docs!
> -Daniel
> 
>>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
>> -- 
>> 2.25.1
>>
> 


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 13:02       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-22 13:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: airlied, gregkh, intel-gfx, linux-kernel, mripard,
	linux-graphics-maintainer, dri-devel, tzimmermann, skhan,
	linux-kernel-mentees, zackr

On 22/7/21 6:35 pm, Daniel Vetter wrote:
> On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
>> In particular, we make it clear that &drm_device.mode_config.idr_mutex
>> protects the lease idr and list structures for drm_master. The lessor
>> field itself doesn't need to be protected as it doesn't change after
>> it's set in drm_lease_create.
>>
>> Additionally, we add descriptions for the lifetime of lessors and
>> leases to make it easier to reason about them.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
>> ---
>>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 51 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
>> index f99d3417f304..c978c85464fa 100644
>> --- a/include/drm/drm_auth.h
>> +++ b/include/drm/drm_auth.h
>> @@ -58,12 +58,6 @@ struct drm_lock_data {
>>    * @refcount: Refcount for this master object.
>>    * @dev: Link back to the DRM device
>>    * @driver_priv: Pointer to driver-private information.
>> - * @lessor: Lease holder
>> - * @lessee_id: id for lessees. Owners always have id 0
>> - * @lessee_list: other lessees of the same master
>> - * @lessees: drm_masters leasing from this one
>> - * @leases: Objects leased to this drm_master.
>> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
>>    *
>>    * Note that master structures are only relevant for the legacy/primary device
>>    * nodes, hence there can only be one per device, not one per drm_minor.
>> @@ -88,17 +82,63 @@ struct drm_master {
>>   	struct idr magic_map;
>>   	void *driver_priv;
>>   
>> -	/* Tree of display resource leases, each of which is a drm_master struct
>> -	 * All of these get activated simultaneously, so drm_device master points
>> -	 * at the top of the tree (for which lessor is NULL). Protected by
>> -	 * &drm_device.mode_config.idr_mutex.
>> +	/**
>> +	 * @lessor:
>> +	 *
>> +	 * Lease holder. The lessor does not change once it's set in
> 
> Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> clarify this with
> 
> "Lease grantor, only set if this struct drm_master represents a lessee
> holding a lease of objects from @lessor. Full owners of the device have
> this set to NULL."
> 
>> +	 * drm_lease_create(). Each lessee holds a reference to its lessor that
> 
> I also figured it'd be a good idea to link to the drm_lease docs here to
> explain the concepts, but alas we don't have those :-( Hence at least
> define what we mean with lessor, lessee, lease and owner.
> 

Thanks for the suggestions, Daniel. I'll incorporate them in a v2.

Regarding the missing drm_lease docs... any reason we can't just add it 
in? Seems like most of the comments in drm_lease.c are almost correctly 
formatted too. I could clean them up, define the terms in a preamble, 
then add it to the v2 patch.

>> +	 * it releases upon being destroyed in drm_lease_destroy().
>> +	 *
>> +	 * Display resource leases form a tree of &struct drm_master. All of
> 
> For now we've limited the tree to a depth of 1, you can't create another
> lease if yourself are a lease. I guess another reason to update the
> drm_lease.c docs.
> 
> So maybe add "Currently the lease tree depth is limited to 1."
> 
>> +	 * these get activated simultaneously, so &drm_device.master
>> +	 * points at the top of the tree (for which lessor is NULL).
>>   	 */
>> -
>>   	struct drm_master *lessor;
>> +
>> +	/**
>> +	 * @lessee_id:
>> +	 *
>> +	 * ID for lessees. Owners always have ID 0. Protected by
> 
> Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	int	lessee_id;
>> +
>> +	/**
>> +	 * @lessee_list:
>> +	 *
>> +	 * List of lessees of the same master. Protected by
> 
> We try to distinguis between list entries and the list, even though it's
> the same struct. So maybe
> 
> "List entry of lessees of @lessor, where they are linked to @lessee. Not
> use for owners."
> 
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> 
>> +	 */
>>   	struct list_head lessee_list;
>> +
>> +	/**
>> +	 * @lessees:
>> +	 *
>> +	 * List of drm_masters leasing from this one. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * This master cannot be destroyed unless this list is empty as lessors
>> +	 * are referenced by all their lessees.
> 
> Maybe add "this list is empty of no leases have been granted."
> 
>> +	 */
>>   	struct list_head lessees;
>> +
>> +	/**
>> +	 * @leases:
>> +	 *
>> +	 * Objects leased to this drm_master. Protected by
>> +	 * &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 *
>> +	 * Objects are leased all together in drm_lease_create(), and are
>> +	 * removed all together when the lease is revoked.
>> +	 */
>>   	struct idr leases;
>> +
>> +	/**
>> +	 * @lessee_idr:
>> +	 *
>> +	 * All lessees under this owner (only used where lessor is NULL).
> 
> @lessor so it's highlighted correctly
> 
>> +	 * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
>> +	 */
>>   	struct idr lessee_idr;
>>   	/* private: */
> 
> With the nits addressed:
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Thanks for updating the docs!
> -Daniel
> 
>>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
>> -- 
>> 2.25.1
>>
> 

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm, drm/vmwgfx: fixes and updates related to drm_master
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
                   ` (5 preceding siblings ...)
  (?)
@ 2021-07-22 14:05 ` Patchwork
  -1 siblings, 0 replies; 72+ messages in thread
From: Patchwork @ 2021-07-22 14:05 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi; +Cc: intel-gfx

== Series Details ==

Series: drm, drm/vmwgfx: fixes and updates related to drm_master
URL   : https://patchwork.freedesktop.org/series/92894/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:312:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:316:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/drm_drv.c:425:6: warning: context imbalance in 'drm_dev_enter' - different lock contexts for basic block
+drivers/gpu/drm/i915/display/intel_display.c:1896:21:    expected struct i915_vma *[assigned] vma
+drivers/gpu/drm/i915/display/intel_display.c:1896:21:    got void [noderef] __iomem *[assigned] iomem
+drivers/gpu/drm/i915/display/intel_display.c:1896:21: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    expected struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    got struct i915_address_space *
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_reset.c:1396:5: warning: context imbalance in 'intel_gt_reset_trylock' - different lock contexts for basic block
+drivers/gpu/drm/i915/gt/intel_ring_submission.c:1210:24: warning: Using plain integer as NULL pointer
+drivers/gpu/drm/i915/i915_perf.c:1434:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/i915_perf.c:1488:15: warning: memset with byte count of 16777216
+./include/asm-generic/bitops/find.h:112:45: warning: shift count is negative (-262080)
+./include/asm-generic/bitops/find.h:32:31: warning: shift count is negative (-262080)
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write8' - different lock contexts for basic block
+./include/linux/srcu.h:188:9: warning: context imbalance in 'drm_dev_exit' - unexpected unlock


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
  2021-07-22 13:02       ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22 14:17         ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 14:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: VMware Graphics, Zack Rusin, Dave Airlie, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, dri-devel,
	Linux Kernel Mailing List, intel-gfx, Shuah Khan, Greg KH,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 3:03 PM Desmond Cheong Zhi Xi
<desmondcheongzx@gmail.com> wrote:
>
> On 22/7/21 6:35 pm, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> >> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> >> protects the lease idr and list structures for drm_master. The lessor
> >> field itself doesn't need to be protected as it doesn't change after
> >> it's set in drm_lease_create.
> >>
> >> Additionally, we add descriptions for the lifetime of lessors and
> >> leases to make it easier to reason about them.
> >>
> >> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> >> ---
> >>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
> >>   1 file changed, 51 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> >> index f99d3417f304..c978c85464fa 100644
> >> --- a/include/drm/drm_auth.h
> >> +++ b/include/drm/drm_auth.h
> >> @@ -58,12 +58,6 @@ struct drm_lock_data {
> >>    * @refcount: Refcount for this master object.
> >>    * @dev: Link back to the DRM device
> >>    * @driver_priv: Pointer to driver-private information.
> >> - * @lessor: Lease holder
> >> - * @lessee_id: id for lessees. Owners always have id 0
> >> - * @lessee_list: other lessees of the same master
> >> - * @lessees: drm_masters leasing from this one
> >> - * @leases: Objects leased to this drm_master.
> >> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
> >>    *
> >>    * Note that master structures are only relevant for the legacy/primary device
> >>    * nodes, hence there can only be one per device, not one per drm_minor.
> >> @@ -88,17 +82,63 @@ struct drm_master {
> >>      struct idr magic_map;
> >>      void *driver_priv;
> >>
> >> -    /* Tree of display resource leases, each of which is a drm_master struct
> >> -     * All of these get activated simultaneously, so drm_device master points
> >> -     * at the top of the tree (for which lessor is NULL). Protected by
> >> -     * &drm_device.mode_config.idr_mutex.
> >> +    /**
> >> +     * @lessor:
> >> +     *
> >> +     * Lease holder. The lessor does not change once it's set in
> >
> > Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> > clarify this with
> >
> > "Lease grantor, only set if this struct drm_master represents a lessee
> > holding a lease of objects from @lessor. Full owners of the device have
> > this set to NULL."
> >
> >> +     * drm_lease_create(). Each lessee holds a reference to its lessor that
> >
> > I also figured it'd be a good idea to link to the drm_lease docs here to
> > explain the concepts, but alas we don't have those :-( Hence at least
> > define what we mean with lessor, lessee, lease and owner.
> >
>
> Thanks for the suggestions, Daniel. I'll incorporate them in a v2.
>
> Regarding the missing drm_lease docs... any reason we can't just add it
> in? Seems like most of the comments in drm_lease.c are almost correctly
> formatted too. I could clean them up, define the terms in a preamble,
> then add it to the v2 patch.

Sure if you want to do that, that would be great. Usual style tips:
- We only document driver interfaces, so structs/inline functions in
headers and exported symbols in .c files.
- Anything else interesting just leave as normal C comments
- An overview DOC: section that explains a bit how leases work and why
(git blame on the commit that added it should help, otherwise I can
type that up) would also be really great.

I think the right place for this is in the drm-uapi.rst section after
the section about primary nodes:

https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#modeset-base-object-abstraction

Cheers, Daniel


>
> >> +     * it releases upon being destroyed in drm_lease_destroy().
> >> +     *
> >> +     * Display resource leases form a tree of &struct drm_master. All of
> >
> > For now we've limited the tree to a depth of 1, you can't create another
> > lease if yourself are a lease. I guess another reason to update the
> > drm_lease.c docs.
> >
> > So maybe add "Currently the lease tree depth is limited to 1."
> >
> >> +     * these get activated simultaneously, so &drm_device.master
> >> +     * points at the top of the tree (for which lessor is NULL).
> >>       */
> >> -
> >>      struct drm_master *lessor;
> >> +
> >> +    /**
> >> +     * @lessee_id:
> >> +     *
> >> +     * ID for lessees. Owners always have ID 0. Protected by
> >
> > Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      int     lessee_id;
> >> +
> >> +    /**
> >> +     * @lessee_list:
> >> +     *
> >> +     * List of lessees of the same master. Protected by
> >
> > We try to distinguis between list entries and the list, even though it's
> > the same struct. So maybe
> >
> > "List entry of lessees of @lessor, where they are linked to @lessee. Not
> > use for owners."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >
> >> +     */
> >>      struct list_head lessee_list;
> >> +
> >> +    /**
> >> +     * @lessees:
> >> +     *
> >> +     * List of drm_masters leasing from this one. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * This master cannot be destroyed unless this list is empty as lessors
> >> +     * are referenced by all their lessees.
> >
> > Maybe add "this list is empty of no leases have been granted."
> >
> >> +     */
> >>      struct list_head lessees;
> >> +
> >> +    /**
> >> +     * @leases:
> >> +     *
> >> +     * Objects leased to this drm_master. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * Objects are leased all together in drm_lease_create(), and are
> >> +     * removed all together when the lease is revoked.
> >> +     */
> >>      struct idr leases;
> >> +
> >> +    /**
> >> +     * @lessee_idr:
> >> +     *
> >> +     * All lessees under this owner (only used where lessor is NULL).
> >
> > @lessor so it's highlighted correctly
> >
> >> +     * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      struct idr lessee_idr;
> >>      /* private: */
> >
> > With the nits addressed:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > Thanks for updating the docs!
> > -Daniel
> >
> >>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
> >> --
> >> 2.25.1
> >>
> >
>


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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 14:17         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 14:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: Dave Airlie, intel-gfx, Maarten Lankhorst,
	Linux Kernel Mailing List, Maxime Ripard, VMware Graphics,
	dri-devel, Thomas Zimmermann, linux-kernel-mentees, Zack Rusin

On Thu, Jul 22, 2021 at 3:03 PM Desmond Cheong Zhi Xi
<desmondcheongzx@gmail.com> wrote:
>
> On 22/7/21 6:35 pm, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> >> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> >> protects the lease idr and list structures for drm_master. The lessor
> >> field itself doesn't need to be protected as it doesn't change after
> >> it's set in drm_lease_create.
> >>
> >> Additionally, we add descriptions for the lifetime of lessors and
> >> leases to make it easier to reason about them.
> >>
> >> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> >> ---
> >>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
> >>   1 file changed, 51 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> >> index f99d3417f304..c978c85464fa 100644
> >> --- a/include/drm/drm_auth.h
> >> +++ b/include/drm/drm_auth.h
> >> @@ -58,12 +58,6 @@ struct drm_lock_data {
> >>    * @refcount: Refcount for this master object.
> >>    * @dev: Link back to the DRM device
> >>    * @driver_priv: Pointer to driver-private information.
> >> - * @lessor: Lease holder
> >> - * @lessee_id: id for lessees. Owners always have id 0
> >> - * @lessee_list: other lessees of the same master
> >> - * @lessees: drm_masters leasing from this one
> >> - * @leases: Objects leased to this drm_master.
> >> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
> >>    *
> >>    * Note that master structures are only relevant for the legacy/primary device
> >>    * nodes, hence there can only be one per device, not one per drm_minor.
> >> @@ -88,17 +82,63 @@ struct drm_master {
> >>      struct idr magic_map;
> >>      void *driver_priv;
> >>
> >> -    /* Tree of display resource leases, each of which is a drm_master struct
> >> -     * All of these get activated simultaneously, so drm_device master points
> >> -     * at the top of the tree (for which lessor is NULL). Protected by
> >> -     * &drm_device.mode_config.idr_mutex.
> >> +    /**
> >> +     * @lessor:
> >> +     *
> >> +     * Lease holder. The lessor does not change once it's set in
> >
> > Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> > clarify this with
> >
> > "Lease grantor, only set if this struct drm_master represents a lessee
> > holding a lease of objects from @lessor. Full owners of the device have
> > this set to NULL."
> >
> >> +     * drm_lease_create(). Each lessee holds a reference to its lessor that
> >
> > I also figured it'd be a good idea to link to the drm_lease docs here to
> > explain the concepts, but alas we don't have those :-( Hence at least
> > define what we mean with lessor, lessee, lease and owner.
> >
>
> Thanks for the suggestions, Daniel. I'll incorporate them in a v2.
>
> Regarding the missing drm_lease docs... any reason we can't just add it
> in? Seems like most of the comments in drm_lease.c are almost correctly
> formatted too. I could clean them up, define the terms in a preamble,
> then add it to the v2 patch.

Sure if you want to do that, that would be great. Usual style tips:
- We only document driver interfaces, so structs/inline functions in
headers and exported symbols in .c files.
- Anything else interesting just leave as normal C comments
- An overview DOC: section that explains a bit how leases work and why
(git blame on the commit that added it should help, otherwise I can
type that up) would also be really great.

I think the right place for this is in the drm-uapi.rst section after
the section about primary nodes:

https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#modeset-base-object-abstraction

Cheers, Daniel


>
> >> +     * it releases upon being destroyed in drm_lease_destroy().
> >> +     *
> >> +     * Display resource leases form a tree of &struct drm_master. All of
> >
> > For now we've limited the tree to a depth of 1, you can't create another
> > lease if yourself are a lease. I guess another reason to update the
> > drm_lease.c docs.
> >
> > So maybe add "Currently the lease tree depth is limited to 1."
> >
> >> +     * these get activated simultaneously, so &drm_device.master
> >> +     * points at the top of the tree (for which lessor is NULL).
> >>       */
> >> -
> >>      struct drm_master *lessor;
> >> +
> >> +    /**
> >> +     * @lessee_id:
> >> +     *
> >> +     * ID for lessees. Owners always have ID 0. Protected by
> >
> > Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      int     lessee_id;
> >> +
> >> +    /**
> >> +     * @lessee_list:
> >> +     *
> >> +     * List of lessees of the same master. Protected by
> >
> > We try to distinguis between list entries and the list, even though it's
> > the same struct. So maybe
> >
> > "List entry of lessees of @lessor, where they are linked to @lessee. Not
> > use for owners."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >
> >> +     */
> >>      struct list_head lessee_list;
> >> +
> >> +    /**
> >> +     * @lessees:
> >> +     *
> >> +     * List of drm_masters leasing from this one. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * This master cannot be destroyed unless this list is empty as lessors
> >> +     * are referenced by all their lessees.
> >
> > Maybe add "this list is empty of no leases have been granted."
> >
> >> +     */
> >>      struct list_head lessees;
> >> +
> >> +    /**
> >> +     * @leases:
> >> +     *
> >> +     * Objects leased to this drm_master. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * Objects are leased all together in drm_lease_create(), and are
> >> +     * removed all together when the lease is revoked.
> >> +     */
> >>      struct idr leases;
> >> +
> >> +    /**
> >> +     * @lessee_idr:
> >> +     *
> >> +     * All lessees under this owner (only used where lessor is NULL).
> >
> > @lessor so it's highlighted correctly
> >
> >> +     * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      struct idr lessee_idr;
> >>      /* private: */
> >
> > With the nits addressed:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > Thanks for updating the docs!
> > -Daniel
> >
> >>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
> >> --
> >> 2.25.1
> >>
> >
>


-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 14:17         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 14:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: Dave Airlie, Greg KH, intel-gfx, Linux Kernel Mailing List,
	VMware Graphics, dri-devel, Thomas Zimmermann, Shuah Khan,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 3:03 PM Desmond Cheong Zhi Xi
<desmondcheongzx@gmail.com> wrote:
>
> On 22/7/21 6:35 pm, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> >> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> >> protects the lease idr and list structures for drm_master. The lessor
> >> field itself doesn't need to be protected as it doesn't change after
> >> it's set in drm_lease_create.
> >>
> >> Additionally, we add descriptions for the lifetime of lessors and
> >> leases to make it easier to reason about them.
> >>
> >> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> >> ---
> >>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
> >>   1 file changed, 51 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> >> index f99d3417f304..c978c85464fa 100644
> >> --- a/include/drm/drm_auth.h
> >> +++ b/include/drm/drm_auth.h
> >> @@ -58,12 +58,6 @@ struct drm_lock_data {
> >>    * @refcount: Refcount for this master object.
> >>    * @dev: Link back to the DRM device
> >>    * @driver_priv: Pointer to driver-private information.
> >> - * @lessor: Lease holder
> >> - * @lessee_id: id for lessees. Owners always have id 0
> >> - * @lessee_list: other lessees of the same master
> >> - * @lessees: drm_masters leasing from this one
> >> - * @leases: Objects leased to this drm_master.
> >> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
> >>    *
> >>    * Note that master structures are only relevant for the legacy/primary device
> >>    * nodes, hence there can only be one per device, not one per drm_minor.
> >> @@ -88,17 +82,63 @@ struct drm_master {
> >>      struct idr magic_map;
> >>      void *driver_priv;
> >>
> >> -    /* Tree of display resource leases, each of which is a drm_master struct
> >> -     * All of these get activated simultaneously, so drm_device master points
> >> -     * at the top of the tree (for which lessor is NULL). Protected by
> >> -     * &drm_device.mode_config.idr_mutex.
> >> +    /**
> >> +     * @lessor:
> >> +     *
> >> +     * Lease holder. The lessor does not change once it's set in
> >
> > Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> > clarify this with
> >
> > "Lease grantor, only set if this struct drm_master represents a lessee
> > holding a lease of objects from @lessor. Full owners of the device have
> > this set to NULL."
> >
> >> +     * drm_lease_create(). Each lessee holds a reference to its lessor that
> >
> > I also figured it'd be a good idea to link to the drm_lease docs here to
> > explain the concepts, but alas we don't have those :-( Hence at least
> > define what we mean with lessor, lessee, lease and owner.
> >
>
> Thanks for the suggestions, Daniel. I'll incorporate them in a v2.
>
> Regarding the missing drm_lease docs... any reason we can't just add it
> in? Seems like most of the comments in drm_lease.c are almost correctly
> formatted too. I could clean them up, define the terms in a preamble,
> then add it to the v2 patch.

Sure if you want to do that, that would be great. Usual style tips:
- We only document driver interfaces, so structs/inline functions in
headers and exported symbols in .c files.
- Anything else interesting just leave as normal C comments
- An overview DOC: section that explains a bit how leases work and why
(git blame on the commit that added it should help, otherwise I can
type that up) would also be really great.

I think the right place for this is in the drm-uapi.rst section after
the section about primary nodes:

https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#modeset-base-object-abstraction

Cheers, Daniel


>
> >> +     * it releases upon being destroyed in drm_lease_destroy().
> >> +     *
> >> +     * Display resource leases form a tree of &struct drm_master. All of
> >
> > For now we've limited the tree to a depth of 1, you can't create another
> > lease if yourself are a lease. I guess another reason to update the
> > drm_lease.c docs.
> >
> > So maybe add "Currently the lease tree depth is limited to 1."
> >
> >> +     * these get activated simultaneously, so &drm_device.master
> >> +     * points at the top of the tree (for which lessor is NULL).
> >>       */
> >> -
> >>      struct drm_master *lessor;
> >> +
> >> +    /**
> >> +     * @lessee_id:
> >> +     *
> >> +     * ID for lessees. Owners always have ID 0. Protected by
> >
> > Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      int     lessee_id;
> >> +
> >> +    /**
> >> +     * @lessee_list:
> >> +     *
> >> +     * List of lessees of the same master. Protected by
> >
> > We try to distinguis between list entries and the list, even though it's
> > the same struct. So maybe
> >
> > "List entry of lessees of @lessor, where they are linked to @lessee. Not
> > use for owners."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >
> >> +     */
> >>      struct list_head lessee_list;
> >> +
> >> +    /**
> >> +     * @lessees:
> >> +     *
> >> +     * List of drm_masters leasing from this one. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * This master cannot be destroyed unless this list is empty as lessors
> >> +     * are referenced by all their lessees.
> >
> > Maybe add "this list is empty of no leases have been granted."
> >
> >> +     */
> >>      struct list_head lessees;
> >> +
> >> +    /**
> >> +     * @leases:
> >> +     *
> >> +     * Objects leased to this drm_master. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * Objects are leased all together in drm_lease_create(), and are
> >> +     * removed all together when the lease is revoked.
> >> +     */
> >>      struct idr leases;
> >> +
> >> +    /**
> >> +     * @lessee_idr:
> >> +     *
> >> +     * All lessees under this owner (only used where lessor is NULL).
> >
> > @lessor so it's highlighted correctly
> >
> >> +     * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      struct idr lessee_idr;
> >>      /* private: */
> >
> > With the nits addressed:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > Thanks for updating the docs!
> > -Daniel
> >
> >>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
> >> --
> >> 2.25.1
> >>
> >
>


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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 2/3] drm: clarify lifetime/locking for drm_master's lease fields
@ 2021-07-22 14:17         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 14:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: Dave Airlie, Greg KH, intel-gfx, Linux Kernel Mailing List,
	Maxime Ripard, VMware Graphics, dri-devel, Thomas Zimmermann,
	Shuah Khan, linux-kernel-mentees, Zack Rusin

On Thu, Jul 22, 2021 at 3:03 PM Desmond Cheong Zhi Xi
<desmondcheongzx@gmail.com> wrote:
>
> On 22/7/21 6:35 pm, Daniel Vetter wrote:
> > On Thu, Jul 22, 2021 at 05:29:28PM +0800, Desmond Cheong Zhi Xi wrote:
> >> In particular, we make it clear that &drm_device.mode_config.idr_mutex
> >> protects the lease idr and list structures for drm_master. The lessor
> >> field itself doesn't need to be protected as it doesn't change after
> >> it's set in drm_lease_create.
> >>
> >> Additionally, we add descriptions for the lifetime of lessors and
> >> leases to make it easier to reason about them.
> >>
> >> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> >> ---
> >>   include/drm/drm_auth.h | 62 ++++++++++++++++++++++++++++++++++--------
> >>   1 file changed, 51 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> >> index f99d3417f304..c978c85464fa 100644
> >> --- a/include/drm/drm_auth.h
> >> +++ b/include/drm/drm_auth.h
> >> @@ -58,12 +58,6 @@ struct drm_lock_data {
> >>    * @refcount: Refcount for this master object.
> >>    * @dev: Link back to the DRM device
> >>    * @driver_priv: Pointer to driver-private information.
> >> - * @lessor: Lease holder
> >> - * @lessee_id: id for lessees. Owners always have id 0
> >> - * @lessee_list: other lessees of the same master
> >> - * @lessees: drm_masters leasing from this one
> >> - * @leases: Objects leased to this drm_master.
> >> - * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
> >>    *
> >>    * Note that master structures are only relevant for the legacy/primary device
> >>    * nodes, hence there can only be one per device, not one per drm_minor.
> >> @@ -88,17 +82,63 @@ struct drm_master {
> >>      struct idr magic_map;
> >>      void *driver_priv;
> >>
> >> -    /* Tree of display resource leases, each of which is a drm_master struct
> >> -     * All of these get activated simultaneously, so drm_device master points
> >> -     * at the top of the tree (for which lessor is NULL). Protected by
> >> -     * &drm_device.mode_config.idr_mutex.
> >> +    /**
> >> +     * @lessor:
> >> +     *
> >> +     * Lease holder. The lessor does not change once it's set in
> >
> > Lessor is the lease grantor, lessee is the one receiving the lease. Maybe
> > clarify this with
> >
> > "Lease grantor, only set if this struct drm_master represents a lessee
> > holding a lease of objects from @lessor. Full owners of the device have
> > this set to NULL."
> >
> >> +     * drm_lease_create(). Each lessee holds a reference to its lessor that
> >
> > I also figured it'd be a good idea to link to the drm_lease docs here to
> > explain the concepts, but alas we don't have those :-( Hence at least
> > define what we mean with lessor, lessee, lease and owner.
> >
>
> Thanks for the suggestions, Daniel. I'll incorporate them in a v2.
>
> Regarding the missing drm_lease docs... any reason we can't just add it
> in? Seems like most of the comments in drm_lease.c are almost correctly
> formatted too. I could clean them up, define the terms in a preamble,
> then add it to the v2 patch.

Sure if you want to do that, that would be great. Usual style tips:
- We only document driver interfaces, so structs/inline functions in
headers and exported symbols in .c files.
- Anything else interesting just leave as normal C comments
- An overview DOC: section that explains a bit how leases work and why
(git blame on the commit that added it should help, otherwise I can
type that up) would also be really great.

I think the right place for this is in the drm-uapi.rst section after
the section about primary nodes:

https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#modeset-base-object-abstraction

Cheers, Daniel


>
> >> +     * it releases upon being destroyed in drm_lease_destroy().
> >> +     *
> >> +     * Display resource leases form a tree of &struct drm_master. All of
> >
> > For now we've limited the tree to a depth of 1, you can't create another
> > lease if yourself are a lease. I guess another reason to update the
> > drm_lease.c docs.
> >
> > So maybe add "Currently the lease tree depth is limited to 1."
> >
> >> +     * these get activated simultaneously, so &drm_device.master
> >> +     * points at the top of the tree (for which lessor is NULL).
> >>       */
> >> -
> >>      struct drm_master *lessor;
> >> +
> >> +    /**
> >> +     * @lessee_id:
> >> +     *
> >> +     * ID for lessees. Owners always have ID 0. Protected by
> >
> > Maybe clarify to "Owners (i.e. @lessor is NULL) ..."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      int     lessee_id;
> >> +
> >> +    /**
> >> +     * @lessee_list:
> >> +     *
> >> +     * List of lessees of the same master. Protected by
> >
> > We try to distinguis between list entries and the list, even though it's
> > the same struct. So maybe
> >
> > "List entry of lessees of @lessor, where they are linked to @lessee. Not
> > use for owners."
> >
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >
> >> +     */
> >>      struct list_head lessee_list;
> >> +
> >> +    /**
> >> +     * @lessees:
> >> +     *
> >> +     * List of drm_masters leasing from this one. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * This master cannot be destroyed unless this list is empty as lessors
> >> +     * are referenced by all their lessees.
> >
> > Maybe add "this list is empty of no leases have been granted."
> >
> >> +     */
> >>      struct list_head lessees;
> >> +
> >> +    /**
> >> +     * @leases:
> >> +     *
> >> +     * Objects leased to this drm_master. Protected by
> >> +     * &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     *
> >> +     * Objects are leased all together in drm_lease_create(), and are
> >> +     * removed all together when the lease is revoked.
> >> +     */
> >>      struct idr leases;
> >> +
> >> +    /**
> >> +     * @lessee_idr:
> >> +     *
> >> +     * All lessees under this owner (only used where lessor is NULL).
> >
> > @lessor so it's highlighted correctly
> >
> >> +     * Protected by &drm_device.mode_config's &drm_mode_config.idr_mutex.
> >> +     */
> >>      struct idr lessee_idr;
> >>      /* private: */
> >
> > With the nits addressed:
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > Thanks for updating the docs!
> > -Daniel
> >
> >>   #if IS_ENABLED(CONFIG_DRM_LEGACY)
> >> --
> >> 2.25.1
> >>
> >
>


-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BAT: failure for drm, drm/vmwgfx: fixes and updates related to drm_master
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
                   ` (6 preceding siblings ...)
  (?)
@ 2021-07-22 14:34 ` Patchwork
  -1 siblings, 0 replies; 72+ messages in thread
From: Patchwork @ 2021-07-22 14:34 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 4441 bytes --]

== Series Details ==

Series: drm, drm/vmwgfx: fixes and updates related to drm_master
URL   : https://patchwork.freedesktop.org/series/92894/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10371 -> Patchwork_20678
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_20678 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_20678, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_20678:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_pm_rpm@basic-rte:
    - fi-bdw-5557u:       NOTRUN -> [FAIL][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-bdw-5557u/igt@i915_pm_rpm@basic-rte.html

  
Known issues
------------

  Here are the changes found in Patchwork_20678 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_basic@query-info:
    - fi-bsw-kefka:       NOTRUN -> [SKIP][2] ([fdo#109271]) +17 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-bsw-kefka/igt@amdgpu/amd_basic@query-info.html

  * igt@amdgpu/amd_basic@semaphore:
    - fi-bdw-5557u:       NOTRUN -> [SKIP][3] ([fdo#109271]) +25 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-bdw-5557u/igt@amdgpu/amd_basic@semaphore.html

  * igt@core_hotunplug@unbind-rebind:
    - fi-bdw-5557u:       NOTRUN -> [WARN][4] ([i915#3718])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-bdw-5557u/igt@core_hotunplug@unbind-rebind.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3:
    - {fi-tgl-1115g4}:    [FAIL][5] ([i915#1888]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10371/fi-tgl-1115g4/igt@gem_exec_suspend@basic-s3.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-tgl-1115g4/igt@gem_exec_suspend@basic-s3.html

  * igt@i915_selftest@live@execlists:
    - fi-bsw-kefka:       [INCOMPLETE][7] ([i915#2782] / [i915#2940]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10371/fi-bsw-kefka/igt@i915_selftest@live@execlists.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-bsw-kefka/igt@i915_selftest@live@execlists.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-kbl-7500u:       [FAIL][9] ([i915#1372]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10371/fi-kbl-7500u/igt@kms_chamelium@dp-crc-fast.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/fi-kbl-7500u/igt@kms_chamelium@dp-crc-fast.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1372]: https://gitlab.freedesktop.org/drm/intel/issues/1372
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#2782]: https://gitlab.freedesktop.org/drm/intel/issues/2782
  [i915#2940]: https://gitlab.freedesktop.org/drm/intel/issues/2940
  [i915#3303]: https://gitlab.freedesktop.org/drm/intel/issues/3303
  [i915#3718]: https://gitlab.freedesktop.org/drm/intel/issues/3718


Participating hosts (38 -> 35)
------------------------------

  Missing    (3): fi-ilk-m540 fi-bdw-samus fi-hsw-4200u 


Build changes
-------------

  * Linux: CI_DRM_10371 -> Patchwork_20678

  CI-20190529: 20190529
  CI_DRM_10371: 8e68c13425e29c96ef94c9dd3583159000c61380 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6147: f3994c2cd99a1acfe991a8cc838a387dcb36598a @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_20678: c769f5bcae2da742a6d8fa65c0d7e26f5221f1d4 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

c769f5bcae2d drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
72270d8ebee2 drm: clarify lifetime/locking for drm_master's lease fields
b8826c209274 drm: use the lookup lock in drm_is_current_master

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20678/index.html

[-- Attachment #1.2: Type: text/html, Size: 5245 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22 10:38     ` Daniel Vetter
  (?)
@ 2021-07-22 15:04       ` Boqun Feng
  -1 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-22 15:04 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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 ;-)

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 15:04       ` Boqun Feng
  0 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-22 15:04 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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 ;-)

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
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 15:04       ` Boqun Feng
  0 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-22 15:04 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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 ;-)

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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22 15:04       ` Boqun Feng
  (?)
  (?)
@ 2021-07-22 19:02         ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 19:02 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra, VMware Graphics,
	Zack Rusin, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, dri-devel, intel-gfx, Shuah Khan, Greg KH,
	linux-kernel-mentees

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 19:02         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 19:02 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Peter Zijlstra, intel-gfx, Maarten Lankhorst, LKML,
	Maxime Ripard, Dave Airlie, VMware Graphics, dri-devel,
	Thomas Zimmermann, Desmond Cheong Zhi Xi, linux-kernel-mentees,
	Zack Rusin

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 19:02         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 19:02 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Peter Zijlstra, Greg KH, intel-gfx, LKML, Dave Airlie,
	VMware Graphics, dri-devel, Thomas Zimmermann, Shuah Khan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-22 19:02         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-22 19:02 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Peter Zijlstra, Greg KH, intel-gfx, LKML, Maxime Ripard,
	Dave Airlie, VMware Graphics, dri-devel, Thomas Zimmermann,
	Shuah Khan, Desmond Cheong Zhi Xi, linux-kernel-mentees,
	Zack Rusin

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
  2021-07-22  9:29   ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-22 19:17     ` Zack Rusin
  -1 siblings, 0 replies; 72+ messages in thread
From: Zack Rusin @ 2021-07-22 19:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, linux-graphics-maintainer, airlied,
	daniel, maarten.lankhorst, mripard, tzimmermann
  Cc: dri-devel, linux-kernel, intel-gfx, skhan, gregkh, linux-kernel-mentees

On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Zack Rusin <zackr@vmware.com>

Thanks for taking the time to fix this. Apart from the clear logic error, do you happen to know under what circumstances would this be hit? We have someone looking at writing some vmwgfx specific igt tests and I was wondering if I could add this to the list.

z

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 19:17     ` Zack Rusin
  0 siblings, 0 replies; 72+ messages in thread
From: Zack Rusin @ 2021-07-22 19:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, linux-graphics-maintainer, airlied,
	daniel, maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, linux-kernel-mentees

On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Zack Rusin <zackr@vmware.com>

Thanks for taking the time to fix this. Apart from the clear logic error, do you happen to know under what circumstances would this be hit? We have someone looking at writing some vmwgfx specific igt tests and I was wondering if I could add this to the list.

z
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 19:17     ` Zack Rusin
  0 siblings, 0 replies; 72+ messages in thread
From: Zack Rusin @ 2021-07-22 19:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, linux-graphics-maintainer, airlied,
	daniel, maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan, linux-kernel-mentees

On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Zack Rusin <zackr@vmware.com>

Thanks for taking the time to fix this. Apart from the clear logic error, do you happen to know under what circumstances would this be hit? We have someone looking at writing some vmwgfx specific igt tests and I was wondering if I could add this to the list.

z

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-22 19:17     ` Zack Rusin
  0 siblings, 0 replies; 72+ messages in thread
From: Zack Rusin @ 2021-07-22 19:17 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, linux-graphics-maintainer, airlied,
	daniel, maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan, linux-kernel-mentees

On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
> drm_file.master should be protected by either drm_device.master_mutex
> or drm_file.master_lookup_lock when being dereferenced. However,
> drm_master_get is called on unprotected file_priv->master pointers in
> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
> 
> This is fixed by replacing drm_master_get with drm_file_get_master.
> 
> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

Reviewed-by: Zack Rusin <zackr@vmware.com>

Thanks for taking the time to fix this. Apart from the clear logic error, do you happen to know under what circumstances would this be hit? We have someone looking at writing some vmwgfx specific igt tests and I was wondering if I could add this to the list.

z
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
  2021-07-22 19:17     ` Zack Rusin
  (?)
  (?)
@ 2021-07-23  6:44       ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-23  6:44 UTC (permalink / raw)
  To: Zack Rusin, linux-graphics-maintainer, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: dri-devel, linux-kernel, intel-gfx, skhan, gregkh, linux-kernel-mentees

On 23/7/21 3:17 am, Zack Rusin wrote:
> On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
>> drm_file.master should be protected by either drm_device.master_mutex
>> or drm_file.master_lookup_lock when being dereferenced. However,
>> drm_master_get is called on unprotected file_priv->master pointers in
>> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
>>
>> This is fixed by replacing drm_master_get with drm_file_get_master.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> 
> Reviewed-by: Zack Rusin <zackr@vmware.com>
> 
> Thanks for taking the time to fix this. Apart from the clear logic 
> error, do you happen to know under what circumstances would this be hit? 
> We have someone looking at writing some vmwgfx specific igt tests and I 
> was wondering if I could add this to the list.
> 
> z

Hi Zack,

Thanks for the review.

For some context, the use-after-free happens when there's a race between 
accessing the value of drm_file.master, and a call to 
drm_setmaster_ioctl. If drm_file is not the creator of master, then the 
ioctl allocates a new master for drm_file and puts the old master.

Thus for example, the old value of drm_file.master could be freed in 
between getting the value of file_priv->master, and the call to 
drm_master_get.

I'm not entirely sure whether this scenario is a good candidate for a test?

For further reference, the issue was originally caught by Syzbot here:
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803

And from the logs it seems that the reproducer set up a race between 
DRM_IOCTL_GET_UNIQUE and DRM_IOCTL_SET_MASTER. So possibly a race 
between VMW_CREATE_SURFACE and DRM_IOCTL_SET_MASTER could trigger the 
same bug.

Best wishes,
Desmond


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-23  6:44       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-23  6:44 UTC (permalink / raw)
  To: Zack Rusin, linux-graphics-maintainer, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: intel-gfx, linux-kernel, dri-devel, linux-kernel-mentees

On 23/7/21 3:17 am, Zack Rusin wrote:
> On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
>> drm_file.master should be protected by either drm_device.master_mutex
>> or drm_file.master_lookup_lock when being dereferenced. However,
>> drm_master_get is called on unprotected file_priv->master pointers in
>> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
>>
>> This is fixed by replacing drm_master_get with drm_file_get_master.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> 
> Reviewed-by: Zack Rusin <zackr@vmware.com>
> 
> Thanks for taking the time to fix this. Apart from the clear logic 
> error, do you happen to know under what circumstances would this be hit? 
> We have someone looking at writing some vmwgfx specific igt tests and I 
> was wondering if I could add this to the list.
> 
> z

Hi Zack,

Thanks for the review.

For some context, the use-after-free happens when there's a race between 
accessing the value of drm_file.master, and a call to 
drm_setmaster_ioctl. If drm_file is not the creator of master, then the 
ioctl allocates a new master for drm_file and puts the old master.

Thus for example, the old value of drm_file.master could be freed in 
between getting the value of file_priv->master, and the call to 
drm_master_get.

I'm not entirely sure whether this scenario is a good candidate for a test?

For further reference, the issue was originally caught by Syzbot here:
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803

And from the logs it seems that the reproducer set up a race between 
DRM_IOCTL_GET_UNIQUE and DRM_IOCTL_SET_MASTER. So possibly a race 
between VMW_CREATE_SURFACE and DRM_IOCTL_SET_MASTER could trigger the 
same bug.

Best wishes,
Desmond

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-23  6:44       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-23  6:44 UTC (permalink / raw)
  To: Zack Rusin, linux-graphics-maintainer, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan, linux-kernel-mentees

On 23/7/21 3:17 am, Zack Rusin wrote:
> On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
>> drm_file.master should be protected by either drm_device.master_mutex
>> or drm_file.master_lookup_lock when being dereferenced. However,
>> drm_master_get is called on unprotected file_priv->master pointers in
>> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
>>
>> This is fixed by replacing drm_master_get with drm_file_get_master.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> 
> Reviewed-by: Zack Rusin <zackr@vmware.com>
> 
> Thanks for taking the time to fix this. Apart from the clear logic 
> error, do you happen to know under what circumstances would this be hit? 
> We have someone looking at writing some vmwgfx specific igt tests and I 
> was wondering if I could add this to the list.
> 
> z

Hi Zack,

Thanks for the review.

For some context, the use-after-free happens when there's a race between 
accessing the value of drm_file.master, and a call to 
drm_setmaster_ioctl. If drm_file is not the creator of master, then the 
ioctl allocates a new master for drm_file and puts the old master.

Thus for example, the old value of drm_file.master could be freed in 
between getting the value of file_priv->master, and the call to 
drm_master_get.

I'm not entirely sure whether this scenario is a good candidate for a test?

For further reference, the issue was originally caught by Syzbot here:
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803

And from the logs it seems that the reproducer set up a race between 
DRM_IOCTL_GET_UNIQUE and DRM_IOCTL_SET_MASTER. So possibly a race 
between VMW_CREATE_SURFACE and DRM_IOCTL_SET_MASTER could trigger the 
same bug.

Best wishes,
Desmond


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 3/3] drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
@ 2021-07-23  6:44       ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-23  6:44 UTC (permalink / raw)
  To: Zack Rusin, linux-graphics-maintainer, airlied, daniel,
	maarten.lankhorst, mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel, dri-devel, skhan, linux-kernel-mentees

On 23/7/21 3:17 am, Zack Rusin wrote:
> On 7/22/21 5:29 AM, Desmond Cheong Zhi Xi wrote:
>> drm_file.master should be protected by either drm_device.master_mutex
>> or drm_file.master_lookup_lock when being dereferenced. However,
>> drm_master_get is called on unprotected file_priv->master pointers in
>> vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
>>
>> This is fixed by replacing drm_master_get with drm_file_get_master.
>>
>> Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
> 
> Reviewed-by: Zack Rusin <zackr@vmware.com>
> 
> Thanks for taking the time to fix this. Apart from the clear logic 
> error, do you happen to know under what circumstances would this be hit? 
> We have someone looking at writing some vmwgfx specific igt tests and I 
> was wondering if I could add this to the list.
> 
> z

Hi Zack,

Thanks for the review.

For some context, the use-after-free happens when there's a race between 
accessing the value of drm_file.master, and a call to 
drm_setmaster_ioctl. If drm_file is not the creator of master, then the 
ioctl allocates a new master for drm_file and puts the old master.

Thus for example, the old value of drm_file.master could be freed in 
between getting the value of file_priv->master, and the call to 
drm_master_get.

I'm not entirely sure whether this scenario is a good candidate for a test?

For further reference, the issue was originally caught by Syzbot here:
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803

And from the logs it seems that the reproducer set up a race between 
DRM_IOCTL_GET_UNIQUE and DRM_IOCTL_SET_MASTER. So possibly a race 
between VMW_CREATE_SURFACE and DRM_IOCTL_SET_MASTER could trigger the 
same bug.

Best wishes,
Desmond

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22 19:02         ` Daniel Vetter
  (?)
@ 2021-07-23  7:16           ` Boqun Feng
  -1 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-23  7:16 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra, VMware Graphics,
	Zack Rusin, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, dri-devel, intel-gfx, Shuah Khan, Greg KH,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 09:02:41PM +0200, Daniel Vetter wrote:
> 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.
> 

Make sense, so we'd better also provide lockdep_assert_held_both(), I
think, to use it at the update side, something as below:


	/*
	 * lockdep_assert_held_{both,either}().
	 * 
	 * Sometimes users can use a combination of two locks to
	 * implement a rwlock-like lock, for example, say we have
	 * locks L1 and L2, and we only allow updates when two locks
	 * both held like:
	 * 
	 * update()
	 * {
	 *	lockdep_assert_held_both(L1, L2);
	 *	x++; // update x
	 * }
	 *
	 * while for read-only accesses, either lock suffices (since
	 * holding either lock means others cannot hold both, so readers
	 * serialized with the updaters):
	 *
	 * read()
	 * {
	 * 	lockdep_assert_held_either(L1, L2);
	 *	r = x; // read x
	 * }
	 */

	#define lockdep_assert_held_both(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) ||		\
					 !lockdep_is_held(l2)));		\
	} while (0)

	#define lockdep_assert_held_either(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) &&		\
					 !lockdep_is_held(l2)));		\
	} while (0)

Still need sometime to think through this (e.g. on whether this it the
best implementation).

Regards,
Boqun

> 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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-23  7:16           ` Boqun Feng
  0 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-23  7:16 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra, VMware Graphics,
	Zack Rusin, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, dri-devel, intel-gfx, Shuah Khan, Greg KH,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 09:02:41PM +0200, Daniel Vetter wrote:
> 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.
> 

Make sense, so we'd better also provide lockdep_assert_held_both(), I
think, to use it at the update side, something as below:


	/*
	 * lockdep_assert_held_{both,either}().
	 * 
	 * Sometimes users can use a combination of two locks to
	 * implement a rwlock-like lock, for example, say we have
	 * locks L1 and L2, and we only allow updates when two locks
	 * both held like:
	 * 
	 * update()
	 * {
	 *	lockdep_assert_held_both(L1, L2);
	 *	x++; // update x
	 * }
	 *
	 * while for read-only accesses, either lock suffices (since
	 * holding either lock means others cannot hold both, so readers
	 * serialized with the updaters):
	 *
	 * read()
	 * {
	 * 	lockdep_assert_held_either(L1, L2);
	 *	r = x; // read x
	 * }
	 */

	#define lockdep_assert_held_both(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) ||		\
					 !lockdep_is_held(l2)));		\
	} while (0)

	#define lockdep_assert_held_either(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) &&		\
					 !lockdep_is_held(l2)));		\
	} while (0)

Still need sometime to think through this (e.g. on whether this it the
best implementation).

Regards,
Boqun

> 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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-23  7:16           ` Boqun Feng
  0 siblings, 0 replies; 72+ messages in thread
From: Boqun Feng @ 2021-07-23  7:16 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, LKML, Peter Zijlstra, VMware Graphics,
	Zack Rusin, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, dri-devel, intel-gfx, Shuah Khan, Greg KH,
	linux-kernel-mentees

On Thu, Jul 22, 2021 at 09:02:41PM +0200, Daniel Vetter wrote:
> 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.
> 

Make sense, so we'd better also provide lockdep_assert_held_both(), I
think, to use it at the update side, something as below:


	/*
	 * lockdep_assert_held_{both,either}().
	 * 
	 * Sometimes users can use a combination of two locks to
	 * implement a rwlock-like lock, for example, say we have
	 * locks L1 and L2, and we only allow updates when two locks
	 * both held like:
	 * 
	 * update()
	 * {
	 *	lockdep_assert_held_both(L1, L2);
	 *	x++; // update x
	 * }
	 *
	 * while for read-only accesses, either lock suffices (since
	 * holding either lock means others cannot hold both, so readers
	 * serialized with the updaters):
	 *
	 * read()
	 * {
	 * 	lockdep_assert_held_either(L1, L2);
	 *	r = x; // read x
	 * }
	 */

	#define lockdep_assert_held_both(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) ||		\
					 !lockdep_is_held(l2)));		\
	} while (0)

	#define lockdep_assert_held_either(l1, l2)	do {			\
			WARN_ON_ONCE(debug_locks &&				\
					(!lockdep_is_held(l1) &&		\
					 !lockdep_is_held(l2)));		\
	} while (0)

Still need sometime to think through this (e.g. on whether this it the
best implementation).

Regards,
Boqun

> 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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-22 10:38     ` Daniel Vetter
  (?)
@ 2021-07-27 14:37       ` Peter Zijlstra
  -1 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-27 14:37 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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.
> 
> Adding lockdep folks, maybe they have ideas.

#ifdef CONFIG_LOCKDEP
	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
				      lockdep_is_held(&drm_file.master_lookup_lock)));
#endif

doesn't exactly roll off the tongue, but should do as you want I
suppose.

Would something like:

#define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))

Such that we can write:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

make it better ?

---
Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers

Extract lockdep_assert{,_once}() helpers to more easily write composite
assertions like, for example:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 5cf387813754..0da67341c1fb 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
 
 #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
 
-#define lockdep_assert_held(l)	do {					\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
-	} while (0)
+#define lockdep_assert(cond)		\
+	do { WARN_ON(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_not_held(l)	do {				\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_HELD);		\
-	} while (0)
+#define lockdep_assert_once(cond)	\
+	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_held_write(l)	do {			\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
-	} while (0)
+#define lockdep_assert_held(l)		\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
 
-#define lockdep_assert_held_read(l)	do {				\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
-	} while (0)
+#define lockdep_assert_not_held(l)	\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
 
-#define lockdep_assert_held_once(l)	do {				\
-		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
-	} while (0)
+#define lockdep_assert_held_write(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 0))
 
-#define lockdep_assert_none_held_once()	do {				\
-		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
-	} while (0)
+#define lockdep_assert_held_read(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 1))
+
+#define lockdep_assert_held_once(l)		\
+	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
+
+#define lockdep_assert_none_held_once()		\
+	lockdep_assert_once(!current->lockdep_depth)
 
 #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
 
@@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
 extern int lockdep_is_held(const void *);
 #define lockdep_is_held_type(l, r)		(1)
 
+#define lockdep_assert(c)			do { } while (0)
+#define lockdep_assert_once(c)			do { } while (0)
+
 #define lockdep_assert_held(l)			do { (void)(l); } while (0)
 #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
 #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-27 14:37       ` Peter Zijlstra
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-27 14:37 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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.
> 
> Adding lockdep folks, maybe they have ideas.

#ifdef CONFIG_LOCKDEP
	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
				      lockdep_is_held(&drm_file.master_lookup_lock)));
#endif

doesn't exactly roll off the tongue, but should do as you want I
suppose.

Would something like:

#define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))

Such that we can write:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

make it better ?

---
Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers

Extract lockdep_assert{,_once}() helpers to more easily write composite
assertions like, for example:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 5cf387813754..0da67341c1fb 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
 
 #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
 
-#define lockdep_assert_held(l)	do {					\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
-	} while (0)
+#define lockdep_assert(cond)		\
+	do { WARN_ON(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_not_held(l)	do {				\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_HELD);		\
-	} while (0)
+#define lockdep_assert_once(cond)	\
+	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_held_write(l)	do {			\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
-	} while (0)
+#define lockdep_assert_held(l)		\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
 
-#define lockdep_assert_held_read(l)	do {				\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
-	} while (0)
+#define lockdep_assert_not_held(l)	\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
 
-#define lockdep_assert_held_once(l)	do {				\
-		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
-	} while (0)
+#define lockdep_assert_held_write(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 0))
 
-#define lockdep_assert_none_held_once()	do {				\
-		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
-	} while (0)
+#define lockdep_assert_held_read(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 1))
+
+#define lockdep_assert_held_once(l)		\
+	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
+
+#define lockdep_assert_none_held_once()		\
+	lockdep_assert_once(!current->lockdep_depth)
 
 #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
 
@@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
 extern int lockdep_is_held(const void *);
 #define lockdep_is_held_type(l, r)		(1)
 
+#define lockdep_assert(c)			do { } while (0)
+#define lockdep_assert_once(c)			do { } while (0)
+
 #define lockdep_assert_held(l)			do { (void)(l); } while (0)
 #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
 #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-27 14:37       ` Peter Zijlstra
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-27 14:37 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

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.
> 
> Adding lockdep folks, maybe they have ideas.

#ifdef CONFIG_LOCKDEP
	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
				      lockdep_is_held(&drm_file.master_lookup_lock)));
#endif

doesn't exactly roll off the tongue, but should do as you want I
suppose.

Would something like:

#define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))

Such that we can write:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

make it better ?

---
Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers

Extract lockdep_assert{,_once}() helpers to more easily write composite
assertions like, for example:

	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
		       lockdep_is_held(&drm_file.master_lookup_lock));

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 5cf387813754..0da67341c1fb 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
 
 #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
 
-#define lockdep_assert_held(l)	do {					\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
-	} while (0)
+#define lockdep_assert(cond)		\
+	do { WARN_ON(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_not_held(l)	do {				\
-		WARN_ON(debug_locks &&					\
-			lockdep_is_held(l) == LOCK_STATE_HELD);		\
-	} while (0)
+#define lockdep_assert_once(cond)	\
+	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
 
-#define lockdep_assert_held_write(l)	do {			\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
-	} while (0)
+#define lockdep_assert_held(l)		\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
 
-#define lockdep_assert_held_read(l)	do {				\
-		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
-	} while (0)
+#define lockdep_assert_not_held(l)	\
+	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
 
-#define lockdep_assert_held_once(l)	do {				\
-		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
-	} while (0)
+#define lockdep_assert_held_write(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 0))
 
-#define lockdep_assert_none_held_once()	do {				\
-		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
-	} while (0)
+#define lockdep_assert_held_read(l)	\
+	lockdep_assert(lockdep_is_held_type(l, 1))
+
+#define lockdep_assert_held_once(l)		\
+	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
+
+#define lockdep_assert_none_held_once()		\
+	lockdep_assert_once(!current->lockdep_depth)
 
 #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
 
@@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
 extern int lockdep_is_held(const void *);
 #define lockdep_is_held_type(l, r)		(1)
 
+#define lockdep_assert(c)			do { } while (0)
+#define lockdep_assert_once(c)			do { } while (0)
+
 #define lockdep_assert_held(l)			do { (void)(l); } while (0)
 #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
 #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm, drm/vmwgfx: fixes and updates related to drm_master (rev2)
  2021-07-22  9:29 ` Desmond Cheong Zhi Xi
                   ` (7 preceding siblings ...)
  (?)
@ 2021-07-27 17:42 ` Patchwork
  -1 siblings, 0 replies; 72+ messages in thread
From: Patchwork @ 2021-07-27 17:42 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: intel-gfx

== Series Details ==

Series: drm, drm/vmwgfx: fixes and updates related to drm_master (rev2)
URL   : https://patchwork.freedesktop.org/series/92894/
State : failure

== Summary ==

CC      arch/x86/kernel/asm-offsets.s
In file included from ./arch/x86/include/asm/bug.h:84,
                 from ./include/linux/bug.h:5,
                 from ./include/linux/crypto.h:18,
                 from arch/x86/kernel/asm-offsets.c:9:
./include/linux/ww_mutex.h: In function ‘ww_acquire_done’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/asm-generic/bug.h:121:25: note: in definition of macro ‘WARN_ON’
  int __ret_warn_on = !!(condition);    \
                         ^~~~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/ww_mutex.h:147:2: note: in expansion of macro ‘lockdep_assert_held’
  lockdep_assert_held(ctx);
  ^~~~~~~~~~~~~~~~~~~
./include/linux/lockdep.h:316:39: note: each undeclared identifier is reported only once for each function it appears in
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/asm-generic/bug.h:121:25: note: in definition of macro ‘WARN_ON’
  int __ret_warn_on = !!(condition);    \
                         ^~~~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/ww_mutex.h:147:2: note: in expansion of macro ‘lockdep_assert_held’
  lockdep_assert_held(ctx);
  ^~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/mmzone.h:16,
                 from ./include/linux/gfp.h:6,
                 from ./include/linux/slab.h:15,
                 from ./include/linux/crypto.h:20,
                 from arch/x86/kernel/asm-offsets.c:9:
./include/linux/seqlock.h: In function ‘__seqprop_raw_spinlock_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:152:26: note: in definition of macro ‘__SEQ_LOCK’
 #define __SEQ_LOCK(expr) expr
                          ^~~~
./include/linux/lockdep.h:310:7: note: in expansion of macro ‘WARN_ON’
  do { WARN_ON(debug_locks && !(cond)); } while (0)
       ^~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/seqlock.h:247:13: note: in expansion of macro ‘lockdep_assert_held’
  __SEQ_LOCK(lockdep_assert_held(lockmember));   \
             ^~~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:276:1: note: in expansion of macro ‘SEQCOUNT_LOCKNAME’
 SEQCOUNT_LOCKNAME(raw_spinlock, raw_spinlock_t,  false,    s->lock,        raw_spin, raw_spin_lock(s->lock))
 ^~~~~~~~~~~~~~~~~
./include/linux/seqlock.h: In function ‘__seqprop_spinlock_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:152:26: note: in definition of macro ‘__SEQ_LOCK’
 #define __SEQ_LOCK(expr) expr
                          ^~~~
./include/linux/lockdep.h:310:7: note: in expansion of macro ‘WARN_ON’
  do { WARN_ON(debug_locks && !(cond)); } while (0)
       ^~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/seqlock.h:247:13: note: in expansion of macro ‘lockdep_assert_held’
  __SEQ_LOCK(lockdep_assert_held(lockmember));   \
             ^~~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:277:1: note: in expansion of macro ‘SEQCOUNT_LOCKNAME’
 SEQCOUNT_LOCKNAME(spinlock,     spinlock_t,      __SEQ_RT, s->lock,        spin,     spin_lock(s->lock))
 ^~~~~~~~~~~~~~~~~
./include/linux/seqlock.h: In function ‘__seqprop_rwlock_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:152:26: note: in definition of macro ‘__SEQ_LOCK’
 #define __SEQ_LOCK(expr) expr
                          ^~~~
./include/linux/lockdep.h:310:7: note: in expansion of macro ‘WARN_ON’
  do { WARN_ON(debug_locks && !(cond)); } while (0)
       ^~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/seqlock.h:247:13: note: in expansion of macro ‘lockdep_assert_held’
  __SEQ_LOCK(lockdep_assert_held(lockmember));   \
             ^~~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:278:1: note: in expansion of macro ‘SEQCOUNT_LOCKNAME’
 SEQCOUNT_LOCKNAME(rwlock,       rwlock_t,        __SEQ_RT, s->lock,        read,     read_lock(s->lock))
 ^~~~~~~~~~~~~~~~~
./include/linux/seqlock.h: In function ‘__seqprop_mutex_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:152:26: note: in definition of macro ‘__SEQ_LOCK’
 #define __SEQ_LOCK(expr) expr
                          ^~~~
./include/linux/lockdep.h:310:7: note: in expansion of macro ‘WARN_ON’
  do { WARN_ON(debug_locks && !(cond)); } while (0)
       ^~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/seqlock.h:247:13: note: in expansion of macro ‘lockdep_assert_held’
  __SEQ_LOCK(lockdep_assert_held(lockmember));   \
             ^~~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:279:1: note: in expansion of macro ‘SEQCOUNT_LOCKNAME’
 SEQCOUNT_LOCKNAME(mutex,        struct mutex,    true,     s->lock,        mutex,    mutex_lock(s->lock))
 ^~~~~~~~~~~~~~~~~
./include/linux/seqlock.h: In function ‘__seqprop_ww_mutex_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:152:26: note: in definition of macro ‘__SEQ_LOCK’
 #define __SEQ_LOCK(expr) expr
                          ^~~~
./include/linux/lockdep.h:310:7: note: in expansion of macro ‘WARN_ON’
  do { WARN_ON(debug_locks && !(cond)); } while (0)
       ^~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/seqlock.h:247:13: note: in expansion of macro ‘lockdep_assert_held’
  __SEQ_LOCK(lockdep_assert_held(lockmember));   \
             ^~~~~~~~~~~~~~~~~~~
./include/linux/seqlock.h:280:1: note: in expansion of macro ‘SEQCOUNT_LOCKNAME’
 SEQCOUNT_LOCKNAME(ww_mutex,     struct ww_mutex, true,     &s->lock->base, ww_mutex, ww_mutex_lock(s->lock, NULL))
 ^~~~~~~~~~~~~~~~~
In file included from ./arch/x86/include/asm/bug.h:84,
                 from ./include/linux/bug.h:5,
                 from ./include/linux/crypto.h:18,
                 from arch/x86/kernel/asm-offsets.c:9:
./include/linux/fs.h: In function ‘i_mmap_assert_locked’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/asm-generic/bug.h:121:25: note: in definition of macro ‘WARN_ON’
  int __ret_warn_on = !!(condition);    \
                         ^~~~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/fs.h:519:2: note: in expansion of macro ‘lockdep_assert_held’
  lockdep_assert_held(&mapping->i_mmap_rwsem);
  ^~~~~~~~~~~~~~~~~~~
./include/linux/mmap_lock.h: In function ‘mmap_assert_locked’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/asm-generic/bug.h:121:25: note: in definition of macro ‘WARN_ON’
  int __ret_warn_on = !!(condition);    \
                         ^~~~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/mmap_lock.h:164:2: note: in expansion of macro ‘lockdep_assert_held’
  lockdep_assert_held(&mm->mmap_lock);
  ^~~~~~~~~~~~~~~~~~~
In file included from ./arch/x86/include/asm/bug.h:84,
                 from ./include/linux/bug.h:5,
                 from ./include/linux/crypto.h:18,
                 from arch/x86/kernel/asm-offsets.c:9:
./include/linux/device.h: In function ‘device_lock_assert’:
./include/linux/lockdep.h:316:39: error: ‘LOCK_STAT_NOT_HELD’ undeclared (first use in this function); did you mean ‘LOCK_STATE_NOT_HELD’?
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
                                       ^~~~~~~~~~~~~~~~~~
./include/asm-generic/bug.h:121:25: note: in definition of macro ‘WARN_ON’
  int __ret_warn_on = !!(condition);    \
                         ^~~~~~~~~
./include/linux/lockdep.h:316:2: note: in expansion of macro ‘lockdep_assert’
  lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
  ^~~~~~~~~~~~~~
./include/linux/device.h:774:2: note: in expansion of macro ‘lockdep_assert_held’
  lockdep_assert_held(&dev->mutex);
  ^~~~~~~~~~~~~~~~~~~
scripts/Makefile.build:117: recipe for target 'arch/x86/kernel/asm-offsets.s' failed
make[1]: *** [arch/x86/kernel/asm-offsets.s] Error 1
Makefile:1212: recipe for target 'prepare0' failed
make: *** [prepare0] Error 2


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-27 14:37       ` Peter Zijlstra
  (?)
  (?)
@ 2021-07-29  7:00         ` Daniel Vetter
  -1 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-29  7:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Desmond Cheong Zhi Xi, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann, dri-devel, intel-gfx, skhan, gregkh,
	linux-kernel-mentees

On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
> > 
> > Adding lockdep folks, maybe they have ideas.
> 
> #ifdef CONFIG_LOCKDEP
> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
> #endif
> 
> doesn't exactly roll off the tongue, but should do as you want I
> suppose.
> 
> Would something like:
> 
> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
> 
> Such that we can write:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> make it better ?

Yeah I think that's pretty tidy and flexible.

Desmond, can you pls give this a shot with Peter's patch below?
-Daniel
> 
> ---
> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
> 
> Extract lockdep_assert{,_once}() helpers to more easily write composite
> assertions like, for example:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 5cf387813754..0da67341c1fb 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>  
>  #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>  
> -#define lockdep_assert_held(l)	do {					\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
> -	} while (0)
> +#define lockdep_assert(cond)		\
> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_not_held(l)	do {				\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
> -	} while (0)
> +#define lockdep_assert_once(cond)	\
> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_held_write(l)	do {			\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
> -	} while (0)
> +#define lockdep_assert_held(l)		\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>  
> -#define lockdep_assert_held_read(l)	do {				\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
> -	} while (0)
> +#define lockdep_assert_not_held(l)	\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>  
> -#define lockdep_assert_held_once(l)	do {				\
> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
> -	} while (0)
> +#define lockdep_assert_held_write(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 0))
>  
> -#define lockdep_assert_none_held_once()	do {				\
> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
> -	} while (0)
> +#define lockdep_assert_held_read(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 1))
> +
> +#define lockdep_assert_held_once(l)		\
> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
> +
> +#define lockdep_assert_none_held_once()		\
> +	lockdep_assert_once(!current->lockdep_depth)
>  
>  #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>  
> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>  extern int lockdep_is_held(const void *);
>  #define lockdep_is_held_type(l, r)		(1)
>  
> +#define lockdep_assert(c)			do { } while (0)
> +#define lockdep_assert_once(c)			do { } while (0)
> +
>  #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>  #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>  #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29  7:00         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-29  7:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: airlied, Boqun Feng, maarten.lankhorst, LKML, mripard,
	linux-graphics-maintainer, dri-devel, tzimmermann,
	Desmond Cheong Zhi Xi, linux-kernel-mentees, intel-gfx, zackr

On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
> > 
> > Adding lockdep folks, maybe they have ideas.
> 
> #ifdef CONFIG_LOCKDEP
> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
> #endif
> 
> doesn't exactly roll off the tongue, but should do as you want I
> suppose.
> 
> Would something like:
> 
> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
> 
> Such that we can write:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> make it better ?

Yeah I think that's pretty tidy and flexible.

Desmond, can you pls give this a shot with Peter's patch below?
-Daniel
> 
> ---
> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
> 
> Extract lockdep_assert{,_once}() helpers to more easily write composite
> assertions like, for example:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 5cf387813754..0da67341c1fb 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>  
>  #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>  
> -#define lockdep_assert_held(l)	do {					\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
> -	} while (0)
> +#define lockdep_assert(cond)		\
> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_not_held(l)	do {				\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
> -	} while (0)
> +#define lockdep_assert_once(cond)	\
> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_held_write(l)	do {			\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
> -	} while (0)
> +#define lockdep_assert_held(l)		\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>  
> -#define lockdep_assert_held_read(l)	do {				\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
> -	} while (0)
> +#define lockdep_assert_not_held(l)	\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>  
> -#define lockdep_assert_held_once(l)	do {				\
> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
> -	} while (0)
> +#define lockdep_assert_held_write(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 0))
>  
> -#define lockdep_assert_none_held_once()	do {				\
> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
> -	} while (0)
> +#define lockdep_assert_held_read(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 1))
> +
> +#define lockdep_assert_held_once(l)		\
> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
> +
> +#define lockdep_assert_none_held_once()		\
> +	lockdep_assert_once(!current->lockdep_depth)
>  
>  #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>  
> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>  extern int lockdep_is_held(const void *);
>  #define lockdep_is_held_type(l, r)		(1)
>  
> +#define lockdep_assert(c)			do { } while (0)
> +#define lockdep_assert_once(c)			do { } while (0)
> +
>  #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>  #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>  #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29  7:00         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-29  7:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: airlied, gregkh, Boqun Feng, LKML, linux-graphics-maintainer,
	dri-devel, tzimmermann, skhan, Desmond Cheong Zhi Xi,
	linux-kernel-mentees, intel-gfx

On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
> > 
> > Adding lockdep folks, maybe they have ideas.
> 
> #ifdef CONFIG_LOCKDEP
> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
> #endif
> 
> doesn't exactly roll off the tongue, but should do as you want I
> suppose.
> 
> Would something like:
> 
> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
> 
> Such that we can write:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> make it better ?

Yeah I think that's pretty tidy and flexible.

Desmond, can you pls give this a shot with Peter's patch below?
-Daniel
> 
> ---
> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
> 
> Extract lockdep_assert{,_once}() helpers to more easily write composite
> assertions like, for example:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 5cf387813754..0da67341c1fb 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>  
>  #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>  
> -#define lockdep_assert_held(l)	do {					\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
> -	} while (0)
> +#define lockdep_assert(cond)		\
> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_not_held(l)	do {				\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
> -	} while (0)
> +#define lockdep_assert_once(cond)	\
> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_held_write(l)	do {			\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
> -	} while (0)
> +#define lockdep_assert_held(l)		\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>  
> -#define lockdep_assert_held_read(l)	do {				\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
> -	} while (0)
> +#define lockdep_assert_not_held(l)	\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>  
> -#define lockdep_assert_held_once(l)	do {				\
> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
> -	} while (0)
> +#define lockdep_assert_held_write(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 0))
>  
> -#define lockdep_assert_none_held_once()	do {				\
> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
> -	} while (0)
> +#define lockdep_assert_held_read(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 1))
> +
> +#define lockdep_assert_held_once(l)		\
> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
> +
> +#define lockdep_assert_none_held_once()		\
> +	lockdep_assert_once(!current->lockdep_depth)
>  
>  #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>  
> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>  extern int lockdep_is_held(const void *);
>  #define lockdep_is_held_type(l, r)		(1)
>  
> +#define lockdep_assert(c)			do { } while (0)
> +#define lockdep_assert_once(c)			do { } while (0)
> +
>  #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>  #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>  #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
> 

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29  7:00         ` Daniel Vetter
  0 siblings, 0 replies; 72+ messages in thread
From: Daniel Vetter @ 2021-07-29  7:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: airlied, gregkh, Boqun Feng, LKML, mripard,
	linux-graphics-maintainer, dri-devel, tzimmermann, skhan,
	Desmond Cheong Zhi Xi, linux-kernel-mentees, intel-gfx, zackr

On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
> > 
> > Adding lockdep folks, maybe they have ideas.
> 
> #ifdef CONFIG_LOCKDEP
> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
> #endif
> 
> doesn't exactly roll off the tongue, but should do as you want I
> suppose.
> 
> Would something like:
> 
> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
> 
> Such that we can write:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> make it better ?

Yeah I think that's pretty tidy and flexible.

Desmond, can you pls give this a shot with Peter's patch below?
-Daniel
> 
> ---
> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
> 
> Extract lockdep_assert{,_once}() helpers to more easily write composite
> assertions like, for example:
> 
> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
> 		       lockdep_is_held(&drm_file.master_lookup_lock));
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 5cf387813754..0da67341c1fb 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>  
>  #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>  
> -#define lockdep_assert_held(l)	do {					\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
> -	} while (0)
> +#define lockdep_assert(cond)		\
> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_not_held(l)	do {				\
> -		WARN_ON(debug_locks &&					\
> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
> -	} while (0)
> +#define lockdep_assert_once(cond)	\
> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>  
> -#define lockdep_assert_held_write(l)	do {			\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
> -	} while (0)
> +#define lockdep_assert_held(l)		\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>  
> -#define lockdep_assert_held_read(l)	do {				\
> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
> -	} while (0)
> +#define lockdep_assert_not_held(l)	\
> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>  
> -#define lockdep_assert_held_once(l)	do {				\
> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
> -	} while (0)
> +#define lockdep_assert_held_write(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 0))
>  
> -#define lockdep_assert_none_held_once()	do {				\
> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
> -	} while (0)
> +#define lockdep_assert_held_read(l)	\
> +	lockdep_assert(lockdep_is_held_type(l, 1))
> +
> +#define lockdep_assert_held_once(l)		\
> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
> +
> +#define lockdep_assert_none_held_once()		\
> +	lockdep_assert_once(!current->lockdep_depth)
>  
>  #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>  
> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>  extern int lockdep_is_held(const void *);
>  #define lockdep_is_held_type(l, r)		(1)
>  
> +#define lockdep_assert(c)			do { } while (0)
> +#define lockdep_assert_once(c)			do { } while (0)
> +
>  #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>  #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>  #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
> 

-- 
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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-29  7:00         ` Daniel Vetter
  (?)
  (?)
@ 2021-07-29 14:32           ` Desmond Cheong Zhi Xi
  -1 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-29 14:32 UTC (permalink / raw)
  To: Daniel Vetter, Peter Zijlstra, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann
  Cc: dri-devel, intel-gfx, skhan, gregkh, linux-kernel-mentees

On 29/7/21 3:00 pm, Daniel Vetter wrote:
> On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
>>>
>>> Adding lockdep folks, maybe they have ideas.
>>
>> #ifdef CONFIG_LOCKDEP
>> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
>> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
>> #endif
>>
>> doesn't exactly roll off the tongue, but should do as you want I
>> suppose.
>>
>> Would something like:
>>
>> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
>>
>> Such that we can write:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> make it better ?
> 
> Yeah I think that's pretty tidy and flexible.
> 
> Desmond, can you pls give this a shot with Peter's patch below?
> -Daniel

Sounds good, will do. Thanks for the patch, Peter.

Just going to make a small edit:
s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Best wishes,
Desmond

>>
>> ---
>> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
>>
>> Extract lockdep_assert{,_once}() helpers to more easily write composite
>> assertions like, for example:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>> ---
>> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
>> index 5cf387813754..0da67341c1fb 100644
>> --- a/include/linux/lockdep.h
>> +++ b/include/linux/lockdep.h
>> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>>   
>>   #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>>   
>> -#define lockdep_assert_held(l)	do {					\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
>> -	} while (0)
>> +#define lockdep_assert(cond)		\
>> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_not_held(l)	do {				\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
>> -	} while (0)
>> +#define lockdep_assert_once(cond)	\
>> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_held_write(l)	do {			\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
>> -	} while (0)
>> +#define lockdep_assert_held(l)		\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>>   
>> -#define lockdep_assert_held_read(l)	do {				\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
>> -	} while (0)
>> +#define lockdep_assert_not_held(l)	\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>>   
>> -#define lockdep_assert_held_once(l)	do {				\
>> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
>> -	} while (0)
>> +#define lockdep_assert_held_write(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 0))
>>   
>> -#define lockdep_assert_none_held_once()	do {				\
>> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
>> -	} while (0)
>> +#define lockdep_assert_held_read(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 1))
>> +
>> +#define lockdep_assert_held_once(l)		\
>> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>> +
>> +#define lockdep_assert_none_held_once()		\
>> +	lockdep_assert_once(!current->lockdep_depth)
>>   
>>   #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>>   
>> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>>   extern int lockdep_is_held(const void *);
>>   #define lockdep_is_held_type(l, r)		(1)
>>   
>> +#define lockdep_assert(c)			do { } while (0)
>> +#define lockdep_assert_once(c)			do { } while (0)
>> +
>>   #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>>   #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>>   #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
>>
> 


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:32           ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-29 14:32 UTC (permalink / raw)
  To: Daniel Vetter, Peter Zijlstra, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann
  Cc: intel-gfx, linux-kernel-mentees, dri-devel

On 29/7/21 3:00 pm, Daniel Vetter wrote:
> On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
>>>
>>> Adding lockdep folks, maybe they have ideas.
>>
>> #ifdef CONFIG_LOCKDEP
>> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
>> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
>> #endif
>>
>> doesn't exactly roll off the tongue, but should do as you want I
>> suppose.
>>
>> Would something like:
>>
>> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
>>
>> Such that we can write:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> make it better ?
> 
> Yeah I think that's pretty tidy and flexible.
> 
> Desmond, can you pls give this a shot with Peter's patch below?
> -Daniel

Sounds good, will do. Thanks for the patch, Peter.

Just going to make a small edit:
s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Best wishes,
Desmond

>>
>> ---
>> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
>>
>> Extract lockdep_assert{,_once}() helpers to more easily write composite
>> assertions like, for example:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>> ---
>> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
>> index 5cf387813754..0da67341c1fb 100644
>> --- a/include/linux/lockdep.h
>> +++ b/include/linux/lockdep.h
>> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>>   
>>   #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>>   
>> -#define lockdep_assert_held(l)	do {					\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
>> -	} while (0)
>> +#define lockdep_assert(cond)		\
>> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_not_held(l)	do {				\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
>> -	} while (0)
>> +#define lockdep_assert_once(cond)	\
>> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_held_write(l)	do {			\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
>> -	} while (0)
>> +#define lockdep_assert_held(l)		\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>>   
>> -#define lockdep_assert_held_read(l)	do {				\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
>> -	} while (0)
>> +#define lockdep_assert_not_held(l)	\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>>   
>> -#define lockdep_assert_held_once(l)	do {				\
>> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
>> -	} while (0)
>> +#define lockdep_assert_held_write(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 0))
>>   
>> -#define lockdep_assert_none_held_once()	do {				\
>> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
>> -	} while (0)
>> +#define lockdep_assert_held_read(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 1))
>> +
>> +#define lockdep_assert_held_once(l)		\
>> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>> +
>> +#define lockdep_assert_none_held_once()		\
>> +	lockdep_assert_once(!current->lockdep_depth)
>>   
>>   #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>>   
>> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>>   extern int lockdep_is_held(const void *);
>>   #define lockdep_is_held_type(l, r)		(1)
>>   
>> +#define lockdep_assert(c)			do { } while (0)
>> +#define lockdep_assert_once(c)			do { } while (0)
>> +
>>   #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>>   #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>>   #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
>>
> 

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:32           ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-29 14:32 UTC (permalink / raw)
  To: Daniel Vetter, Peter Zijlstra, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel-mentees, dri-devel, skhan

On 29/7/21 3:00 pm, Daniel Vetter wrote:
> On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
>>>
>>> Adding lockdep folks, maybe they have ideas.
>>
>> #ifdef CONFIG_LOCKDEP
>> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
>> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
>> #endif
>>
>> doesn't exactly roll off the tongue, but should do as you want I
>> suppose.
>>
>> Would something like:
>>
>> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
>>
>> Such that we can write:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> make it better ?
> 
> Yeah I think that's pretty tidy and flexible.
> 
> Desmond, can you pls give this a shot with Peter's patch below?
> -Daniel

Sounds good, will do. Thanks for the patch, Peter.

Just going to make a small edit:
s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Best wishes,
Desmond

>>
>> ---
>> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
>>
>> Extract lockdep_assert{,_once}() helpers to more easily write composite
>> assertions like, for example:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>> ---
>> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
>> index 5cf387813754..0da67341c1fb 100644
>> --- a/include/linux/lockdep.h
>> +++ b/include/linux/lockdep.h
>> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>>   
>>   #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>>   
>> -#define lockdep_assert_held(l)	do {					\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
>> -	} while (0)
>> +#define lockdep_assert(cond)		\
>> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_not_held(l)	do {				\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
>> -	} while (0)
>> +#define lockdep_assert_once(cond)	\
>> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_held_write(l)	do {			\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
>> -	} while (0)
>> +#define lockdep_assert_held(l)		\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>>   
>> -#define lockdep_assert_held_read(l)	do {				\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
>> -	} while (0)
>> +#define lockdep_assert_not_held(l)	\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>>   
>> -#define lockdep_assert_held_once(l)	do {				\
>> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
>> -	} while (0)
>> +#define lockdep_assert_held_write(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 0))
>>   
>> -#define lockdep_assert_none_held_once()	do {				\
>> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
>> -	} while (0)
>> +#define lockdep_assert_held_read(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 1))
>> +
>> +#define lockdep_assert_held_once(l)		\
>> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>> +
>> +#define lockdep_assert_none_held_once()		\
>> +	lockdep_assert_once(!current->lockdep_depth)
>>   
>>   #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>>   
>> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>>   extern int lockdep_is_held(const void *);
>>   #define lockdep_is_held_type(l, r)		(1)
>>   
>> +#define lockdep_assert(c)			do { } while (0)
>> +#define lockdep_assert_once(c)			do { } while (0)
>> +
>>   #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>>   #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>>   #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
>>
> 


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:32           ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 72+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-29 14:32 UTC (permalink / raw)
  To: Daniel Vetter, Peter Zijlstra, Boqun Feng, LKML,
	linux-graphics-maintainer, zackr, airlied, maarten.lankhorst,
	mripard, tzimmermann
  Cc: gregkh, intel-gfx, linux-kernel-mentees, dri-devel, skhan

On 29/7/21 3:00 pm, Daniel Vetter wrote:
> On Tue, Jul 27, 2021 at 04:37:22PM +0200, Peter Zijlstra 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.
>>>
>>> Adding lockdep folks, maybe they have ideas.
>>
>> #ifdef CONFIG_LOCKDEP
>> 	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&drm_device.master_mutex) ||
>> 				      lockdep_is_held(&drm_file.master_lookup_lock)));
>> #endif
>>
>> doesn't exactly roll off the tongue, but should do as you want I
>> suppose.
>>
>> Would something like:
>>
>> #define lockdep_assert(cond)	WARN_ON_ONCE(debug_locks && !(cond))
>>
>> Such that we can write:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> make it better ?
> 
> Yeah I think that's pretty tidy and flexible.
> 
> Desmond, can you pls give this a shot with Peter's patch below?
> -Daniel

Sounds good, will do. Thanks for the patch, Peter.

Just going to make a small edit:
s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Best wishes,
Desmond

>>
>> ---
>> Subject: locking/lockdep: Provide lockdep_assert{,_once}() helpers
>>
>> Extract lockdep_assert{,_once}() helpers to more easily write composite
>> assertions like, for example:
>>
>> 	lockdep_assert(lockdep_is_held(&drm_device.master_mutex) ||
>> 		       lockdep_is_held(&drm_file.master_lookup_lock));
>>
>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>> ---
>> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
>> index 5cf387813754..0da67341c1fb 100644
>> --- a/include/linux/lockdep.h
>> +++ b/include/linux/lockdep.h
>> @@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>>   
>>   #define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
>>   
>> -#define lockdep_assert_held(l)	do {					\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_NOT_HELD);	\
>> -	} while (0)
>> +#define lockdep_assert(cond)		\
>> +	do { WARN_ON(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_not_held(l)	do {				\
>> -		WARN_ON(debug_locks &&					\
>> -			lockdep_is_held(l) == LOCK_STATE_HELD);		\
>> -	} while (0)
>> +#define lockdep_assert_once(cond)	\
>> +	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>>   
>> -#define lockdep_assert_held_write(l)	do {			\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 0));	\
>> -	} while (0)
>> +#define lockdep_assert_held(l)		\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>>   
>> -#define lockdep_assert_held_read(l)	do {				\
>> -		WARN_ON(debug_locks && !lockdep_is_held_type(l, 1));	\
>> -	} while (0)
>> +#define lockdep_assert_not_held(l)	\
>> +	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>>   
>> -#define lockdep_assert_held_once(l)	do {				\
>> -		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
>> -	} while (0)
>> +#define lockdep_assert_held_write(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 0))
>>   
>> -#define lockdep_assert_none_held_once()	do {				\
>> -		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
>> -	} while (0)
>> +#define lockdep_assert_held_read(l)	\
>> +	lockdep_assert(lockdep_is_held_type(l, 1))
>> +
>> +#define lockdep_assert_held_once(l)		\
>> +	lockdep_assert_once(lockdep_is_held(l) != LOCK_STAT_NOT_HELD)
>> +
>> +#define lockdep_assert_none_held_once()		\
>> +	lockdep_assert_once(!current->lockdep_depth)
>>   
>>   #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>>   
>> @@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
>>   extern int lockdep_is_held(const void *);
>>   #define lockdep_is_held_type(l, r)		(1)
>>   
>> +#define lockdep_assert(c)			do { } while (0)
>> +#define lockdep_assert_once(c)			do { } while (0)
>> +
>>   #define lockdep_assert_held(l)			do { (void)(l); } while (0)
>>   #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
>>   #define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
>>
> 

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
  2021-07-29 14:32           ` Desmond Cheong Zhi Xi
  (?)
  (?)
@ 2021-07-29 14:45             ` Peter Zijlstra
  -1 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-29 14:45 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: Daniel Vetter, Boqun Feng, LKML, linux-graphics-maintainer,
	zackr, airlied, maarten.lankhorst, mripard, tzimmermann,
	dri-devel, intel-gfx, skhan, gregkh, linux-kernel-mentees

On Thu, Jul 29, 2021 at 10:32:13PM +0800, Desmond Cheong Zhi Xi wrote:
> Sounds good, will do. Thanks for the patch, Peter.
> 
> Just going to make a small edit:
> s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Bah, I knew I should've compile tested it :-), Thanks!

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:45             ` Peter Zijlstra
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-29 14:45 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, Boqun Feng, maarten.lankhorst, LKML,
	mripard, linux-graphics-maintainer, dri-devel, Daniel Vetter,
	linux-kernel-mentees, intel-gfx, zackr

On Thu, Jul 29, 2021 at 10:32:13PM +0800, Desmond Cheong Zhi Xi wrote:
> Sounds good, will do. Thanks for the patch, Peter.
> 
> Just going to make a small edit:
> s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Bah, I knew I should've compile tested it :-), Thanks!
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:45             ` Peter Zijlstra
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-29 14:45 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, Boqun Feng, LKML,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees, intel-gfx

On Thu, Jul 29, 2021 at 10:32:13PM +0800, Desmond Cheong Zhi Xi wrote:
> Sounds good, will do. Thanks for the patch, Peter.
> 
> Just going to make a small edit:
> s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Bah, I knew I should've compile tested it :-), Thanks!

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [Intel-gfx] [PATCH 1/3] drm: use the lookup lock in drm_is_current_master
@ 2021-07-29 14:45             ` Peter Zijlstra
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Zijlstra @ 2021-07-29 14:45 UTC (permalink / raw)
  To: Desmond Cheong Zhi Xi
  Cc: tzimmermann, airlied, gregkh, Boqun Feng, LKML, mripard,
	linux-graphics-maintainer, dri-devel, skhan,
	linux-kernel-mentees, intel-gfx, zackr

On Thu, Jul 29, 2021 at 10:32:13PM +0800, Desmond Cheong Zhi Xi wrote:
> Sounds good, will do. Thanks for the patch, Peter.
> 
> Just going to make a small edit:
> s/LOCK_STAT_NOT_HELD/LOCK_STATE_NOT_HELD/

Bah, I knew I should've compile tested it :-), Thanks!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2021-07-29 14:58 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2021-07-22 19:02         ` [Intel-gfx] " Daniel Vetter
2021-07-22 19:02         ` Daniel Vetter
2021-07-22 19:02         ` 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         ` [Intel-gfx] " Daniel Vetter
2021-07-29  7:00         ` Daniel Vetter
2021-07-29  7:00         ` 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           ` Peter Zijlstra
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-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       ` [Intel-gfx] " Desmond Cheong Zhi Xi
2021-07-22 13:02       ` 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         ` [Intel-gfx] " Daniel Vetter
2021-07-22 14:17         ` Daniel Vetter
2021-07-22 14:17         ` 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     ` [Intel-gfx] " Zack Rusin
2021-07-22 19:17     ` Zack Rusin
2021-07-22 19:17     ` 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

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.