On 10/12/2016 07:05 AM, Christian König wrote: > Andy & Leo could you give that a brief testing? run `kill -9' over 30 times, no issue. Patch is: Reviewed-and-Tested by: Leo Liu <leo.liu at amd.com> > 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 > >