[RFC 02/15] drm/xe/pagefault: Use xe_usm_queue helpers

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

Wire struct xe_pagefault into the generic xe_usm_queue infrastructure
introduced in the previous commit.

- Use struct xe_usm_queue directly in all pagefault function signatures
instead of keeping a xe_pagefault_queue alias; xe_device_types.h
already declares pf_queue[] as struct xe_usm_queue.
- Replace xe_pagefault_entry_size() function with XE_PF_ENTRY_SIZE macro
so the value is available at compile time.
- Remove xe_pagefault_queue_pop() and xe_pagefault_queue_full() wrappers;
call xe_usm_queue_pop(), xe_usm_queue_full(), and xe_usm_queue_push()
directly at every call site.

No behaviour change.

Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_device_types.h | 2 +-
drivers/gpu/drm/xe/xe_pagefault.c | 41 +++++--------------------
drivers/gpu/drm/xe/xe_pagefault_types.h | 27 ++--------------
3 files changed, 10 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 615218d775b1..b9231544e500 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -310,7 +310,7 @@ struct xe_device {
*/
#define XE_PAGEFAULT_QUEUE_COUNT 4
/** @usm.pf_queue: Page fault queues */
- struct xe_pagefault_queue pf_queue[XE_PAGEFAULT_QUEUE_COUNT];
+ struct xe_usm_queue pf_queue[XE_PAGEFAULT_QUEUE_COUNT];
#if IS_ENABLED(CONFIG_DRM_XE_PAGEMAP)
/** @usm.pagemap_shrinker: Shrinker for unused pagemaps */
struct drm_pagemap_shrinker *dpagemap_shrinker;
diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
index ea4857acf28d..67dd07927684 100644
--- a/drivers/gpu/drm/xe/xe_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_pagefault.c
@@ -204,23 +204,6 @@ static int xe_pagefault_service(struct xe_pagefault *pf)
return err;
}

-static bool xe_pagefault_queue_pop(struct xe_pagefault_queue *pf_queue,
- struct xe_pagefault *pf)
-{
- bool found_fault = false;
-
- spin_lock_irq(&pf_queue->lock);
- if (pf_queue->tail != pf_queue->head) {
- memcpy(pf, pf_queue->data + pf_queue->tail, sizeof(*pf));
- pf_queue->tail = (pf_queue->tail + xe_pagefault_entry_size()) %
- pf_queue->size;
- found_fault = true;
- }
- spin_unlock_irq(&pf_queue->lock);
-
- return found_fault;
-}
-
static void xe_pagefault_print(struct xe_pagefault *pf)
{
xe_gt_info(pf->gt, "\n\tASID: %d\n"
@@ -246,7 +229,7 @@ static void xe_pagefault_print(struct xe_pagefault *pf)

static void xe_pagefault_queue_work(struct work_struct *w)
{
- struct xe_pagefault_queue *pf_queue =
+ struct xe_usm_queue *pf_queue =
container_of(w, typeof(*pf_queue), worker);
struct xe_pagefault pf;
unsigned long threshold;
@@ -254,7 +237,7 @@ static void xe_pagefault_queue_work(struct work_struct *w)
#define USM_QUEUE_MAX_RUNTIME_MS 20
threshold = jiffies + msecs_to_jiffies(USM_QUEUE_MAX_RUNTIME_MS);

- while (xe_pagefault_queue_pop(pf_queue, &pf)) {
+ while (xe_usm_queue_pop(pf_queue, &pf, sizeof(struct xe_pagefault))) {
int err;

if (!pf.gt) /* Fault squashed during reset */
@@ -284,7 +267,7 @@ static void xe_pagefault_queue_work(struct work_struct *w)
}

static int xe_pagefault_queue_init(struct xe_device *xe,
- struct xe_pagefault_queue *pf_queue)
+ struct xe_usm_queue *pf_queue)
{
struct xe_gt *gt;
int total_num_eus = 0;
@@ -373,7 +356,7 @@ int xe_pagefault_init(struct xe_device *xe)
}

static void xe_pagefault_queue_reset(struct xe_device *xe, struct xe_gt *gt,
- struct xe_pagefault_queue *pf_queue)
+ struct xe_usm_queue *pf_queue)
{
u32 i;

@@ -410,14 +393,6 @@ void xe_pagefault_reset(struct xe_device *xe, struct xe_gt *gt)
xe_pagefault_queue_reset(xe, gt, xe->usm.pf_queue + i);
}

-static bool xe_pagefault_queue_full(struct xe_pagefault_queue *pf_queue)
-{
- lockdep_assert_held(&pf_queue->lock);
-
- return CIRC_SPACE(pf_queue->head, pf_queue->tail, pf_queue->size) <=
- xe_pagefault_entry_size();
-}
-
/**
* xe_pagefault_handler() - Page fault handler
* @xe: xe device instance
@@ -430,17 +405,15 @@ static bool xe_pagefault_queue_full(struct xe_pagefault_queue *pf_queue)
*/
int xe_pagefault_handler(struct xe_device *xe, struct xe_pagefault *pf)
{
- struct xe_pagefault_queue *pf_queue = xe->usm.pf_queue +
+ struct xe_usm_queue *pf_queue = xe->usm.pf_queue +
(pf->consumer.asid % XE_PAGEFAULT_QUEUE_COUNT);
unsigned long flags;
bool full;

spin_lock_irqsave(&pf_queue->lock, flags);
- full = xe_pagefault_queue_full(pf_queue);
+ full = xe_usm_queue_full(pf_queue, sizeof(struct xe_pagefault));
if (!full) {
- memcpy(pf_queue->data + pf_queue->head, pf, sizeof(*pf));
- pf_queue->head = (pf_queue->head + xe_pagefault_entry_size()) %
- pf_queue->size;
+ xe_usm_queue_push(pf_queue, pf, sizeof(struct xe_pagefault));
queue_work(xe->usm.pf_wq, &pf_queue->worker);
} else {
drm_warn(&xe->drm,
diff --git a/drivers/gpu/drm/xe/xe_pagefault_types.h b/drivers/gpu/drm/xe/xe_pagefault_types.h
index b3289219b1be..49359f643358 100644
--- a/drivers/gpu/drm/xe/xe_pagefault_types.h
+++ b/drivers/gpu/drm/xe/xe_pagefault_types.h
@@ -8,6 +8,8 @@

#include <linux/workqueue.h>

+#include "xe_usm_queue.h"
+
struct xe_gt;
struct xe_pagefault;

@@ -110,29 +112,4 @@ struct xe_pagefault {
u32 msg[XE_PAGEFAULT_PRODUCER_MSG_LEN_DW];
} producer;
};
-
-/**
- * struct xe_pagefault_queue: Xe pagefault queue (consumer)
- *
- * Used to capture all device page faults for deferred processing. Size this
- * queue to absorb the device’s worst-case number of outstanding faults.
- */
-struct xe_pagefault_queue {
- /**
- * @data: Data in queue containing struct xe_pagefault, protected by
- * @lock
- */
- void *data;
- /** @size: Size of queue in bytes */
- u32 size;
- /** @head: Head pointer in bytes, moved by producer, protected by @lock */
- u32 head;
- /** @tail: Tail pointer in bytes, moved by consumer, protected by @lock */
- u32 tail;
- /** @lock: protects page fault queue */
- spinlock_t lock;
- /** @worker: to process page faults */
- struct work_struct worker;
-};
-
#endif
--
2.34.1