[PATCH 07/16] drm/i915: introduce page_size members
Matthew Auld
matthew.auld at intel.com
Tue Jun 6 17:07:39 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.
v2: pass the sg_mask to set_pages
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 | 5 ++++-
drivers/gpu/drm/i915/i915_gem.c | 29 +++++++++++++++++++++++++++--
drivers/gpu/drm/i915/i915_gem_object.h | 5 +++++
drivers/gpu/drm/i915/i915_gem_userptr.c | 13 ++++++++++++-
4 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 66ae17608883..7814c135e33a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2897,6 +2897,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) \
@@ -3275,7 +3277,8 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj,
unsigned long n);
void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
- struct sg_table *pages);
+ struct sg_table *pages,
+ unsigned int sg_mask);
int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
static inline int __must_check
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7ddd360461ae..f0727dd4fb21 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2295,6 +2295,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.page_sizes.phys = obj->mm.page_sizes.sg = 0;
+
unlock:
mutex_unlock(&obj->mm.lock);
}
@@ -2472,8 +2474,13 @@ 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)
+ struct sg_table *pages,
+ unsigned int sg_mask)
{
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
+ unsigned long supported_page_sizes = INTEL_INFO(i915)->page_size_mask;
+ unsigned int bit;
+
lockdep_assert_held(&obj->mm.lock);
obj->mm.get_page.sg_pos = pages->sgl;
@@ -2487,11 +2494,26 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
__i915_gem_object_pin_pages(obj);
obj->mm.quirked = true;
}
+
+ GEM_BUG_ON(!sg_mask);
+
+ obj->mm.page_sizes.phys = sg_mask;
+
+ obj->mm.page_sizes.sg = 0;
+ for_each_set_bit(bit, &supported_page_sizes, BITS_PER_LONG) {
+ if (obj->mm.page_sizes.phys & ~0u << bit)
+ obj->mm.page_sizes.sg |= BIT(bit);
+ }
+
+ GEM_BUG_ON(!HAS_PAGE_SIZE(i915, obj->mm.page_sizes.sg));
}
static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
{
struct sg_table *pages;
+ struct scatterlist *sg;
+ unsigned int sg_mask = 0;
+ int i;
GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
@@ -2504,7 +2526,10 @@ static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
if (unlikely(IS_ERR(pages)))
return PTR_ERR(pages);
- __i915_gem_object_set_pages(obj, pages);
+ for_each_sg(pages->sgl, sg, pages->nents, i)
+ sg_mask |= sg->length;
+
+ __i915_gem_object_set_pages(obj, pages, sg_mask);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 915057824284..94a50bf100ac 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -144,6 +144,11 @@ struct drm_i915_gem_object {
struct sg_table *pages;
void *mapping;
+ struct i915_page_sizes {
+ unsigned int phys;
+ unsigned int sg;
+ } page_sizes;
+
struct i915_gem_object_page_iter {
struct scatterlist *sg_pos;
unsigned int sg_idx; /* in pages, but 32bit eek! */
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 1a0ce1dc68f5..230c3a7be592 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -542,7 +542,18 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
if (pinned == npages) {
pages = __i915_gem_userptr_set_pages(obj, pvec, npages);
if (!IS_ERR(pages)) {
- __i915_gem_object_set_pages(obj, pages);
+ unsigned int sg_mask = 0;
+
+ if (swiotlb_active()) {
+ sg_mask = I915_GTT_PAGE_SIZE;
+ } else {
+ struct scatterlist *sg;
+ int i;
+ for_each_sg(pages->sgl, sg, pages->nents, i)
+ sg_mask |= sg->length;
+ }
+
+ __i915_gem_object_set_pages(obj, pages, sg_mask);
pinned = 0;
pages = NULL;
}
--
2.9.4
More information about the Intel-gfx-trybot
mailing list