All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Subject: [PATCH v5 11/13] drm/i915/ttm: make evicted shmem pages visible to the shrinker
Date: Mon, 27 Sep 2021 12:41:12 +0100	[thread overview]
Message-ID: <20210927114114.152310-11-matthew.auld@intel.com> (raw)
In-Reply-To: <20210927114114.152310-1-matthew.auld@intel.com>

We currently just evict lmem objects to system memory when under memory
pressure, and in the next patch we want to use the shmem backend even
for this case. For this case we lack the usual object mm.pages, which
effectively hides the pages from the i915-gem shrinker, until we
actually "attach" the TT to the object, or in the case of lmem-only
objects it just gets migrated back to lmem when touched again.

For all cases we can just adjust the i915 shrinker LRU each time we also
adjust the TTM LRU. The two cases we care about are:

  1) When something is moved by TTM, including when initially populating
     an object. Importantly this covers the case where TTM moves something from
     lmem <-> smem, outside of the normal get_pages() interface, which
     should still ensure the shmem pages underneath are reclaimable.

  2) When calling into i915_gem_object_unlock(). The unlock should
     ensure the object is removed from the shinker LRU, if it was indeed
     swapped out, or just purged, when the shrinker drops the object lock.

We can optimise this(if needed) by tracking if the object is already
visible to the shrinker(protected by the object lock), so we don't touch
the shrinker LRU more than needed.

v2(Thomas)
  - Handle managing the shrinker LRU in adjust_lru, where it is always
    safe to touch the object.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 29 +++++++++++++++-----
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c      | 28 +++++++++++++++----
 3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 1c9a1d8d3434..640dfbf1f01e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -523,6 +523,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 
 void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj);
 void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
+void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
 void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj);
 
 static inline bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 0440696f786a..4b6b2bb6f180 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -487,13 +487,12 @@ void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj)
 	spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 }
 
-static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
-					      struct list_head *head)
+static void ___i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
+					       struct list_head *head)
 {
 	struct drm_i915_private *i915 = obj_to_i915(obj);
 	unsigned long flags;
 
-	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
 	if (!i915_gem_object_is_shrinkable(obj))
 		return;
 
@@ -512,6 +511,21 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
 	spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 }
 
+/**
+ * __i915_gem_object_make_shrinkable - Move the object to the tail of the
+ * shrinkable list. Objects on this list might be swapped out. Used with
+ * WILLNEED objects.
+ * @obj: The GEM object.
+ *
+ * DO NOT USE. This is intended to be called on very special objects that don't
+ * yet have mm.pages, but are guaranteed to have potentially reclaimable pages
+ * underneath.
+ */
+void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
+{
+	___i915_gem_object_make_shrinkable(obj,
+					   &obj_to_i915(obj)->mm.shrink_list);
+}
 
 /**
  * i915_gem_object_make_shrinkable - Move the object to the tail of the
@@ -523,8 +537,8 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
  */
 void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
 {
-	__i915_gem_object_make_shrinkable(obj,
-					  &obj_to_i915(obj)->mm.shrink_list);
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	__i915_gem_object_make_shrinkable(obj);
 }
 
 /**
@@ -538,6 +552,7 @@ void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
  */
 void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj)
 {
-	__i915_gem_object_make_shrinkable(obj,
-					  &obj_to_i915(obj)->mm.purge_list);
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	___i915_gem_object_make_shrinkable(obj,
+					   &obj_to_i915(obj)->mm.purge_list);
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index c7402995a8f9..194e5f1deda8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -749,6 +749,8 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
 			return ret;
 	}
 
+	i915_ttm_adjust_lru(obj);
+
 	dst_st = i915_ttm_resource_get_st(obj, dst_mem);
 	if (IS_ERR(dst_st))
 		return PTR_ERR(dst_st);
@@ -856,7 +858,6 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
 			return i915_ttm_err_to_gem(ret);
 	}
 
-	i915_ttm_adjust_lru(obj);
 	if (bo->ttm && !ttm_tt_is_populated(bo->ttm)) {
 		ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx);
 		if (ret)
@@ -876,10 +877,10 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
 			return PTR_ERR(st);
 
 		__i915_gem_object_set_pages(obj, st, i915_sg_dma_sizes(st->sgl));
-		if (!bo->ttm || !i915_tt->is_shmem)
-			i915_gem_object_make_unshrinkable(obj);
 	}
 
+	i915_ttm_adjust_lru(obj);
+
 	return ret;
 }
 
@@ -950,8 +951,6 @@ static void i915_ttm_put_pages(struct drm_i915_gem_object *obj,
 	 * If the object is not destroyed next, The TTM eviction logic
 	 * and shrinkers will move it out if needed.
 	 */
-
-	i915_ttm_adjust_lru(obj);
 }
 
 static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
@@ -967,6 +966,17 @@ static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
 	if (!kref_read(&bo->kref))
 		return;
 
+	/*
+	 * Even if we lack mm.pages for this object(which will be the case when
+	 * something is evicted to system memory by TTM), we still want to make
+	 * this object visible to the shrinker, since the underlying ttm_tt
+	 * still has the real shmem pages.
+	 */
+	if (bo->ttm && i915_tt->filp && ttm_tt_is_populated(bo->ttm))
+		__i915_gem_object_make_shrinkable(obj);
+	else
+		i915_gem_object_make_unshrinkable(obj);
+
 	/*
 	 * Put on the correct LRU list depending on the MADV status
 	 */
@@ -1006,6 +1016,14 @@ static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
 static void i915_ttm_delayed_free(struct drm_i915_gem_object *obj)
 {
 	if (obj->ttm.created) {
+		/*
+		 * We freely manage the shrinker LRU outide of the mm.pages life
+		 * cycle. As a result when destroying the object it's up to us
+		 * to ensure we remove it from the LRU, before we free the
+		 * object.
+		 */
+		i915_gem_object_make_unshrinkable(obj);
+
 		ttm_bo_put(i915_gem_to_ttm(obj));
 	} else {
 		__i915_gem_free_object(obj);
-- 
2.26.3


WARNING: multiple messages have this Message-ID (diff)
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Subject: [Intel-gfx] [PATCH v5 11/13] drm/i915/ttm: make evicted shmem pages visible to the shrinker
Date: Mon, 27 Sep 2021 12:41:12 +0100	[thread overview]
Message-ID: <20210927114114.152310-11-matthew.auld@intel.com> (raw)
In-Reply-To: <20210927114114.152310-1-matthew.auld@intel.com>

We currently just evict lmem objects to system memory when under memory
pressure, and in the next patch we want to use the shmem backend even
for this case. For this case we lack the usual object mm.pages, which
effectively hides the pages from the i915-gem shrinker, until we
actually "attach" the TT to the object, or in the case of lmem-only
objects it just gets migrated back to lmem when touched again.

For all cases we can just adjust the i915 shrinker LRU each time we also
adjust the TTM LRU. The two cases we care about are:

  1) When something is moved by TTM, including when initially populating
     an object. Importantly this covers the case where TTM moves something from
     lmem <-> smem, outside of the normal get_pages() interface, which
     should still ensure the shmem pages underneath are reclaimable.

  2) When calling into i915_gem_object_unlock(). The unlock should
     ensure the object is removed from the shinker LRU, if it was indeed
     swapped out, or just purged, when the shrinker drops the object lock.

We can optimise this(if needed) by tracking if the object is already
visible to the shrinker(protected by the object lock), so we don't touch
the shrinker LRU more than needed.

v2(Thomas)
  - Handle managing the shrinker LRU in adjust_lru, where it is always
    safe to touch the object.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 29 +++++++++++++++-----
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c      | 28 +++++++++++++++----
 3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 1c9a1d8d3434..640dfbf1f01e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -523,6 +523,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 
 void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj);
 void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
+void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
 void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj);
 
 static inline bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 0440696f786a..4b6b2bb6f180 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -487,13 +487,12 @@ void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj)
 	spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 }
 
-static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
-					      struct list_head *head)
+static void ___i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
+					       struct list_head *head)
 {
 	struct drm_i915_private *i915 = obj_to_i915(obj);
 	unsigned long flags;
 
-	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
 	if (!i915_gem_object_is_shrinkable(obj))
 		return;
 
@@ -512,6 +511,21 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
 	spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 }
 
+/**
+ * __i915_gem_object_make_shrinkable - Move the object to the tail of the
+ * shrinkable list. Objects on this list might be swapped out. Used with
+ * WILLNEED objects.
+ * @obj: The GEM object.
+ *
+ * DO NOT USE. This is intended to be called on very special objects that don't
+ * yet have mm.pages, but are guaranteed to have potentially reclaimable pages
+ * underneath.
+ */
+void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
+{
+	___i915_gem_object_make_shrinkable(obj,
+					   &obj_to_i915(obj)->mm.shrink_list);
+}
 
 /**
  * i915_gem_object_make_shrinkable - Move the object to the tail of the
@@ -523,8 +537,8 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj,
  */
 void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
 {
-	__i915_gem_object_make_shrinkable(obj,
-					  &obj_to_i915(obj)->mm.shrink_list);
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	__i915_gem_object_make_shrinkable(obj);
 }
 
 /**
@@ -538,6 +552,7 @@ void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
  */
 void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj)
 {
-	__i915_gem_object_make_shrinkable(obj,
-					  &obj_to_i915(obj)->mm.purge_list);
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	___i915_gem_object_make_shrinkable(obj,
+					   &obj_to_i915(obj)->mm.purge_list);
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index c7402995a8f9..194e5f1deda8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -749,6 +749,8 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
 			return ret;
 	}
 
+	i915_ttm_adjust_lru(obj);
+
 	dst_st = i915_ttm_resource_get_st(obj, dst_mem);
 	if (IS_ERR(dst_st))
 		return PTR_ERR(dst_st);
@@ -856,7 +858,6 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
 			return i915_ttm_err_to_gem(ret);
 	}
 
-	i915_ttm_adjust_lru(obj);
 	if (bo->ttm && !ttm_tt_is_populated(bo->ttm)) {
 		ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx);
 		if (ret)
@@ -876,10 +877,10 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
 			return PTR_ERR(st);
 
 		__i915_gem_object_set_pages(obj, st, i915_sg_dma_sizes(st->sgl));
-		if (!bo->ttm || !i915_tt->is_shmem)
-			i915_gem_object_make_unshrinkable(obj);
 	}
 
+	i915_ttm_adjust_lru(obj);
+
 	return ret;
 }
 
@@ -950,8 +951,6 @@ static void i915_ttm_put_pages(struct drm_i915_gem_object *obj,
 	 * If the object is not destroyed next, The TTM eviction logic
 	 * and shrinkers will move it out if needed.
 	 */
-
-	i915_ttm_adjust_lru(obj);
 }
 
 static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
@@ -967,6 +966,17 @@ static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
 	if (!kref_read(&bo->kref))
 		return;
 
+	/*
+	 * Even if we lack mm.pages for this object(which will be the case when
+	 * something is evicted to system memory by TTM), we still want to make
+	 * this object visible to the shrinker, since the underlying ttm_tt
+	 * still has the real shmem pages.
+	 */
+	if (bo->ttm && i915_tt->filp && ttm_tt_is_populated(bo->ttm))
+		__i915_gem_object_make_shrinkable(obj);
+	else
+		i915_gem_object_make_unshrinkable(obj);
+
 	/*
 	 * Put on the correct LRU list depending on the MADV status
 	 */
@@ -1006,6 +1016,14 @@ static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
 static void i915_ttm_delayed_free(struct drm_i915_gem_object *obj)
 {
 	if (obj->ttm.created) {
+		/*
+		 * We freely manage the shrinker LRU outide of the mm.pages life
+		 * cycle. As a result when destroying the object it's up to us
+		 * to ensure we remove it from the LRU, before we free the
+		 * object.
+		 */
+		i915_gem_object_make_unshrinkable(obj);
+
 		ttm_bo_put(i915_gem_to_ttm(obj));
 	} else {
 		__i915_gem_free_object(obj);
-- 
2.26.3


  parent reply	other threads:[~2021-09-27 11:43 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-27 11:41 [PATCH v5 01/13] drm/ttm: stop calling tt_swapin in vm_access Matthew Auld
2021-09-27 11:41 ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 02/13] drm/ttm: stop setting page->index for the ttm_tt Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 03/13] drm/ttm: move ttm_tt_{add, clear}_mapping into amdgpu Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 04/13] drm/ttm: remove TTM_PAGE_FLAG_NO_RETRY Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 05/13] drm/ttm: s/FLAG_SG/FLAG_EXTERNAL/ Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 06/13] drm/ttm: add some kernel-doc for TTM_TT_FLAG_* Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 07/13] drm/ttm: add TTM_TT_FLAG_EXTERNAL_MAPPABLE Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 08/13] drm/i915/gem: Break out some shmem backend utils Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-27 11:41 ` [PATCH v5 09/13] drm/i915/ttm: add tt shmem backend Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-29 11:07   ` Thomas Hellström
2021-09-29 11:07     ` [Intel-gfx] " Thomas Hellström
2021-10-05  2:05   ` Zeng, Oak
2021-10-05  2:05     ` Zeng, Oak
2021-10-05 13:48     ` Thomas Hellström
2021-10-05 14:23       ` Zeng, Oak
2021-10-05 14:23         ` Zeng, Oak
2021-10-05 17:07         ` Matthew Auld
2021-10-05 18:33           ` Zeng, Oak
2021-10-05 18:33             ` Zeng, Oak
2021-09-27 11:41 ` [PATCH v5 10/13] drm/i915: try to simplify make_{un}shrinkable Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-29 13:00   ` Thomas Hellström
2021-09-29 13:00     ` [Intel-gfx] " Thomas Hellström
2021-09-27 11:41 ` Matthew Auld [this message]
2021-09-27 11:41   ` [Intel-gfx] [PATCH v5 11/13] drm/i915/ttm: make evicted shmem pages visible to the shrinker Matthew Auld
2021-09-29 11:47   ` Thomas Hellström
2021-09-29 11:47     ` [Intel-gfx] " Thomas Hellström
2021-09-27 11:41 ` [PATCH v5 12/13] drm/i915/ttm: use cached system pages when evicting lmem Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-29 11:54   ` Thomas Hellström
2021-09-29 11:54     ` [Intel-gfx] " Thomas Hellström
2021-09-30 10:04     ` Michel Dänzer
2021-09-30 10:04       ` [Intel-gfx] " Michel Dänzer
2021-09-30 12:27       ` Matthew Auld
2021-09-30 12:27         ` [Intel-gfx] " Matthew Auld
2021-09-30 12:55         ` Michel Dänzer
2021-09-30 12:55           ` [Intel-gfx] " Michel Dänzer
2021-09-27 11:41 ` [PATCH v5 13/13] drm/i915/ttm: enable shmem tt backend Matthew Auld
2021-09-27 11:41   ` [Intel-gfx] " Matthew Auld
2021-09-29 12:00   ` Thomas Hellström
2021-09-29 12:00     ` [Intel-gfx] " Thomas Hellström
2021-09-27 11:47 ` [PATCH v5 01/13] drm/ttm: stop calling tt_swapin in vm_access Christian König
2021-09-27 11:47   ` [Intel-gfx] " Christian König
2021-09-27 16:14   ` Matthew Auld
2021-09-29 12:01     ` Christian König
2021-09-29 13:45       ` Matthew Auld
2021-09-27 17:31 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v5,01/13] " Patchwork
2021-09-27 17:34 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-09-27 18:01 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-09-27 21:29 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2021-10-05  2:17 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [v5,01/13] drm/ttm: stop calling tt_swapin in vm_access (rev2) Patchwork

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20210927114114.152310-11-matthew.auld@intel.com \
    --to=matthew.auld@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=thomas.hellstrom@linux.intel.com \
    /path/to/YOUR_REPLY

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

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