[PATCH 2/2] drm/amdgpu: add VCE VM session tracking
Andy Furniss
adf.lists at gmail.com
Wed Oct 12 14:47:41 UTC 2016
Christian König wrote:
> Andy & Leo could you give that a brief testing?
Seems to be OK for me.
>
> I currently don't have a setup for encoding/transcoding clips.
>
> Regards,
> Christian.
>
> Am 10.10.2016 um 18:45 schrieb Alex Deucher:
>> 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
>
>
>
More information about the amd-gfx
mailing list