[PATCH 02/17] drm/i915: introduce page_size members

Matthew Auld matthew.auld at intel.com
Wed May 24 18:24:51 UTC 2017


In preparation for supporting huge gtt pages for the ppgtt, we introduce
a page_sizes members for gem objects.  We fill in the page_sizes by
scanning the sg table.

Signed-off-by: Matthew Auld <matthew.auld at intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Daniel Vetter <daniel at ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h        |  2 ++
 drivers/gpu/drm/i915/i915_gem.c        | 29 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_object.h |  3 +++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cfad610b3ead..ada3a1f37a0d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2892,6 +2892,8 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define USES_PPGTT(dev_priv)		(i915.enable_ppgtt)
 #define USES_FULL_PPGTT(dev_priv)	(i915.enable_ppgtt >= 2)
 #define USES_FULL_48BIT_PPGTT(dev_priv)	(i915.enable_ppgtt == 3)
+#define HAS_PAGE_SIZE(dev_priv, page_size) \
+	((dev_priv)->info.page_size_mask & (page_size))
 
 #define HAS_OVERLAY(dev_priv)		 ((dev_priv)->info.has_overlay)
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a637cc05cc4a..8f7d1cc9f497 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2294,6 +2294,8 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
 	if (!IS_ERR(pages))
 		obj->ops->put_pages(obj, pages);
 
+	obj->mm.phys_page_sizes = obj->mm.gtt_page_sizes = 0;
+
 unlock:
 	mutex_unlock(&obj->mm.lock);
 }
@@ -2473,6 +2475,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 				 struct sg_table *pages)
 {
+
 	lockdep_assert_held(&obj->mm.lock);
 
 	obj->mm.get_page.sg_pos = pages->sgl;
@@ -2516,6 +2519,12 @@ static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
  */
 int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 {
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	unsigned long supported_page_sizes = INTEL_INFO(i915)->page_size_mask;
+	struct scatterlist *sg;
+	unsigned int sg_mask = 0;
+	unsigned int i;
+	unsigned int bit;
 	int err;
 
 	err = mutex_lock_interruptible(&obj->mm.lock);
@@ -2533,7 +2542,25 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 
 unlock:
 	mutex_unlock(&obj->mm.lock);
-	return err;
+
+	if (err)
+		return err;
+
+	for_each_sg(obj->mm.pages->sgl, sg, obj->mm.pages->nents, i)
+		sg_mask |= sg->length;
+
+	GEM_BUG_ON(!sg_mask);
+
+	obj->mm.phys_page_sizes = sg_mask;
+
+	obj->mm.gtt_page_sizes = 0;
+        for_each_set_bit(bit, &supported_page_sizes, BITS_PER_LONG) {
+                if (obj->mm.phys_page_sizes & ~0u << bit)
+                        obj->mm.gtt_page_sizes |= BIT(bit);
+        }
+
+	GEM_BUG_ON(!obj->mm.gtt_page_sizes);
+	return 0;
 }
 
 /* The 'mapping' part of i915_gem_object_pin_map() below */
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 35e1a27729dc..9cbe57453bcf 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -129,6 +129,9 @@ struct drm_i915_gem_object {
 		struct sg_table *pages;
 		void *mapping;
 
+		unsigned int phys_page_sizes;
+		unsigned int gtt_page_sizes;
+
 		struct i915_gem_object_page_iter {
 			struct scatterlist *sg_pos;
 			unsigned int sg_idx; /* in pages, but 32bit eek! */
-- 
2.9.4



More information about the Intel-gfx-trybot mailing list