[PATCH] drm/i915/gvt: refine shadow batch buffer
Zhenyu Wang
zhenyuw at linux.intel.com
Mon Mar 20 03:30:29 UTC 2017
On 2017.03.16 21:25:56 -0400, Tina Zhang wrote:
> i915 driver implements i915 batch buffer pool based on internal GEM
> object, which can be used for shadow batch buffer. This patch refines
> the shadow batch buffer with i915 batch buffer pool APIs to implement
> an internal GEM object based shadow batch buffer.
>
> Signed-off-by: Tina Zhang <tina.zhang at intel.com>
>
> diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
> index 6f972af..4e05215 100644
> --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
> +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
> @@ -1064,7 +1064,7 @@ static int cmd_advance_default(struct parser_exec_state *s)
> return ip_gma_advance(s, cmd_length(s));
> }
>
> -static int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
> +static int batch_buffer_end(struct parser_exec_state *s)
> {
> int ret;
>
> @@ -1082,6 +1082,21 @@ static int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
> return ret;
> }
>
> +static int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
> +{
> + struct intel_shadow_bb_entry *entry_obj;
> +
> + batch_buffer_end(s);
> +
> + entry_obj = list_last_entry(&s->workload->mapped_shadow_bb,
> + struct intel_shadow_bb_entry, list);
> +
> + i915_gem_object_unpin_map(entry_obj->obj);
> + list_move_tail(&entry_obj->list, &s->workload->shadow_bb);
> +
> + return 0;
> +}
> +
> struct mi_display_flip_command_info {
> int pipe;
> int plane;
> @@ -1628,6 +1643,7 @@ static int perform_bb_shadow(struct parser_exec_state *s)
> {
> struct intel_shadow_bb_entry *entry_obj;
> struct intel_vgpu *vgpu = s->vgpu;
> + unsigned int dst_needs_clflush;
> unsigned long gma = 0;
> uint32_t bb_size;
> void *dst = NULL;
> @@ -1644,41 +1660,46 @@ static int perform_bb_shadow(struct parser_exec_state *s)
> if (entry_obj == NULL)
> return -ENOMEM;
>
> - entry_obj->obj =
> - i915_gem_object_create(s->vgpu->gvt->dev_priv,
> - roundup(bb_size, PAGE_SIZE));
> + entry_obj->obj = i915_gem_batch_pool_get(
> + &s->workload->req->engine->batch_pool, PAGE_ALIGN(bb_size));
> if (IS_ERR(entry_obj->obj)) {
> ret = PTR_ERR(entry_obj->obj);
> - goto free_entry;
> + kfree(entry_obj);
> + return ret;
> }
> +
> + entry_obj->obj->active_count++;
> entry_obj->len = bb_size;
> INIT_LIST_HEAD(&entry_obj->list);
>
> + ret = i915_gem_obj_prepare_shmem_write(entry_obj->obj,
> + &dst_needs_clflush);
> + if (ret) {
> + kfree(entry_obj);
> + return ret;
> + }
> dst = i915_gem_object_pin_map(entry_obj->obj, I915_MAP_WB);
> if (IS_ERR(dst)) {
> + i915_gem_obj_finish_shmem_access(entry_obj->obj);
> + kfree(entry_obj);
Should unpin allocated batch from pool.
> ret = PTR_ERR(dst);
> - goto put_obj;
> - }
> -
> - ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false);
> - if (ret) {
> - gvt_vgpu_err("failed to set shadow batch to CPU\n");
> - goto unmap_src;
> + return ret;
> }
>
> - entry_obj->va = dst;
> entry_obj->bb_start_cmd_va = s->ip_va;
>
> /* copy batch buffer to shadow batch buffer*/
> ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm,
> - gma, gma + bb_size,
> - dst);
> + gma, gma + bb_size, dst);
> if (ret < 0) {
> - gvt_vgpu_err("fail to copy guest ring buffer\n");
> - goto unmap_src;
> + gvt_err("fail to copy guest batch buffer\n");
> + i915_gem_object_unpin_map(entry_obj->obj);
> + i915_gem_obj_finish_shmem_access(entry_obj->obj);
> + kfree(entry_obj);
> + return ret;
> }
>
> - list_add(&entry_obj->list, &s->workload->shadow_bb);
> + list_add_tail(&entry_obj->list, &s->workload->mapped_shadow_bb);
> /*
> * ip_va saves the virtual address of the shadow batch buffer, while
> * ip_gma saves the graphics address of the original batch buffer.
> @@ -1690,14 +1711,7 @@ static int perform_bb_shadow(struct parser_exec_state *s)
> s->ip_va = dst;
> s->ip_gma = gma;
>
> - return 0;
> -
> -unmap_src:
> - i915_gem_object_unpin_map(entry_obj->obj);
> -put_obj:
> - i915_gem_object_put(entry_obj->obj);
> -free_entry:
> - kfree(entry_obj);
> + i915_gem_obj_finish_shmem_access(entry_obj->obj);
> return ret;
> }
>
> @@ -1735,7 +1749,7 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
> gvt_vgpu_err("invalid shadow batch buffer\n");
> } else {
> /* emulate a batch buffer end to do return right */
> - ret = cmd_handler_mi_batch_buffer_end(s);
> + ret = batch_buffer_end(s);
> if (ret < 0)
> return ret;
> }
> diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
> index f1f426a..6c19645 100644
> --- a/drivers/gpu/drm/i915/gvt/execlist.c
> +++ b/drivers/gpu/drm/i915/gvt/execlist.c
> @@ -374,12 +374,11 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
> /* pin the gem object to ggtt */
> list_for_each_entry(entry_obj, &workload->shadow_bb, list) {
> struct i915_vma *vma;
> -
> - vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, 4, 0);
> + vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, 0, 0);
> if (IS_ERR(vma)) {
> return;
> }
> -
> + entry_obj->batch = vma;
> /* FIXME: we are not tracking our pinned VMA leaving it
> * up to the core to fix up the stray pin_count upon
> * free.
> @@ -389,6 +388,9 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
> entry_obj->bb_start_cmd_va[1] = i915_ggtt_offset(vma);
> if (gmadr_bytes == 8)
> entry_obj->bb_start_cmd_va[2] = 0;
> +
> + i915_gem_object_get(entry_obj->obj);
> + i915_gem_object_unpin_pages(entry_obj->obj);
> }
> }
>
> @@ -477,7 +479,8 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
>
> list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
> list) {
> - i915_gem_object_unpin_map(entry_obj->obj);
> + i915_vma_unpin(entry_obj->batch);
> + --entry_obj->obj->active_count;
> i915_gem_object_put(entry_obj->obj);
> list_del(&entry_obj->list);
> kfree(entry_obj);
> @@ -650,6 +653,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
>
> INIT_LIST_HEAD(&workload->list);
> INIT_LIST_HEAD(&workload->shadow_bb);
> + INIT_LIST_HEAD(&workload->mapped_shadow_bb);
>
> init_waitqueue_head(&workload->shadow_ctx_status_wq);
> atomic_set(&workload->shadow_ctx_active, 0);
> diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
> index 2833dfa..505a2c6 100644
> --- a/drivers/gpu/drm/i915/gvt/scheduler.h
> +++ b/drivers/gpu/drm/i915/gvt/scheduler.h
> @@ -104,6 +104,7 @@ struct intel_vgpu_workload {
>
> /* shadow batch buffer */
> struct list_head shadow_bb;
> + struct list_head mapped_shadow_bb;
> struct intel_shadow_wa_ctx wa_ctx;
> };
>
> @@ -111,7 +112,7 @@ struct intel_vgpu_workload {
> struct intel_shadow_bb_entry {
> struct list_head list;
> struct drm_i915_gem_object *obj;
> - void *va;
> + struct i915_vma *batch;
> unsigned long len;
> u32 *bb_start_cmd_va;
> };
> --
> 2.7.4
>
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gvt-dev/attachments/20170320/4507d5d2/attachment.sig>
More information about the intel-gvt-dev
mailing list