[RFC 05/15] drm/xe: Implement xe_access_counter_handler

Himal Prasad Ghimiray
2026-03-18T07:10:24Z

Enqueue access counter notifications to the appropriate queue based on
ASID and schedule worker to process them.

Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_access_counter.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_access_counter.c b/drivers/gpu/drm/xe/xe_access_counter.c
index cafcc42897f8..a2ce9dc45d05 100644
--- a/drivers/gpu/drm/xe/xe_access_counter.c
+++ b/drivers/gpu/drm/xe/xe_access_counter.c
@@ -87,12 +87,29 @@ int xe_access_counter_init(struct xe_device *xe)
* @xe: xe device
* @ac: access counter notification
*
- * Process an access counter notification from the producer layer.
+ * Sink the access counter notification to a queue (i.e., a memory buffer) and
+ * queue a worker to service it.
*
* Return: 0 on success, negative error code on error
*/
int xe_access_counter_handler(struct xe_device *xe, struct xe_access_counter *ac)
{
- /* Stub implementation - to be filled in */
- return 0;
+ struct xe_usm_queue *ac_queue = xe->usm.ac_queue +
+ (ac->consumer.xe3.asid % XE_ACCESS_COUNTER_QUEUE_COUNT);
+ unsigned long flags;
+ bool full;
+
+ spin_lock_irqsave(&ac_queue->lock, flags);
+ full = xe_usm_queue_full(ac_queue, sizeof(struct xe_access_counter));
+ if (!full) {
+ xe_usm_queue_push(ac_queue, ac, xe_access_counter_entry_size());
+ queue_work(xe->usm.pf_wq, &ac_queue->worker);
+ } else {
+ drm_warn(&xe->drm,
+ "AccessCounter Queue (%d) full, shouldn't be possible\n",
+ ac->consumer.xe3.asid % XE_ACCESS_COUNTER_QUEUE_COUNT);
+ }
+ spin_unlock_irqrestore(&ac_queue->lock, flags);
+
+ return full ? -ENOSPC : 0;
}
--
2.34.1