All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v3 04/21] drm/i915/region: support volatile objects
Date: Fri,  4 Oct 2019 18:04:35 +0100	[thread overview]
Message-ID: <20191004170452.15410-5-matthew.auld@intel.com> (raw)
In-Reply-To: <20191004170452.15410-1-matthew.auld@intel.com>

Volatile objects are marked as DONTNEED while pinned, therefore once
unpinned the backing store can be discarded. This is limited to kernel
internal objects.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: CQ Tang <cq.tang@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c    | 17 +++++++++--------
 drivers/gpu/drm/i915/gem/i915_gem_object.h      | 12 ++++++++++++
 .../gpu/drm/i915/gem/i915_gem_object_types.h    |  9 ++++++++-
 drivers/gpu/drm/i915/gem/i915_gem_pages.c       |  6 ++++++
 drivers/gpu/drm/i915/gem/i915_gem_region.c      | 13 +++++++++++++
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 12 ++++--------
 drivers/gpu/drm/i915/intel_memory_region.c      |  4 ++++
 drivers/gpu/drm/i915/intel_memory_region.h      |  5 +++++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c   |  5 ++---
 9 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index 0c41e04ab8fa..5ae694c24df4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -117,13 +117,6 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 		goto err;
 	}
 
-	/* Mark the pages as dontneed whilst they are still pinned. As soon
-	 * as they are unpinned they are allowed to be reaped by the shrinker,
-	 * and the caller is expected to repopulate - the contents of this
-	 * object are only valid whilst active and pinned.
-	 */
-	obj->mm.madv = I915_MADV_DONTNEED;
-
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
 	return 0;
@@ -143,7 +136,6 @@ static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
 	internal_free_pages(pages);
 
 	obj->mm.dirty = false;
-	obj->mm.madv = I915_MADV_WILLNEED;
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
@@ -188,6 +180,15 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
 	drm_gem_private_object_init(&i915->drm, &obj->base, size);
 	i915_gem_object_init(obj, &i915_gem_object_internal_ops);
 
+	/*
+	 * Mark the object as volatile, such that the pages are marked as
+	 * dontneed whilst they are still pinned. As soon as they are unpinned
+	 * they are allowed to be reaped by the shrinker, and the caller is
+	 * expected to repopulate - the contents of this object are only valid
+	 * whilst active and pinned.
+	 */
+	i915_gem_object_set_volatile(obj);
+
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index dfd16d65630f..c5e14c9c805c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -145,6 +145,18 @@ i915_gem_object_is_contiguous(const struct drm_i915_gem_object *obj)
 	return obj->flags & I915_BO_ALLOC_CONTIGUOUS;
 }
 
+static inline bool
+i915_gem_object_is_volatile(const struct drm_i915_gem_object *obj)
+{
+	return obj->flags & I915_BO_ALLOC_VOLATILE;
+}
+
+static inline void
+i915_gem_object_set_volatile(struct drm_i915_gem_object *obj)
+{
+	obj->flags |= I915_BO_ALLOC_VOLATILE;
+}
+
 static inline bool
 i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
 			 unsigned long flags)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index c6a712cf7d7a..a387e3ee728b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -121,7 +121,8 @@ struct drm_i915_gem_object {
 
 	unsigned long flags;
 #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
-#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
+#define I915_BO_ALLOC_VOLATILE   BIT(1)
+#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | I915_BO_ALLOC_VOLATILE)
 
 	/*
 	 * Is the object to be mapped as read-only to the GPU
@@ -172,6 +173,12 @@ struct drm_i915_gem_object {
 		 * List of memory region blocks allocated for this object.
 		 */
 		struct list_head blocks;
+		/**
+		 * Element within memory_region->objects or region->purgeable
+		 * if the object is marked as DONTNEED. Access is protected by
+		 * region->obj_lock.
+		 */
+		struct list_head region_link;
 
 		struct sg_table *pages;
 		void *mapping;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 2e941f093a20..b0ec0959c13f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -18,6 +18,9 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 
 	lockdep_assert_held(&obj->mm.lock);
 
+	if (i915_gem_object_is_volatile(obj))
+		obj->mm.madv = I915_MADV_DONTNEED;
+
 	/* Make the pages coherent with the GPU (flushing any swapin). */
 	if (obj->cache_dirty) {
 		obj->write_domain = 0;
@@ -160,6 +163,9 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 	if (IS_ERR_OR_NULL(pages))
 		return pages;
 
+	if (i915_gem_object_is_volatile(obj))
+		obj->mm.madv = I915_MADV_WILLNEED;
+
 	i915_gem_object_make_unshrinkable(obj);
 
 	if (obj->mm.mapping) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 04cb9f72945e..663254b3da21 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -109,10 +109,23 @@ void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
 	INIT_LIST_HEAD(&obj->mm.blocks);
 	obj->mm.region = intel_memory_region_get(mem);
 	obj->flags = flags;
+
+	mutex_lock(&mem->obj_lock);
+
+	if (obj->flags & I915_BO_ALLOC_VOLATILE)
+		list_add(&obj->mm.region_link, &mem->purgeable);
+	else
+		list_add(&obj->mm.region_link, &mem->objects);
+
+	mutex_unlock(&mem->obj_lock);
 }
 
 void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
 {
+	mutex_lock(&obj->mm.region->obj_lock);
+	list_del(&obj->mm.region_link);
+	mutex_unlock(&obj->mm.region->obj_lock);
+
 	intel_memory_region_put(obj->mm.region);
 }
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 63a4743e5f54..f27772f6779a 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -115,8 +115,6 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 	if (i915_gem_gtt_prepare_pages(obj, st))
 		goto err;
 
-	obj->mm.madv = I915_MADV_DONTNEED;
-
 	GEM_BUG_ON(sg_page_sizes != obj->mm.page_mask);
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
@@ -137,7 +135,6 @@ static void put_huge_pages(struct drm_i915_gem_object *obj,
 	huge_pages_free_pages(pages);
 
 	obj->mm.dirty = false;
-	obj->mm.madv = I915_MADV_WILLNEED;
 }
 
 static const struct drm_i915_gem_object_ops huge_page_ops = {
@@ -170,6 +167,8 @@ huge_pages_object(struct drm_i915_private *i915,
 	drm_gem_private_object_init(&i915->drm, &obj->base, size);
 	i915_gem_object_init(obj, &huge_page_ops);
 
+	i915_gem_object_set_volatile(obj);
+
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
 	obj->cache_level = I915_CACHE_NONE;
@@ -229,8 +228,6 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 	i915_sg_trim(st);
 
-	obj->mm.madv = I915_MADV_DONTNEED;
-
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
 	return 0;
@@ -263,8 +260,6 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	sg_dma_len(sg) = obj->base.size;
 	sg_dma_address(sg) = page_size;
 
-	obj->mm.madv = I915_MADV_DONTNEED;
-
 	__i915_gem_object_set_pages(obj, st, sg->length);
 
 	return 0;
@@ -283,7 +278,6 @@ static void fake_put_huge_pages(struct drm_i915_gem_object *obj,
 {
 	fake_free_huge_pages(obj, pages);
 	obj->mm.dirty = false;
-	obj->mm.madv = I915_MADV_WILLNEED;
 }
 
 static const struct drm_i915_gem_object_ops fake_ops = {
@@ -323,6 +317,8 @@ fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single)
 	else
 		i915_gem_object_init(obj, &fake_ops);
 
+	i915_gem_object_set_volatile(obj);
+
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
 	obj->cache_level = I915_CACHE_NONE;
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 98006618e871..fe808899cbf8 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -152,6 +152,10 @@ intel_memory_region_create(struct drm_i915_private *i915,
 	mem->min_page_size = min_page_size;
 	mem->ops = ops;
 
+	mutex_init(&mem->obj_lock);
+	INIT_LIST_HEAD(&mem->objects);
+	INIT_LIST_HEAD(&mem->purgeable);
+
 	mutex_init(&mem->mm_lock);
 
 	if (ops->init) {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 29b86ca17dd9..323270a1ef67 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -52,6 +52,11 @@ struct intel_memory_region {
 	unsigned int type;
 	unsigned int instance;
 	unsigned int id;
+
+	/* Protects access to objects and purgeable */
+	struct mutex obj_lock;
+	struct list_head objects;
+	struct list_head purgeable;
 };
 
 int intel_memory_region_init_buddy(struct intel_memory_region *mem);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 165b3a7f9744..ebe735df6504 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -82,8 +82,6 @@ static int fake_get_pages(struct drm_i915_gem_object *obj)
 	}
 	GEM_BUG_ON(rem);
 
-	obj->mm.madv = I915_MADV_DONTNEED;
-
 	__i915_gem_object_set_pages(obj, pages, sg_page_sizes);
 
 	return 0;
@@ -95,7 +93,6 @@ static void fake_put_pages(struct drm_i915_gem_object *obj,
 {
 	fake_free_pages(obj, pages);
 	obj->mm.dirty = false;
-	obj->mm.madv = I915_MADV_WILLNEED;
 }
 
 static const struct drm_i915_gem_object_ops fake_ops = {
@@ -122,6 +119,8 @@ fake_dma_object(struct drm_i915_private *i915, u64 size)
 	drm_gem_private_object_init(&i915->drm, &obj->base, size);
 	i915_gem_object_init(obj, &fake_ops);
 
+	i915_gem_object_set_volatile(obj);
+
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
 	obj->cache_level = I915_CACHE_NONE;
-- 
2.20.1

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

  parent reply	other threads:[~2019-10-04 17:05 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-04 17:04 [PATCH v3 00/21] LMEM basics Matthew Auld
2019-10-04 17:04 ` [PATCH v3 01/21] drm/i915/stolen: make the object creation interface consistent Matthew Auld
2019-10-04 17:04 ` [PATCH v3 02/21] drm/i915: introduce intel_memory_region Matthew Auld
2019-10-04 22:12   ` Chris Wilson
2019-10-08  8:59   ` Chris Wilson
2019-10-08 11:57     ` Matthew Auld
2019-10-08 12:09       ` Chris Wilson
2019-10-04 17:04 ` [PATCH v3 03/21] drm/i915/region: support contiguous allocations Matthew Auld
2019-10-08  9:06   ` Chris Wilson
2019-10-04 17:04 ` Matthew Auld [this message]
2019-10-08  9:10   ` [PATCH v3 04/21] drm/i915/region: support volatile objects Chris Wilson
2019-10-04 17:04 ` [PATCH v3 05/21] drm/i915: Add memory region information to device_info Matthew Auld
2019-10-08  9:11   ` Chris Wilson
2019-10-04 17:04 ` [PATCH v3 06/21] drm/i915: support creating LMEM objects Matthew Auld
2019-10-04 17:04 ` [PATCH v3 07/21] drm/i915: setup io-mapping for LMEM Matthew Auld
2019-10-04 17:04 ` [PATCH v3 08/21] drm/i915/lmem: support kernel mapping Matthew Auld
2019-10-04 17:04 ` [PATCH v3 09/21] drm/i915/selftests: add write-dword test for LMEM Matthew Auld
2019-10-04 17:04 ` [PATCH v3 10/21] drm/i915/selftests: extend coverage to include LMEM huge-pages Matthew Auld
2019-10-04 17:04 ` [PATCH v3 11/21] drm/i915: enumerate and init each supported region Matthew Auld
2019-10-04 17:04 ` [PATCH v3 12/21] drm/i915: treat shmem as a region Matthew Auld
2019-10-04 17:04 ` [PATCH v3 13/21] drm/i915: treat stolen " Matthew Auld
2019-10-04 17:04 ` [PATCH v3 14/21] drm/i915: define i915_ggtt_has_aperture Matthew Auld
2019-10-04 17:04 ` [PATCH v3 15/21] drm/i915: do not map aperture if it is not available Matthew Auld
2019-10-04 17:04 ` [PATCH v3 16/21] drm/i915: set num_fence_regs to 0 if there is no aperture Matthew Auld
2019-10-04 17:04 ` [PATCH v3 17/21] drm/i915: error capture with no ggtt slot Matthew Auld
2019-10-04 17:04 ` [PATCH v3 18/21] drm/i915: Don't try to place HWS in non-existing mappable region Matthew Auld
2019-10-04 17:25   ` Chris Wilson
2019-10-04 17:04 ` [PATCH v3 19/21] drm/i915: don't allocate the ring in stolen if we lack aperture Matthew Auld
2019-10-04 17:04 ` [PATCH v3 20/21] drm/i915/selftests: check for missing aperture Matthew Auld
2019-10-04 17:04 ` [PATCH v3 21/21] HAX drm/i915: add the fake lmem region Matthew Auld
2019-10-04 18:09 ` ✗ Fi.CI.CHECKPATCH: warning for LMEM basics (rev3) Patchwork
2019-10-04 18:19 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-10-04 18:33 ` ✓ Fi.CI.BAT: success " Patchwork
2019-10-05  5:46 ` ✗ Fi.CI.IGT: failure " 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=20191004170452.15410-5-matthew.auld@intel.com \
    --to=matthew.auld@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /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.