From: Tvrtko Ursulin <[email protected]>

Simplify the partial view creation loop by using the newly
introduced helpers.

It also allows the list to be coalesced when possbile.

New i915_sg_add_dma helper was added to allow adding just
the DMA address entries to the list.

Signed-off-by: Tvrtko Ursulin <[email protected]>
---
 drivers/gpu/drm/i915/i915_drv.h     |  1 +
 drivers/gpu/drm/i915/i915_gem.c     | 38 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.c | 34 ++++++++-------------------------
 3 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e226794ffc1b..641a1dbc87b8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -4019,6 +4019,7 @@ struct i915_sg_create_state {
 
 struct i915_sg_create_state *i915_sg_create(unsigned int page_count);
 void i915_sg_add_page(struct i915_sg_create_state *state, struct page *page);
+void i915_sg_add_dma(struct i915_sg_create_state *state, dma_addr_t addr);
 struct sg_table *i915_sg_complete(struct i915_sg_create_state *state);
 void i915_sg_abort(struct i915_sg_create_state *state);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1c1aa3bbde8a..05dc2af1a89e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2268,6 +2268,8 @@ struct i915_sg_create_state *i915_sg_create(unsigned int 
page_count)
  * page which needs to be added to the sg list.
  * Function manages the internal state which can be read (only!) by the caller
  * where appropriate.
+ *
+ * MUST NOT be mixed with i915_sg_add_dma!
  */
 void i915_sg_add_page(struct i915_sg_create_state *state, struct page *page)
 {
@@ -2291,6 +2293,42 @@ void i915_sg_add_page(struct i915_sg_create_state 
*state, struct page *page)
 }
 
 /**
+ * i915_sg_add_dma - adds a dma address to the sg list being built
+ * @state: state created with i915_sg_create
+ * @addr: dma address to add
+ *
+ * Intended to be called under the i915_sg_for_each_page iterator once for each
+ * page which needs to be added to the sg list.
+ * Function manages the internal state which can be read (only!) by the caller
+ * where appropriate.
+ *
+ * MUST NOT be mixed with i915_sg_add_page!
+ */
+void i915_sg_add_dma(struct i915_sg_create_state *state, dma_addr_t addr)
+{
+       struct scatterlist *sg = state->sg;
+
+       if (!state->idx ||
+           sg->length >= state->max_segment ||
+           addr != state->last_pfn + PAGE_SIZE) {
+               if (state->idx)
+                       sg = sg_next(sg);
+               state->st->nents++;
+               sg_set_page(sg, NULL, PAGE_SIZE, 0);
+               sg_dma_address(sg) = addr;
+               sg_dma_len(sg) = PAGE_SIZE;
+       } else {
+               sg->length += PAGE_SIZE;
+               if (IS_ENABLED(CONFIG_NEED_SG_DMA_LENGTH))
+                       sg_dma_len(sg) += PAGE_SIZE;
+       }
+
+       state->last_pfn = addr;
+       state->sg = sg;
+       state->idx++;
+}
+
+/**
  * i915_sg_complete - completes the sg list building
  * @state: state created with i915_sg_create
  *
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2d846aa39ca5..f0c70e7c8daa 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3559,41 +3559,23 @@ static struct sg_table *
 intel_partial_pages(const struct i915_ggtt_view *view,
                    struct drm_i915_gem_object *obj)
 {
-       struct sg_table *st;
-       struct scatterlist *sg;
+       struct i915_sg_create_state *state;
        struct sg_page_iter obj_sg_iter;
-       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);
-       if (ret)
-               goto err_sg_alloc;
+       state = i915_sg_create(view->params.partial.size);
+       if (IS_ERR(state))
+               return ERR_CAST(state);
 
-       sg = st->sgl;
-       st->nents = 0;
        for_each_sg_page(obj->pages->sgl, &obj_sg_iter, obj->pages->nents,
-               view->params.partial.offset)
+                        view->params.partial.offset)
        {
-               if (st->nents >= view->params.partial.size)
+               if (state->idx >= view->params.partial.size)
                        break;
 
-               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 = sg_next(sg);
-               st->nents++;
+               i915_sg_add_dma(state, sg_page_iter_dma_address(&obj_sg_iter));
        }
 
-       return st;
-
-err_sg_alloc:
-       kfree(st);
-err_st_alloc:
-       return ERR_PTR(ret);
+       return i915_sg_complete(state);
 }
 
 static int
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to