drm/xe/guc: Allocate GuC data structures in system memory for initial load
authorMichał Winiarski <michal.winiarski@intel.com>
Mon, 19 Feb 2024 13:05:27 +0000 (14:05 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 20 Feb 2024 19:13:42 +0000 (14:13 -0500)
GuC load will need to happen at an earlier point in probe, where local
memory is not yet available. Use system memory for GuC data structures
used for initial "hwconfig" load, and realloc at a later,
"post-hwconfig" load if needed, when local memory is available.

Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240219130530.1406044-1-michal.winiarski@intel.com
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_bo.h
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_guc_ads.c
drivers/gpu/drm/xe/xe_guc_ct.c
drivers/gpu/drm/xe/xe_guc_hwconfig.c
drivers/gpu/drm/xe/xe_guc_log.c

index 9d7ad67..76dfaf1 100644 (file)
@@ -1612,6 +1612,38 @@ struct xe_bo *xe_managed_bo_create_from_data(struct xe_device *xe, struct xe_til
        return bo;
 }
 
+/**
+ * xe_managed_bo_reinit_in_vram
+ * @xe: xe device
+ * @tile: Tile where the new buffer will be created
+ * @src: Managed buffer object allocated in system memory
+ *
+ * Replace a managed src buffer object allocated in system memory with a new
+ * one allocated in vram, copying the data between them.
+ * Buffer object in VRAM is not going to have the same GGTT address, the caller
+ * is responsible for making sure that any old references to it are updated.
+ *
+ * Returns 0 for success, negative error code otherwise.
+ */
+int xe_managed_bo_reinit_in_vram(struct xe_device *xe, struct xe_tile *tile, struct xe_bo **src)
+{
+       struct xe_bo *bo;
+
+       xe_assert(xe, IS_DGFX(xe));
+       xe_assert(xe, !(*src)->vmap.is_iomem);
+
+       bo = xe_managed_bo_create_from_data(xe, tile, (*src)->vmap.vaddr, (*src)->size,
+                                           XE_BO_CREATE_VRAM_IF_DGFX(tile) |
+                                           XE_BO_CREATE_GGTT_BIT);
+       if (IS_ERR(bo))
+               return PTR_ERR(bo);
+
+       drmm_release_action(&xe->drm, __xe_bo_unpin_map_no_vm, *src);
+       *src = bo;
+
+       return 0;
+}
+
 /*
  * XXX: This is in the VM bind data path, likely should calculate this once and
  * store, with a recalculation if the BO is moved.
index 7e49e67..c59ad15 100644 (file)
@@ -129,6 +129,7 @@ struct xe_bo *xe_managed_bo_create_pin_map(struct xe_device *xe, struct xe_tile
                                           size_t size, u32 flags);
 struct xe_bo *xe_managed_bo_create_from_data(struct xe_device *xe, struct xe_tile *tile,
                                             const void *data, size_t size, u32 flags);
+int xe_managed_bo_reinit_in_vram(struct xe_device *xe, struct xe_tile *tile, struct xe_bo **src);
 
 int xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo,
                              u32 bo_flags);
index 868208a..8c10546 100644 (file)
@@ -272,6 +272,34 @@ void xe_guc_comm_init_early(struct xe_guc *guc)
                guc->notify_reg = GUC_HOST_INTERRUPT;
 }
 
+static int xe_guc_realloc_post_hwconfig(struct xe_guc *guc)
+{
+       struct xe_tile *tile = gt_to_tile(guc_to_gt(guc));
+       struct xe_device *xe = guc_to_xe(guc);
+       int ret;
+
+       if (!IS_DGFX(guc_to_xe(guc)))
+               return 0;
+
+       ret = xe_managed_bo_reinit_in_vram(xe, tile, &guc->fw.bo);
+       if (ret)
+               return ret;
+
+       ret = xe_managed_bo_reinit_in_vram(xe, tile, &guc->log.bo);
+       if (ret)
+               return ret;
+
+       ret = xe_managed_bo_reinit_in_vram(xe, tile, &guc->ads.bo);
+       if (ret)
+               return ret;
+
+       ret = xe_managed_bo_reinit_in_vram(xe, tile, &guc->ct.bo);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 int xe_guc_init(struct xe_guc *guc)
 {
        struct xe_device *xe = guc_to_xe(guc);
@@ -331,6 +359,12 @@ out:
  */
 int xe_guc_init_post_hwconfig(struct xe_guc *guc)
 {
+       int ret;
+
+       ret = xe_guc_realloc_post_hwconfig(guc);
+       if (ret)
+               return ret;
+
        guc_init_params_post_hwconfig(guc);
 
        return xe_guc_ads_init_post_hwconfig(&guc->ads);
index 390e6f1..6ad4c1a 100644 (file)
@@ -273,7 +273,7 @@ int xe_guc_ads_init(struct xe_guc_ads *ads)
        ads->regset_size = calculate_regset_size(gt);
 
        bo = xe_managed_bo_create_pin_map(xe, tile, guc_ads_size(ads) + MAX_GOLDEN_LRC_SIZE,
-                                         XE_BO_CREATE_VRAM_IF_DGFX(tile) |
+                                         XE_BO_CREATE_SYSTEM_BIT |
                                          XE_BO_CREATE_GGTT_BIT);
        if (IS_ERR(bo))
                return PTR_ERR(bo);
index f3d3563..355edd4 100644 (file)
@@ -155,7 +155,7 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
        primelockdep(ct);
 
        bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
-                                         XE_BO_CREATE_VRAM_IF_DGFX(tile) |
+                                         XE_BO_CREATE_SYSTEM_BIT |
                                          XE_BO_CREATE_GGTT_BIT);
        if (IS_ERR(bo))
                return PTR_ERR(bo);
index 2a13a00..ea49f38 100644 (file)
@@ -78,7 +78,7 @@ int xe_guc_hwconfig_init(struct xe_guc *guc)
                return -EINVAL;
 
        bo = xe_managed_bo_create_pin_map(xe, tile, PAGE_ALIGN(size),
-                                         XE_BO_CREATE_VRAM_IF_DGFX(tile) |
+                                         XE_BO_CREATE_SYSTEM_BIT |
                                          XE_BO_CREATE_GGTT_BIT);
        if (IS_ERR(bo))
                return PTR_ERR(bo);
index bcd2f4d..45135c3 100644 (file)
@@ -84,7 +84,7 @@ int xe_guc_log_init(struct xe_guc_log *log)
        struct xe_bo *bo;
 
        bo = xe_managed_bo_create_pin_map(xe, tile, guc_log_size(),
-                                         XE_BO_CREATE_VRAM_IF_DGFX(tile) |
+                                         XE_BO_CREATE_SYSTEM_BIT |
                                          XE_BO_CREATE_GGTT_BIT);
        if (IS_ERR(bo))
                return PTR_ERR(bo);