Add a minimal producer for the render-node eventfd subscription mechanism by signaling a fixed event_id on GFX11 MES/userq EOP interrupts.
To reach the correct per-file registry from the IRQ path, plumb the originating drm_file's fpriv into the userq fence driver, and in the EOP IRQ handler walk: doorbell_offset -> fence_drv -> fence_drv->fpriv -> eventfd_xa[event_id] Cc: Harish Kasiviswanathan <[email protected]> Cc: Felix Kuehling <[email protected]> Cc: Alex Deucher <[email protected]> Cc: Christian König <[email protected]> Signed-off-by: Srinivasan Shanmugam <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index b700c2b91465..a3a38efdc3aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -820,7 +820,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) queue->doorbell_index = index; xa_init_flags(&queue->fence_drv_xa, XA_FLAGS_ALLOC); - r = amdgpu_userq_fence_driver_alloc(adev, queue); + r = amdgpu_userq_fence_driver_alloc(adev, fpriv, queue); if (r) { drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n"); goto unlock; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 212056d4ddf0..507defcfabd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -76,6 +76,7 @@ amdgpu_userq_fence_write(struct amdgpu_userq_fence_driver *fence_drv, } int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev, + struct amdgpu_fpriv *fpriv, struct amdgpu_usermode_queue *userq) { struct amdgpu_userq_fence_driver *fence_drv; @@ -102,6 +103,8 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev, fence_drv->context = dma_fence_context_alloc(1); get_task_comm(fence_drv->timeline_name, current); + fence_drv->fpriv = fpriv; + xa_lock_irqsave(&adev->userq_xa, flags); r = xa_err(__xa_store(&adev->userq_xa, userq->doorbell_index, fence_drv, GFP_KERNEL)); @@ -192,6 +195,8 @@ void amdgpu_userq_fence_driver_destroy(struct kref *ref) unsigned long index, flags; struct dma_fence *f; + WRITE_ONCE(fence_drv->fpriv, NULL); + spin_lock_irqsave(&fence_drv->fence_list_lock, flags); list_for_each_entry_safe(fence, tmp, &fence_drv->fences, link) { f = &fence->base; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h index d76add2afc77..8fa444a07f77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h @@ -42,6 +42,8 @@ struct amdgpu_userq_fence { struct amdgpu_userq_fence_driver **fence_drv_array; }; +struct amdgpu_fpriv; + struct amdgpu_userq_fence_driver { struct kref refcount; u64 va; @@ -56,6 +58,7 @@ struct amdgpu_userq_fence_driver { struct list_head fences; struct amdgpu_device *adev; char timeline_name[TASK_COMM_LEN]; + struct amdgpu_fpriv *fpriv; }; int amdgpu_userq_fence_slab_init(void); @@ -64,6 +67,7 @@ void amdgpu_userq_fence_slab_fini(void); void amdgpu_userq_fence_driver_get(struct amdgpu_userq_fence_driver *fence_drv); void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver *fence_drv); int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev, + struct amdgpu_fpriv *fpriv, struct amdgpu_usermode_queue *userq); void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq); void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index b1a1b8a10a08..b06adeeeed2a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -54,6 +54,8 @@ #define GFX11_NUM_GFX_RINGS 1 #define GFX11_MEC_HPD_SIZE 2048 +#define AMDGPU_EVENT_ID_USERQ_EOP 1 + #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1 0x1388 @@ -6489,6 +6491,7 @@ static int gfx_v11_0_eop_irq(struct amdgpu_device *adev, if (adev->enable_mes && doorbell_offset) { struct amdgpu_userq_fence_driver *fence_drv = NULL; + struct amdgpu_fpriv *fpriv = NULL; struct xarray *xa = &adev->userq_xa; unsigned long flags; @@ -6496,7 +6499,18 @@ static int gfx_v11_0_eop_irq(struct amdgpu_device *adev, fence_drv = xa_load(xa, doorbell_offset); if (fence_drv) amdgpu_userq_fence_driver_process(fence_drv); + /* + * Read fpriv while fence_drv is still guaranteed alive under xa_lock. + * fence_drv->fpriv is cleared during teardown. + */ + fpriv = fence_drv ? READ_ONCE(fence_drv->fpriv) : NULL; xa_unlock_irqrestore(xa, flags); + /* + * RFC: notify render-node eventfd subscribers for this drm_file. + * Mapping: doorbell_offset -> fence_drv -> fpriv -> eventfd_xa[event_id] + */ + if (fpriv) + amdgpu_eventfd_signal(fpriv, AMDGPU_EVENT_ID_USERQ_EOP, 1); } else { me_id = (entry->ring_id & 0x0c) >> 2; pipe_id = (entry->ring_id & 0x03) >> 0; -- 2.34.1
