From: Matthew Brost Date: Fri, 31 Oct 2025 16:54:13 +0000 (-0700) Subject: drm/xe: Implement xe_pagefault_handler X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=143aa16572c5508f95b2a78b1769b0c83bfee09c;p=thirdparty%2Fkernel%2Flinux.git drm/xe: Implement xe_pagefault_handler Enqueue (copy) the input struct xe_pagefault into a queue (i.e., into a memory buffer) and schedule a worker to service it. Signed-off-by: Matthew Brost Reviewed-by: Francois Dugast Tested-by: Francois Dugast Link: https://patch.msgid.link/20251031165416.2871503-5-matthew.brost@intel.com --- diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c index b1decad9b54cd..7b2ac01a558eb 100644 --- a/drivers/gpu/drm/xe/xe_pagefault.c +++ b/drivers/gpu/drm/xe/xe_pagefault.c @@ -3,6 +3,8 @@ * Copyright © 2025 Intel Corporation */ +#include + #include #include "xe_device.h" @@ -167,6 +169,14 @@ 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 @@ -179,6 +189,24 @@ void xe_pagefault_reset(struct xe_device *xe, struct xe_gt *gt) */ int xe_pagefault_handler(struct xe_device *xe, struct xe_pagefault *pf) { - /* TODO - implement */ - return 0; + struct xe_pagefault_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); + 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; + queue_work(xe->usm.pf_wq, &pf_queue->worker); + } else { + drm_warn(&xe->drm, + "PageFault Queue (%d) full, shouldn't be possible\n", + pf->consumer.asid % XE_PAGEFAULT_QUEUE_COUNT); + } + spin_unlock_irqrestore(&pf_queue->lock, flags); + + return full ? -ENOSPC : 0; }