[PATCH 2/2] drm/amdgpu: add VCE VM session tracking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 10, 2016 at 9:40 AM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> Only compile tested, but should fix the problems with killing
> VCE sessions in VM mode.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

Series is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 90 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h |  1 +
>  drivers/gpu/drm/amd/amdgpu/vce_v3_0.c   |  1 +
>  3 files changed, 92 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index 05a1ea9..3d6f86c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -792,6 +792,96 @@ out:
>  }
>
>  /**
> + * amdgpu_vce_cs_parse_vm - parse the command stream in VM mode
> + *
> + * @p: parser context
> + *
> + */
> +int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx)
> +{
> +       struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
> +       int session_idx = -1;
> +       uint32_t destroyed = 0;
> +       uint32_t created = 0;
> +       uint32_t allocated = 0;
> +       uint32_t tmp, handle = 0;
> +       int i, r = 0, idx = 0;
> +
> +       while (idx < ib->length_dw) {
> +               uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
> +               uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
> +
> +               if ((len < 8) || (len & 3)) {
> +                       DRM_ERROR("invalid VCE command length (%d)!\n", len);
> +                       r = -EINVAL;
> +                       goto out;
> +               }
> +
> +               switch (cmd) {
> +               case 0x00000001: /* session */
> +                       handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
> +                       session_idx = amdgpu_vce_validate_handle(p, handle,
> +                                                                &allocated);
> +                       if (session_idx < 0) {
> +                               r = session_idx;
> +                               goto out;
> +                       }
> +                       break;
> +
> +               case 0x01000001: /* create */
> +                       created |= 1 << session_idx;
> +                       if (destroyed & (1 << session_idx)) {
> +                               destroyed &= ~(1 << session_idx);
> +                               allocated |= 1 << session_idx;
> +
> +                       } else if (!(allocated & (1 << session_idx))) {
> +                               DRM_ERROR("Handle already in use!\n");
> +                               r = -EINVAL;
> +                               goto out;
> +                       }
> +
> +                       break;
> +
> +               case 0x02000001: /* destroy */
> +                       destroyed |= 1 << session_idx;
> +                       break;
> +
> +               default:
> +                       break;
> +               }
> +
> +               if (session_idx == -1) {
> +                       DRM_ERROR("no session command at start of IB\n");
> +                       r = -EINVAL;
> +                       goto out;
> +               }
> +
> +               idx += len / 4;
> +       }
> +
> +       if (allocated & ~created) {
> +               DRM_ERROR("New session without create command!\n");
> +               r = -ENOENT;
> +       }
> +
> +out:
> +       if (!r) {
> +               /* No error, free all destroyed handle slots */
> +               tmp = destroyed;
> +               amdgpu_ib_free(p->adev, ib, NULL);
> +       } else {
> +               /* Error during parsing, free all allocated handle slots */
> +               tmp = allocated;
> +       }
> +
> +       for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i)
> +               if (tmp & (1 << i))
> +                       atomic_set(&p->adev->vce.handles[i], 0);
> +
> +       return r;
> +}
> +
> +/**
>   * amdgpu_vce_ring_emit_ib - execute indirect buffer
>   *
>   * @ring: engine to use
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> index 12729d2..44d49b5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> @@ -34,6 +34,7 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
>                                bool direct, struct fence **fence);
>  void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
>  int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx);
> +int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx);
>  void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib,
>                              unsigned vm_id, bool ctx_switch);
>  void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> index f7dbd0d..2abf5bd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> @@ -854,6 +854,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = {
>         .get_rptr = vce_v3_0_ring_get_rptr,
>         .get_wptr = vce_v3_0_ring_get_wptr,
>         .set_wptr = vce_v3_0_ring_set_wptr,
> +       .parse_cs = amdgpu_vce_ring_parse_cs_vm,
>         .emit_frame_size =
>                 6 + /* vce_v3_0_emit_vm_flush */
>                 4 + /* vce_v3_0_emit_pipeline_sync */
> --
> 2.5.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux