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

drm/xe/pf: Increase PF GuC Buffer Cache size and use it for VF migration

Contiguous PF GGTT VMAs can be scarce after creating VFs.
Increase the GuC buffer cache size to 8M for PF so that we can fit GuC
migration data (which currently maxes out at just over 4M) and use the
cache instead of allocating fresh BOs.

Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20251112132220.516975-13-michal.winiarski@intel.com
Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>

+30 -33
+15 -32
drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
··· 11 11 #include "xe_gt_sriov_pf_helpers.h" 12 12 #include "xe_gt_sriov_pf_migration.h" 13 13 #include "xe_gt_sriov_printk.h" 14 - #include "xe_guc.h" 14 + #include "xe_guc_buf.h" 15 15 #include "xe_guc_ct.h" 16 16 #include "xe_sriov.h" 17 17 #include "xe_sriov_packet.h" ··· 58 58 59 59 /* Return: number of state dwords saved or a negative error code on failure */ 60 60 static int pf_send_guc_save_vf_state(struct xe_gt *gt, unsigned int vfid, 61 - void *buff, size_t size) 61 + void *dst, size_t size) 62 62 { 63 63 const int ndwords = size / sizeof(u32); 64 - struct xe_tile *tile = gt_to_tile(gt); 65 - struct xe_device *xe = tile_to_xe(tile); 66 64 struct xe_guc *guc = &gt->uc.guc; 67 - struct xe_bo *bo; 65 + CLASS(xe_guc_buf, buf)(&guc->buf, ndwords); 68 66 int ret; 69 67 70 68 xe_gt_assert(gt, size % sizeof(u32) == 0); 71 69 xe_gt_assert(gt, size == ndwords * sizeof(u32)); 72 70 73 - bo = xe_bo_create_pin_map_novm(xe, tile, 74 - ALIGN(size, PAGE_SIZE), 75 - ttm_bo_type_kernel, 76 - XE_BO_FLAG_SYSTEM | 77 - XE_BO_FLAG_GGTT | 78 - XE_BO_FLAG_GGTT_INVALIDATE, false); 79 - if (IS_ERR(bo)) 80 - return PTR_ERR(bo); 71 + if (!xe_guc_buf_is_valid(buf)) 72 + return -ENOBUFS; 73 + 74 + /* FW expects this buffer to be zero-initialized */ 75 + memset(xe_guc_buf_cpu_ptr(buf), 0, size); 81 76 82 77 ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_SAVE, 83 - xe_bo_ggtt_addr(bo), ndwords); 78 + xe_guc_buf_flush(buf), ndwords); 84 79 if (!ret) 85 80 ret = -ENODATA; 86 81 else if (ret > ndwords) 87 82 ret = -EPROTO; 88 83 else if (ret > 0) 89 - xe_map_memcpy_from(xe, buff, &bo->vmap, 0, ret * sizeof(u32)); 84 + memcpy(dst, xe_guc_buf_sync_read(buf), ret * sizeof(u32)); 90 85 91 - xe_bo_unpin_map_no_vm(bo); 92 86 return ret; 93 87 } 94 88 95 89 /* Return: number of state dwords restored or a negative error code on failure */ 96 90 static int pf_send_guc_restore_vf_state(struct xe_gt *gt, unsigned int vfid, 97 - const void *buff, size_t size) 91 + const void *src, size_t size) 98 92 { 99 93 const int ndwords = size / sizeof(u32); 100 - struct xe_tile *tile = gt_to_tile(gt); 101 - struct xe_device *xe = tile_to_xe(tile); 102 94 struct xe_guc *guc = &gt->uc.guc; 103 - struct xe_bo *bo; 95 + CLASS(xe_guc_buf_from_data, buf)(&guc->buf, src, size); 104 96 int ret; 105 97 106 98 xe_gt_assert(gt, size % sizeof(u32) == 0); 107 99 xe_gt_assert(gt, size == ndwords * sizeof(u32)); 108 100 109 - bo = xe_bo_create_pin_map_novm(xe, tile, 110 - ALIGN(size, PAGE_SIZE), 111 - ttm_bo_type_kernel, 112 - XE_BO_FLAG_SYSTEM | 113 - XE_BO_FLAG_GGTT | 114 - XE_BO_FLAG_GGTT_INVALIDATE, false); 115 - if (IS_ERR(bo)) 116 - return PTR_ERR(bo); 117 - 118 - xe_map_memcpy_to(xe, &bo->vmap, 0, buff, size); 101 + if (!xe_guc_buf_is_valid(buf)) 102 + return -ENOBUFS; 119 103 120 104 ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_RESTORE, 121 - xe_bo_ggtt_addr(bo), ndwords); 105 + xe_guc_buf_flush(buf), ndwords); 122 106 if (!ret) 123 107 ret = -ENODATA; 124 108 else if (ret > ndwords) 125 109 ret = -EPROTO; 126 110 127 - xe_bo_unpin_map_no_vm(bo); 128 111 return ret; 129 112 } 130 113
+3
drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h
··· 11 11 struct xe_gt; 12 12 struct xe_sriov_packet; 13 13 14 + /* TODO: get this information by querying GuC in the future */ 15 + #define XE_GT_SRIOV_PF_MIGRATION_GUC_DATA_MAX_SIZE SZ_8M 16 + 14 17 int xe_gt_sriov_pf_migration_init(struct xe_gt *gt); 15 18 int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid); 16 19 int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid);
+12 -1
drivers/gpu/drm/xe/xe_guc.c
··· 24 24 #include "xe_gt_printk.h" 25 25 #include "xe_gt_sriov_vf.h" 26 26 #include "xe_gt_throttle.h" 27 + #include "xe_gt_sriov_pf_migration.h" 27 28 #include "xe_guc_ads.h" 28 29 #include "xe_guc_buf.h" 29 30 #include "xe_guc_capture.h" ··· 41 40 #include "xe_mmio.h" 42 41 #include "xe_platform_types.h" 43 42 #include "xe_sriov.h" 43 + #include "xe_sriov_pf_migration.h" 44 44 #include "xe_uc.h" 45 45 #include "xe_uc_fw.h" 46 46 #include "xe_wa.h" ··· 823 821 return 0; 824 822 } 825 823 824 + static u32 guc_additional_cache_size(struct xe_device *xe) 825 + { 826 + if (IS_SRIOV_PF(xe) && xe_sriov_pf_migration_supported(xe)) 827 + return XE_GT_SRIOV_PF_MIGRATION_GUC_DATA_MAX_SIZE; 828 + else 829 + return 0; /* Fallback to default size */ 830 + } 831 + 826 832 /** 827 833 * xe_guc_init_post_hwconfig - initialize GuC post hwconfig load 828 834 * @guc: The GuC object ··· 870 860 if (ret) 871 861 return ret; 872 862 873 - ret = xe_guc_buf_cache_init(&guc->buf); 863 + ret = xe_guc_buf_cache_init_with_size(&guc->buf, 864 + guc_additional_cache_size(guc_to_xe(guc))); 874 865 if (ret) 875 866 return ret; 876 867