Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/xe: Suballocate BO for page reclaim

Page reclamation feature needs the PRL to be suballocated into a
GGTT-mapped BO. On allocation failure, fallback to default tlb
invalidation with full PPC flush.

PRL's BO allocation is managed in separate pool to ensure 4K alignment
for proper GGTT address.

With BO, pass into TLB invalidation backend and modify fence to
accomadate accordingly.

v2:
- Removed page reclaim related variables from TLB fence. (Matthew B)
- Allocate PRL bo size to num_entries. (Matthew B)
- Move PRL bo allocation to tlb_inval run_job. (Matthew B)

v5:
- Use xe_page_reclaim_list_valid. (Matthew B)

Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20251212213225.3564537-18-brian3.nguyen@intel.com

authored by

Brian Nguyen and committed by
Matthew Brost
2b192beb b912138d

+66
+7
drivers/gpu/drm/xe/xe_device_types.h
··· 185 185 * Media GT shares a pool with its primary GT. 186 186 */ 187 187 struct xe_sa_manager *kernel_bb_pool; 188 + 189 + /** 190 + * @mem.reclaim_pool: Pool for PRLs allocated. 191 + * 192 + * Only main GT has page reclaim list allocations. 193 + */ 194 + struct xe_sa_manager *reclaim_pool; 188 195 } mem; 189 196 190 197 /** @sriov: tile level virtualization data */
+39
drivers/gpu/drm/xe/xe_page_reclaim.c
··· 13 13 #include "regs/xe_gt_regs.h" 14 14 #include "xe_assert.h" 15 15 #include "xe_macros.h" 16 + #include "xe_sa.h" 17 + #include "xe_tlb_inval_types.h" 18 + 19 + /** 20 + * xe_page_reclaim_create_prl_bo() - Back a PRL with a suballocated GGTT BO 21 + * @tlb_inval: TLB invalidation frontend associated with the request 22 + * @prl: page reclaim list data that bo will copy from 23 + * @fence: tlb invalidation fence that page reclaim action is paired to 24 + * 25 + * Suballocates a 4K BO out of the tile reclaim pool, copies the PRL CPU 26 + * copy into the BO and queues the buffer for release when @fence signals. 27 + * 28 + * Return: struct drm_suballoc pointer on success or ERR_PTR on failure. 29 + */ 30 + struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inval, 31 + struct xe_page_reclaim_list *prl, 32 + struct xe_tlb_inval_fence *fence) 33 + { 34 + struct xe_gt *gt = container_of(tlb_inval, struct xe_gt, tlb_inval); 35 + struct xe_tile *tile = gt_to_tile(gt); 36 + /* (+1) for NULL page_reclaim_entry to indicate end of list */ 37 + int prl_size = min(prl->num_entries + 1, XE_PAGE_RECLAIM_MAX_ENTRIES) * 38 + sizeof(struct xe_guc_page_reclaim_entry); 39 + struct drm_suballoc *prl_sa; 40 + 41 + /* Maximum size of PRL is 1 4K-page */ 42 + prl_sa = __xe_sa_bo_new(tile->mem.reclaim_pool, 43 + prl_size, GFP_ATOMIC); 44 + if (IS_ERR(prl_sa)) 45 + return prl_sa; 46 + 47 + memcpy(xe_sa_bo_cpu_addr(prl_sa), prl->entries, 48 + prl_size); 49 + xe_sa_bo_flush_write(prl_sa); 50 + /* Queue up sa_bo_free on tlb invalidation fence signal */ 51 + xe_sa_bo_free(prl_sa, &fence->base); 52 + 53 + return prl_sa; 54 + } 16 55 17 56 /** 18 57 * xe_page_reclaim_list_invalidate() - Mark a PRL as invalid
+6
drivers/gpu/drm/xe/xe_page_reclaim.h
··· 16 16 #define XE_PAGE_RECLAIM_MAX_ENTRIES 512 17 17 #define XE_PAGE_RECLAIM_LIST_MAX_SIZE SZ_4K 18 18 19 + struct xe_tlb_inval; 20 + struct xe_tlb_inval_fence; 21 + 19 22 struct xe_guc_page_reclaim_entry { 20 23 u64 qw; 21 24 /* valid reclaim entry bit */ ··· 68 65 prl->num_entries != XE_PAGE_RECLAIM_INVALID_LIST; 69 66 } 70 67 68 + struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inval, 69 + struct xe_page_reclaim_list *prl, 70 + struct xe_tlb_inval_fence *fence); 71 71 void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl); 72 72 void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl); 73 73 int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list *prl);
+5
drivers/gpu/drm/xe/xe_tile.c
··· 209 209 if (IS_ERR(tile->mem.kernel_bb_pool)) 210 210 return PTR_ERR(tile->mem.kernel_bb_pool); 211 211 212 + /* Optimistically anticipate at most 256 TLB fences with PRL */ 213 + tile->mem.reclaim_pool = xe_sa_bo_manager_init(tile, SZ_1M, XE_PAGE_RECLAIM_LIST_MAX_SIZE); 214 + if (IS_ERR(tile->mem.reclaim_pool)) 215 + return PTR_ERR(tile->mem.reclaim_pool); 216 + 212 217 return 0; 213 218 } 214 219 void xe_tile_migrate_wait(struct xe_tile *tile)
+9
drivers/gpu/drm/xe/xe_tlb_inval_job.c
··· 24 24 struct xe_exec_queue *q; 25 25 /** @vm: VM which TLB invalidation is being issued for */ 26 26 struct xe_vm *vm; 27 + /** @prl: Embedded copy of page reclaim list */ 28 + struct xe_page_reclaim_list prl; 27 29 /** @refcount: ref count of this job */ 28 30 struct kref refcount; 29 31 /** ··· 49 47 container_of(dep_job, typeof(*job), dep); 50 48 struct xe_tlb_inval_fence *ifence = 51 49 container_of(job->fence, typeof(*ifence), base); 50 + struct drm_suballoc *prl_sa = NULL; 51 + 52 + if (xe_page_reclaim_list_valid(&job->prl)) { 53 + prl_sa = xe_page_reclaim_create_prl_bo(job->tlb_inval, &job->prl, ifence); 54 + if (IS_ERR(prl_sa)) 55 + prl_sa = NULL; /* Indicate fall back PPC flush with NULL */ 56 + } 52 57 53 58 xe_tlb_inval_range(job->tlb_inval, ifence, job->start, 54 59 job->end, job->vm->usm.asid);