From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> 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 <tvrtko.ursulin@xxxxxxxxx> --- 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 Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx