From 77ebc7c10d1607533cf7cf6c7a7b77105498d8b0 Mon Sep 17 00:00:00 2001 From: Brian Nguyen Date: Sat, 13 Dec 2025 05:32:30 +0800 Subject: [PATCH] drm/xe/guc: Add page reclamation interface to GuC Add page reclamation related changes to GuC interface, handlers, and senders to support page reclamation. Currently TLB invalidations will perform an entire PPC flush in order to prevent stale memory access for noncoherent system memory. Page reclamation is an extension of the typical TLB invalidation workflow, allowing disabling of full PPC flush and enable selective PPC flushing. Selective flushing will be decided by a list of pages whom's address is passed to GuC at time of action. Page reclamation interfaces require at least GuC FW ver 70.31.0. v2: - Moved send_page_reclaim to first patch usage. - Add comments explaining shared done handler. (Matthew B) - Add FW version fallback to disable page reclaim on older versions. (Matthew B, Shuicheng) Signed-off-by: Brian Nguyen Reviewed-by: Matthew Brost Reviewed-by: Shuicheng Lin Signed-off-by: Matthew Brost Link: https://patch.msgid.link/20251212213225.3564537-16-brian3.nguyen@intel.com --- drivers/gpu/drm/xe/abi/guc_actions_abi.h | 2 ++ drivers/gpu/drm/xe/xe_guc.c | 4 ++++ drivers/gpu/drm/xe/xe_guc_ct.c | 17 +++++++++++++++++ drivers/gpu/drm/xe/xe_guc_fwif.h | 1 + 4 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/xe/abi/guc_actions_abi.h b/drivers/gpu/drm/xe/abi/guc_actions_abi.h index 8af3691626bf..83a6e7794982 100644 --- a/drivers/gpu/drm/xe/abi/guc_actions_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_actions_abi.h @@ -155,6 +155,8 @@ enum xe_guc_action { XE_GUC_ACTION_TLB_INVALIDATION = 0x7000, XE_GUC_ACTION_TLB_INVALIDATION_DONE = 0x7001, XE_GUC_ACTION_TLB_INVALIDATION_ALL = 0x7002, + XE_GUC_ACTION_PAGE_RECLAMATION = 0x7003, + XE_GUC_ACTION_PAGE_RECLAMATION_DONE = 0x7004, XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002, XE_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003, XE_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004, diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index f0407bab9a0c..7daae3294665 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -767,6 +767,10 @@ int xe_guc_init(struct xe_guc *guc) if (!xe_uc_fw_is_enabled(&guc->fw)) return 0; + /* Disable page reclaim if GuC FW does not support */ + if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 31, 0)) + xe->info.has_page_reclaim_hw_assist = false; + if (IS_SRIOV_VF(xe)) { ret = xe_guc_ct_init(&guc->ct); if (ret) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 3e49e7fd0031..c3df9b3f1b4d 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -1406,6 +1406,7 @@ static int parse_g2h_event(struct xe_guc_ct *ct, u32 *msg, u32 len) case XE_GUC_ACTION_DEREGISTER_CONTEXT_DONE: case XE_GUC_ACTION_SCHED_ENGINE_MODE_DONE: case XE_GUC_ACTION_TLB_INVALIDATION_DONE: + case XE_GUC_ACTION_PAGE_RECLAMATION_DONE: g2h_release_space(ct, len); } @@ -1592,6 +1593,15 @@ static int process_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) ret = xe_guc_pagefault_handler(guc, payload, adj_len); break; case XE_GUC_ACTION_TLB_INVALIDATION_DONE: + case XE_GUC_ACTION_PAGE_RECLAMATION_DONE: + /* + * Page reclamation is an extension of TLB invalidation. Both + * operations share the same seqno and fence. When either + * action completes, we need to signal the corresponding + * fence. Since the handling logic (lookup fence by seqno, + * fence signalling) is identical, we use the same handler + * for both G2H events. + */ ret = xe_guc_tlb_inval_done_handler(guc, payload, adj_len); break; case XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF: @@ -1764,6 +1774,7 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path) switch (action) { case XE_GUC_ACTION_REPORT_PAGE_FAULT_REQ_DESC: case XE_GUC_ACTION_TLB_INVALIDATION_DONE: + case XE_GUC_ACTION_PAGE_RECLAMATION_DONE: break; /* Process these in fast-path */ default: return 0; @@ -1800,6 +1811,12 @@ static void g2h_fast_path(struct xe_guc_ct *ct, u32 *msg, u32 len) ret = xe_guc_pagefault_handler(guc, payload, adj_len); break; case XE_GUC_ACTION_TLB_INVALIDATION_DONE: + case XE_GUC_ACTION_PAGE_RECLAMATION_DONE: + /* + * Seqno and fence handling of page reclamation and TLB + * invalidation is identical, so we can use the same handler + * for both actions. + */ __g2h_release_space(ct, len); ret = xe_guc_tlb_inval_done_handler(guc, payload, adj_len); break; diff --git a/drivers/gpu/drm/xe/xe_guc_fwif.h b/drivers/gpu/drm/xe/xe_guc_fwif.h index e27f0088f24f..a04faec477ae 100644 --- a/drivers/gpu/drm/xe/xe_guc_fwif.h +++ b/drivers/gpu/drm/xe/xe_guc_fwif.h @@ -17,6 +17,7 @@ #define G2H_LEN_DW_TLB_INVALIDATE 3 #define G2H_LEN_DW_G2G_NOTIFY_MIN 3 #define G2H_LEN_DW_MULTI_QUEUE_CONTEXT 3 +#define G2H_LEN_DW_PAGE_RECLAMATION 3 #define GUC_ID_MAX 65535 #define GUC_ID_UNKNOWN 0xffffffff -- 2.47.3