Route existing render-node events through the debug event layer. Without an attached debugger, the helper immediately delivers the event to the normal EVENTFD and WAIT_EVENT paths. With an attached debugger, the event is queued to the debug fd first and is delivered to the application only when the debugger forwards it.
This keeps EVENTFD notification-only and keeps WAIT_EVENT as the metadata path, while adding the debugger as an optional routing layer on top of both. Cc: Alex Deucher <[email protected]> Cc: Christian König <[email protected]> Signed-off-by: Srinivasan Shanmugam <[email protected]> --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 94 +++++++++++----------- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 14 ++-- drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 27 ++++--- 3 files changed, 71 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 1bd1eee77262..053e20c1e27b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -6480,57 +6480,61 @@ static int gfx_v11_0_eop_irq(struct amdgpu_device *adev, DRM_DEBUG("IH: CP EOP\n"); if (adev->enable_mes && doorbell_offset) { - struct amdgpu_usermode_queue *queue = NULL; - struct amdgpu_userq_mgr *mgr = NULL; - struct xarray *xa = &adev->userq_doorbell_xa; - u32 queue_key = 0; - unsigned long flags; - - amdgpu_userq_process_fence_irq(adev, doorbell_offset); - - xa_lock_irqsave(xa, flags); - queue = xa_load(xa, doorbell_offset); - if (queue) { - mgr = queue->userq_mgr; - queue_key = queue->qid; - } - - if (mgr && mgr->eventfd_mgr) - amdgpu_eventfd_signal(mgr->eventfd_mgr, - DRM_AMDGPU_EVENT_TYPE_USERQ_EOP, - queue_key); - - if (mgr && mgr->wait_event_mgr) - amdgpu_wait_event_push_userq_eop(mgr->wait_event_mgr, - queue_key, 0, 0, 0); - - xa_unlock_irqrestore(xa, flags); + struct amdgpu_usermode_queue *queue = NULL; + struct amdgpu_userq_mgr *mgr = NULL; + struct xarray *xa = &adev->userq_doorbell_xa; + u32 queue_key = 0; + unsigned long flags; + + amdgpu_userq_process_fence_irq(adev, doorbell_offset); + + xa_lock_irqsave(xa, flags); + queue = xa_load(xa, doorbell_offset); + if (queue) { + mgr = queue->userq_mgr; + queue_key = queue->qid; + } + + if (mgr && mgr->file) { + struct amdgpu_fpriv *fpriv = mgr->file->driver_priv; + struct drm_amdgpu_wait_event_data data = {}; + + data.event_type = DRM_AMDGPU_EVENT_TYPE_USERQ_EOP; + data.queue_id = queue_key; + data.u.queue.queue_id = queue_key; + data.u.queue.status = 0; + data.u.queue.data0 = 0; + data.u.queue.data1 = 0; + + amdgpu_debug_event_route(fpriv, &data); + } + xa_unlock_irqrestore(xa, flags); } else { me_id = (entry->ring_id & 0x0c) >> 2; pipe_id = (entry->ring_id & 0x03) >> 0; queue_id = (entry->ring_id & 0x70) >> 4; switch (me_id) { - case 0: - if (pipe_id == 0) - amdgpu_fence_process(&adev->gfx.gfx_ring[0]); - else - amdgpu_fence_process(&adev->gfx.gfx_ring[1]); - break; - case 1: - case 2: - for (i = 0; i < adev->gfx.num_compute_rings; i++) { - ring = &adev->gfx.compute_ring[i]; - /* Per-queue interrupt is supported for MEC starting from VI. - * The interrupt can only be enabled/disabled per pipe instead - * of per queue. - */ - if ((ring->me == me_id) && - (ring->pipe == pipe_id) && - (ring->queue == queue_id)) - amdgpu_fence_process(ring); - } - break; + case 0: + if (pipe_id == 0) + amdgpu_fence_process(&adev->gfx.gfx_ring[0]); + else + amdgpu_fence_process(&adev->gfx.gfx_ring[1]); + break; + case 1: + case 2: + for (i = 0; i < adev->gfx.num_compute_rings; i++) { + ring = &adev->gfx.compute_ring[i]; + /* Per-queue interrupt is supported for MEC starting from VI. + * The interrupt can only be enabled/disabled per pipe instead + * of per queue. + */ + if ((ring->me == me_id) && + (ring->pipe == pipe_id) && + (ring->queue == queue_id)) + amdgpu_fence_process(ring); + } + break; } } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 4136f2a8e31c..1af5f1289897 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -142,17 +142,19 @@ static int gmc_v11_0_process_interrupt(struct amdgpu_device *adev, list_for_each_entry(file, &adev_to_drm(adev)->filelist, lhead) { struct amdgpu_fpriv *fpriv = file->driver_priv; + struct drm_amdgpu_wait_event_data data = {}; if (!fpriv) continue; - amdgpu_eventfd_signal(&fpriv->eventfd_mgr, - DRM_AMDGPU_EVENT_TYPE_MEMORY_EXCEPTION, - 0); + data.event_type = DRM_AMDGPU_EVENT_TYPE_MEMORY_EXCEPTION; + data.queue_id = 0; + data.u.memory.queue_id = 0; + data.u.memory.fault_status = status; + data.u.memory.va = addr; + data.u.memory.data0 = 0; - amdgpu_wait_event_push_memory_exception( - &fpriv->wait_event_mgr, - 0, status, addr, 0); + amdgpu_debug_event_route(fpriv, &data); } } } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index cdbd732ee7ef..3e3ee1b0b5dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -241,19 +241,20 @@ static int mes_userq_detect_and_reset(struct amdgpu_device *adev, if (queue->doorbell_index == db_array[i]) { queue->state = AMDGPU_USERQ_STATE_HUNG; - if (queue->userq_mgr && - queue->userq_mgr->eventfd_mgr) - amdgpu_eventfd_signal( - queue->userq_mgr->eventfd_mgr, - DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET, - queue->qid); - - if (queue->userq_mgr && - queue->userq_mgr->wait_event_mgr) - amdgpu_wait_event_push_queue_reset( - queue->userq_mgr->wait_event_mgr, - queue->qid, - 0, 0, 0); + if (queue->userq_mgr && queue->userq_mgr->file) { + struct amdgpu_fpriv *fpriv = + queue->userq_mgr->file->driver_priv; + struct drm_amdgpu_wait_event_data data = {}; + + data.event_type = DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET; + data.queue_id = queue->qid; + data.u.reset.queue_id = queue->qid; + data.u.reset.reset_cause = 0; + data.u.reset.data0 = 0; + data.u.reset.data1 = 0; + + amdgpu_debug_event_route(fpriv, &data); + } found_hung_queue = true; atomic_inc(&adev->gpu_reset_counter); -- 2.34.1
