Skip to content

Commit 6405f5b

Browse files
committed
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: dd08ebf ("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> (cherry picked from commit c31a0b6) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
1 parent 8ffd015 commit 6405f5b

File tree

1 file changed

+45
-30
lines changed

1 file changed

+45
-30
lines changed

drivers/gpu/drm/xe/xe_guc_ads.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -490,24 +490,52 @@ static void fill_engine_enable_masks(struct xe_gt *gt,
490490
engine_enable_mask(gt, XE_ENGINE_CLASS_OTHER));
491491
}
492492

493-
static void guc_prep_golden_lrc_null(struct xe_guc_ads *ads)
493+
/*
494+
* Write the offsets corresponding to the golden LRCs. The actual data is
495+
* populated later by guc_golden_lrc_populate()
496+
*/
497+
static void guc_golden_lrc_init(struct xe_guc_ads *ads)
494498
{
495499
struct xe_device *xe = ads_to_xe(ads);
500+
struct xe_gt *gt = ads_to_gt(ads);
496501
struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),
497502
offsetof(struct __guc_ads_blob, system_info));
498-
u8 guc_class;
503+
size_t alloc_size, real_size;
504+
u32 addr_ggtt, offset;
505+
int class;
506+
507+
offset = guc_ads_golden_lrc_offset(ads);
508+
addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset;
509+
510+
for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) {
511+
u8 guc_class;
512+
513+
guc_class = xe_engine_class_to_guc_class(class);
499514

500-
for (guc_class = 0; guc_class <= GUC_MAX_ENGINE_CLASSES; ++guc_class) {
501515
if (!info_map_read(xe, &info_map,
502516
engine_enabled_masks[guc_class]))
503517
continue;
504518

519+
real_size = xe_gt_lrc_size(gt, class);
520+
alloc_size = PAGE_ALIGN(real_size);
521+
522+
/*
523+
* This interface is slightly confusing. We need to pass the
524+
* base address of the full golden context and the size of just
525+
* the engine state, which is the section of the context image
526+
* that starts after the execlists LRC registers. This is
527+
* required to allow the GuC to restore just the engine state
528+
* when a watchdog reset occurs.
529+
* We calculate the engine state size by removing the size of
530+
* what comes before it in the context image (which is identical
531+
* on all engines).
532+
*/
505533
ads_blob_write(ads, ads.eng_state_size[guc_class],
506-
guc_ads_golden_lrc_size(ads) -
507-
xe_lrc_skip_size(xe));
534+
real_size - xe_lrc_skip_size(xe));
508535
ads_blob_write(ads, ads.golden_context_lrca[guc_class],
509-
xe_bo_ggtt_addr(ads->bo) +
510-
guc_ads_golden_lrc_offset(ads));
536+
addr_ggtt);
537+
538+
addr_ggtt += alloc_size;
511539
}
512540
}
513541

@@ -857,7 +885,7 @@ void xe_guc_ads_populate_minimal(struct xe_guc_ads *ads)
857885

858886
xe_map_memset(ads_to_xe(ads), ads_to_map(ads), 0, 0, ads->bo->size);
859887
guc_policies_init(ads);
860-
guc_prep_golden_lrc_null(ads);
888+
guc_golden_lrc_init(ads);
861889
guc_mapping_table_init_invalid(gt, &info_map);
862890
guc_doorbell_init(ads);
863891

@@ -883,7 +911,7 @@ void xe_guc_ads_populate(struct xe_guc_ads *ads)
883911
guc_policies_init(ads);
884912
fill_engine_enable_masks(gt, &info_map);
885913
guc_mmio_reg_state_init(ads);
886-
guc_prep_golden_lrc_null(ads);
914+
guc_golden_lrc_init(ads);
887915
guc_mapping_table_init(gt, &info_map);
888916
guc_capture_prep_lists(ads);
889917
guc_doorbell_init(ads);
@@ -903,18 +931,22 @@ void xe_guc_ads_populate(struct xe_guc_ads *ads)
903931
guc_ads_private_data_offset(ads));
904932
}
905933

906-
static void guc_populate_golden_lrc(struct xe_guc_ads *ads)
934+
/*
935+
* After the golden LRC's are recorded for each engine class by the first
936+
* submission, copy them to the ADS, as initialized earlier by
937+
* guc_golden_lrc_init().
938+
*/
939+
static void guc_golden_lrc_populate(struct xe_guc_ads *ads)
907940
{
908941
struct xe_device *xe = ads_to_xe(ads);
909942
struct xe_gt *gt = ads_to_gt(ads);
910943
struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),
911944
offsetof(struct __guc_ads_blob, system_info));
912945
size_t total_size = 0, alloc_size, real_size;
913-
u32 addr_ggtt, offset;
946+
u32 offset;
914947
int class;
915948

916949
offset = guc_ads_golden_lrc_offset(ads);
917-
addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset;
918950

919951
for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) {
920952
u8 guc_class;
@@ -931,26 +963,9 @@ static void guc_populate_golden_lrc(struct xe_guc_ads *ads)
931963
alloc_size = PAGE_ALIGN(real_size);
932964
total_size += alloc_size;
933965

934-
/*
935-
* This interface is slightly confusing. We need to pass the
936-
* base address of the full golden context and the size of just
937-
* the engine state, which is the section of the context image
938-
* that starts after the execlists LRC registers. This is
939-
* required to allow the GuC to restore just the engine state
940-
* when a watchdog reset occurs.
941-
* We calculate the engine state size by removing the size of
942-
* what comes before it in the context image (which is identical
943-
* on all engines).
944-
*/
945-
ads_blob_write(ads, ads.eng_state_size[guc_class],
946-
real_size - xe_lrc_skip_size(xe));
947-
ads_blob_write(ads, ads.golden_context_lrca[guc_class],
948-
addr_ggtt);
949-
950966
xe_map_memcpy_to(xe, ads_to_map(ads), offset,
951967
gt->default_lrc[class], real_size);
952968

953-
addr_ggtt += alloc_size;
954969
offset += alloc_size;
955970
}
956971

@@ -959,7 +974,7 @@ static void guc_populate_golden_lrc(struct xe_guc_ads *ads)
959974

960975
void xe_guc_ads_populate_post_load(struct xe_guc_ads *ads)
961976
{
962-
guc_populate_golden_lrc(ads);
977+
guc_golden_lrc_populate(ads);
963978
}
964979

965980
static int guc_ads_action_update_policies(struct xe_guc_ads *ads, u32 policy_offset)

0 commit comments

Comments
 (0)