From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Harrison Subject: Re: [PATCH 15/42] drm/i915: Use radixtree to jump start intel_partial_pages() Date: Fri, 7 Oct 2016 14:46:50 +0100 Message-ID: References: <20161007094635.28319-1-chris@chris-wilson.co.uk> <20161007094635.28319-16-chris@chris-wilson.co.uk> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0694100071==" Return-path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6D4F76E3DD for ; Fri, 7 Oct 2016 13:46:52 +0000 (UTC) In-Reply-To: <20161007094635.28319-16-chris@chris-wilson.co.uk> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org This is a multi-part message in MIME format. --===============0694100071== Content-Type: multipart/alternative; boundary="------------5ABC0D2CF5AB82E82AB1F5A0" This is a multi-part message in MIME format. --------------5ABC0D2CF5AB82E82AB1F5A0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 07/10/2016 10:46, Chris Wilson wrote: > We can use the radixtree index of the obj->pages to find the start > position of the desired partial range. > > Signed-off-by: Chris Wilson > --- > drivers/gpu/drm/i915/i915_gem_gtt.c | 38 +++++++++++++++++++++++-------------- > 1 file changed, 24 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c > index 78b692e5b998..7e0c98576e72 100644 > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c > @@ -3562,35 +3562,45 @@ intel_partial_pages(const struct i915_ggtt_view *view, > struct drm_i915_gem_object *obj) > { > struct sg_table *st; > - struct scatterlist *sg; > - struct sg_page_iter obj_sg_iter; > + struct scatterlist *sg, *iter; > + unsigned int count = view->params.partial.size; > + unsigned int offset; > int ret = -ENOMEM; > > st = kmalloc(sizeof(*st), GFP_KERNEL); > if (!st) > goto err_st_alloc; > > - ret = sg_alloc_table(st, view->params.partial.size, GFP_KERNEL); > + ret = sg_alloc_table(st, count, GFP_KERNEL); > if (ret) > goto err_sg_alloc; > > + iter = i915_gem_object_get_sg(obj, > + view->params.partial.offset, > + &offset); > + > sg = st->sgl; > st->nents = 0; > - for_each_sg_page(obj->pages->sgl, &obj_sg_iter, obj->pages->nents, > - view->params.partial.offset) > - { > - if (st->nents >= view->params.partial.size) > - break; > + do { > + unsigned int len = > + min(iter->length, (count - offset) << PAGE_SHIFT); > > - sg_set_page(sg, NULL, PAGE_SIZE, 0); > - sg_dma_address(sg) = sg_page_iter_dma_address(&obj_sg_iter); > - sg_dma_len(sg) = PAGE_SIZE; > + sg_set_page(sg, NULL, len, 0); > + sg_dma_address(sg) = > + sg_dma_address(iter) + (offset << PAGE_SHIFT); > + sg_dma_len(sg) = len; > > - sg = sg_next(sg); > st->nents++; > - } > + count -= len >> PAGE_SHIFT; > + if (count == 0) { > + sg_mark_end(sg); > + return st; > + } > > - return st; > + sg = __sg_next(sg); > + iter = __sg_next(iter); > + offset = 0; > + } while (1); > > err_sg_alloc: > kfree(st); Reviewed-by: John Harrison --------------5ABC0D2CF5AB82E82AB1F5A0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit On 07/10/2016 10:46, Chris Wilson wrote:
We can use the radixtree index of the obj->pages to find the start
position of the desired partial range.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 38 +++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 78b692e5b998..7e0c98576e72 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3562,35 +3562,45 @@ intel_partial_pages(const struct i915_ggtt_view *view,
 		    struct drm_i915_gem_object *obj)
 {
 	struct sg_table *st;
-	struct scatterlist *sg;
-	struct sg_page_iter obj_sg_iter;
+	struct scatterlist *sg, *iter;
+	unsigned int count = view->params.partial.size;
+	unsigned int offset;
 	int ret = -ENOMEM;
 
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
 	if (!st)
 		goto err_st_alloc;
 
-	ret = sg_alloc_table(st, view->params.partial.size, GFP_KERNEL);
+	ret = sg_alloc_table(st, count, GFP_KERNEL);
 	if (ret)
 		goto err_sg_alloc;
 
+	iter = i915_gem_object_get_sg(obj,
+				      view->params.partial.offset,
+				      &offset);
+
 	sg = st->sgl;
 	st->nents = 0;
-	for_each_sg_page(obj->pages->sgl, &obj_sg_iter, obj->pages->nents,
-		view->params.partial.offset)
-	{
-		if (st->nents >= view->params.partial.size)
-			break;
+	do {
+		unsigned int len =
+			min(iter->length, (count - offset) << PAGE_SHIFT);
 
-		sg_set_page(sg, NULL, PAGE_SIZE, 0);
-		sg_dma_address(sg) = sg_page_iter_dma_address(&obj_sg_iter);
-		sg_dma_len(sg) = PAGE_SIZE;
+		sg_set_page(sg, NULL, len, 0);
+		sg_dma_address(sg) =
+			sg_dma_address(iter) + (offset << PAGE_SHIFT);
+		sg_dma_len(sg) = len;
 
-		sg = sg_next(sg);
 		st->nents++;
-	}
+		count -= len >> PAGE_SHIFT;
+		if (count == 0) {
+			sg_mark_end(sg);
+			return st;
+		}
 
-	return st;
+		sg = __sg_next(sg);
+		iter = __sg_next(iter);
+		offset = 0;
+	} while (1);
 
 err_sg_alloc:
 	kfree(st);


Reviewed-by: John Harrison <john.c.harrison@intel.com>

--------------5ABC0D2CF5AB82E82AB1F5A0-- --===============0694100071== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KSW50ZWwtZ2Z4 IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlz dHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vaW50ZWwtZ2Z4Cg== --===============0694100071==--