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

drm/xe: Set LRC addresses before guc load

The metadata saved in the ADS is read by GuC when it's initialized.
Saving the addresses to the LRCs when they are populated is too late as
GuC will keep using the old ones.

This was causing GuC to use the RCS LRC for any engine class. It's not a
big problem on a Linux-only scenario since the they are used by GuC only
on media engines when the watchdog is triggered. However, in a
virtualization scenario with Windows as the VF, it causes the wrong LRCs
to be loaded as the watchdog is used for all engines.

Fix it by letting guc_golden_lrc_init() initialize the metadata, like
other *_init() functions, and later guc_golden_lrc_populate() to copy
the LRCs to the right places. The former is called before the second GuC
load, while the latter is called after LRCs have been recorded.

Cc: Chee Yin Wong <chee.yin.wong@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: <stable@vger.kernel.org> # v6.11+
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Tested-by: Chee Yin Wong <chee.yin.wong@intel.com>
Link: https://lore.kernel.org/r/20250409-fix-guc-ads-v1-1-494135f7a5d0@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>

+45 -30
+45 -30
drivers/gpu/drm/xe/xe_guc_ads.c
··· 496 496 engine_enable_mask(gt, XE_ENGINE_CLASS_OTHER)); 497 497 } 498 498 499 - static void guc_prep_golden_lrc_null(struct xe_guc_ads *ads) 499 + /* 500 + * Write the offsets corresponding to the golden LRCs. The actual data is 501 + * populated later by guc_golden_lrc_populate() 502 + */ 503 + static void guc_golden_lrc_init(struct xe_guc_ads *ads) 500 504 { 501 505 struct xe_device *xe = ads_to_xe(ads); 506 + struct xe_gt *gt = ads_to_gt(ads); 502 507 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads), 503 508 offsetof(struct __guc_ads_blob, system_info)); 504 - u8 guc_class; 509 + size_t alloc_size, real_size; 510 + u32 addr_ggtt, offset; 511 + int class; 505 512 506 - for (guc_class = 0; guc_class <= GUC_MAX_ENGINE_CLASSES; ++guc_class) { 513 + offset = guc_ads_golden_lrc_offset(ads); 514 + addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset; 515 + 516 + for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) { 517 + u8 guc_class; 518 + 519 + guc_class = xe_engine_class_to_guc_class(class); 520 + 507 521 if (!info_map_read(xe, &info_map, 508 522 engine_enabled_masks[guc_class])) 509 523 continue; 510 524 525 + real_size = xe_gt_lrc_size(gt, class); 526 + alloc_size = PAGE_ALIGN(real_size); 527 + 528 + /* 529 + * This interface is slightly confusing. We need to pass the 530 + * base address of the full golden context and the size of just 531 + * the engine state, which is the section of the context image 532 + * that starts after the execlists LRC registers. This is 533 + * required to allow the GuC to restore just the engine state 534 + * when a watchdog reset occurs. 535 + * We calculate the engine state size by removing the size of 536 + * what comes before it in the context image (which is identical 537 + * on all engines). 538 + */ 511 539 ads_blob_write(ads, ads.eng_state_size[guc_class], 512 - guc_ads_golden_lrc_size(ads) - 513 - xe_lrc_skip_size(xe)); 540 + real_size - xe_lrc_skip_size(xe)); 514 541 ads_blob_write(ads, ads.golden_context_lrca[guc_class], 515 - xe_bo_ggtt_addr(ads->bo) + 516 - guc_ads_golden_lrc_offset(ads)); 542 + addr_ggtt); 543 + 544 + addr_ggtt += alloc_size; 517 545 } 518 546 } 519 547 ··· 891 863 892 864 xe_map_memset(ads_to_xe(ads), ads_to_map(ads), 0, 0, ads->bo->size); 893 865 guc_policies_init(ads); 894 - guc_prep_golden_lrc_null(ads); 866 + guc_golden_lrc_init(ads); 895 867 guc_mapping_table_init_invalid(gt, &info_map); 896 868 guc_doorbell_init(ads); 897 869 ··· 917 889 guc_policies_init(ads); 918 890 fill_engine_enable_masks(gt, &info_map); 919 891 guc_mmio_reg_state_init(ads); 920 - guc_prep_golden_lrc_null(ads); 892 + guc_golden_lrc_init(ads); 921 893 guc_mapping_table_init(gt, &info_map); 922 894 guc_capture_prep_lists(ads); 923 895 guc_doorbell_init(ads); ··· 937 909 guc_ads_private_data_offset(ads)); 938 910 } 939 911 940 - static void guc_populate_golden_lrc(struct xe_guc_ads *ads) 912 + /* 913 + * After the golden LRC's are recorded for each engine class by the first 914 + * submission, copy them to the ADS, as initialized earlier by 915 + * guc_golden_lrc_init(). 916 + */ 917 + static void guc_golden_lrc_populate(struct xe_guc_ads *ads) 941 918 { 942 919 struct xe_device *xe = ads_to_xe(ads); 943 920 struct xe_gt *gt = ads_to_gt(ads); 944 921 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads), 945 922 offsetof(struct __guc_ads_blob, system_info)); 946 923 size_t total_size = 0, alloc_size, real_size; 947 - u32 addr_ggtt, offset; 924 + u32 offset; 948 925 int class; 949 926 950 927 offset = guc_ads_golden_lrc_offset(ads); 951 - addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset; 952 928 953 929 for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) { 954 930 u8 guc_class; ··· 969 937 alloc_size = PAGE_ALIGN(real_size); 970 938 total_size += alloc_size; 971 939 972 - /* 973 - * This interface is slightly confusing. We need to pass the 974 - * base address of the full golden context and the size of just 975 - * the engine state, which is the section of the context image 976 - * that starts after the execlists LRC registers. This is 977 - * required to allow the GuC to restore just the engine state 978 - * when a watchdog reset occurs. 979 - * We calculate the engine state size by removing the size of 980 - * what comes before it in the context image (which is identical 981 - * on all engines). 982 - */ 983 - ads_blob_write(ads, ads.eng_state_size[guc_class], 984 - real_size - xe_lrc_skip_size(xe)); 985 - ads_blob_write(ads, ads.golden_context_lrca[guc_class], 986 - addr_ggtt); 987 - 988 940 xe_map_memcpy_to(xe, ads_to_map(ads), offset, 989 941 gt->default_lrc[class], real_size); 990 942 991 - addr_ggtt += alloc_size; 992 943 offset += alloc_size; 993 944 } 994 945 ··· 980 965 981 966 void xe_guc_ads_populate_post_load(struct xe_guc_ads *ads) 982 967 { 983 - guc_populate_golden_lrc(ads); 968 + guc_golden_lrc_populate(ads); 984 969 } 985 970 986 971 static int guc_ads_action_update_policies(struct xe_guc_ads *ads, u32 policy_offset)