[PATCH 04/15] drm/i915: introduce page_size members
Matthew Auld
matthew.auld at intel.com
Tue May 30 16:28:36 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 | 40 +++++++++++++++++++++++++++++++++-
drivers/gpu/drm/i915/i915_gem_object.h | 3 +++
3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3bbc7f3145d7..2be1e6debd90 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2896,6 +2896,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 ebc9f1d3ce34..375dd94be2fc 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,13 @@ 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;
+ unsigned int largest_size;
int err;
err = mutex_lock_interruptible(&obj->mm.lock);
@@ -2533,7 +2543,35 @@ 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;
+
+ /* Select all the gtt page sizes which fit the sg layout */
+ 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);
+ }
+
+ largest_size = BIT(fls64(obj->mm.gtt_page_sizes)-1);
+
+ /* For simplicity we don't support 64K in mixed-mode */
+ if (largest_size == I915_GTT_PAGE_SIZE_64K &&
+ IS_ALIGNED(obj->mm.phys_page_sizes, I915_GTT_PAGE_SIZE_64K)) {
+ obj->mm.gtt_page_sizes = I915_GTT_PAGE_SIZE_64K;
+ }
+
+ 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