]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe: Simplify GuC early initialization
authorMaarten Lankhorst <dev@lankhorst.se>
Thu, 19 Jun 2025 10:49:02 +0000 (12:49 +0200)
committerMaarten Lankhorst <dev@lankhorst.se>
Thu, 26 Jun 2025 20:10:30 +0000 (22:10 +0200)
Add a 2-stage GuC init. An early one for everything that is needed
for VF, and a full one that loads GuC and is allowed to do allocations.

Link: https://lore.kernel.org/r/20250619104858.418440-16-dev@lankhorst.se
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_guc.h
drivers/gpu/drm/xe/xe_guc_ct.c
drivers/gpu/drm/xe/xe_guc_ct.h
drivers/gpu/drm/xe/xe_uc.c
drivers/gpu/drm/xe/xe_uc.h

index 4370a4db95e051d683275dd024c7e9a7f5e51c74..6bc793043b400f0371aa5cc698bee95cc0677f60 100644 (file)
@@ -426,7 +426,7 @@ int xe_gt_init_early(struct xe_gt *gt)
         */
        xe_gt_mmio_init(gt);
 
-       return 0;
+       return xe_uc_init_noalloc(&gt->uc);
 }
 
 static void dump_pat_on_error(struct xe_gt *gt)
index 81b22b6fb2493ba363eb5890a79d729a64f67917..eeb23f8aa9de81732fe0698c3e27dbc040cbf4c0 100644 (file)
@@ -627,21 +627,11 @@ static int xe_guc_realloc_post_hwconfig(struct xe_guc *guc)
        return 0;
 }
 
-static int vf_guc_init(struct xe_guc *guc)
+static int vf_guc_init_noalloc(struct xe_guc *guc)
 {
        struct xe_gt *gt = guc_to_gt(guc);
        int err;
 
-       xe_guc_comm_init_early(guc);
-
-       err = xe_guc_ct_init(&guc->ct);
-       if (err)
-               return err;
-
-       err = xe_guc_relay_init(&guc->relay);
-       if (err)
-               return err;
-
        err = xe_gt_sriov_vf_bootstrap(gt);
        if (err)
                return err;
@@ -653,6 +643,35 @@ static int vf_guc_init(struct xe_guc *guc)
        return 0;
 }
 
+int xe_guc_init_noalloc(struct xe_guc *guc)
+{
+       struct xe_device *xe = guc_to_xe(guc);
+       struct xe_gt *gt = guc_to_gt(guc);
+       int ret;
+
+       xe_guc_comm_init_early(guc);
+
+       ret = xe_guc_ct_init_noalloc(&guc->ct);
+       if (ret)
+               goto out;
+
+       ret = xe_guc_relay_init(&guc->relay);
+       if (ret)
+               goto out;
+
+       if (IS_SRIOV_VF(xe)) {
+               ret = vf_guc_init_noalloc(guc);
+               if (ret)
+                       goto out;
+       }
+
+       return 0;
+
+out:
+       xe_gt_err(gt, "GuC init failed with %pe\n", ERR_PTR(ret));
+       return ret;
+}
+
 int xe_guc_init(struct xe_guc *guc)
 {
        struct xe_device *xe = guc_to_xe(guc);
@@ -662,13 +681,13 @@ int xe_guc_init(struct xe_guc *guc)
        guc->fw.type = XE_UC_FW_TYPE_GUC;
        ret = xe_uc_fw_init(&guc->fw);
        if (ret)
-               goto out;
+               return ret;
 
        if (!xe_uc_fw_is_enabled(&guc->fw))
                return 0;
 
        if (IS_SRIOV_VF(xe)) {
-               ret = vf_guc_init(guc);
+               ret = xe_guc_ct_init(&guc->ct);
                if (ret)
                        goto out;
                return 0;
@@ -690,10 +709,6 @@ int xe_guc_init(struct xe_guc *guc)
        if (ret)
                goto out;
 
-       ret = xe_guc_relay_init(&guc->relay);
-       if (ret)
-               goto out;
-
        xe_uc_fw_change_status(&guc->fw, XE_UC_FIRMWARE_LOADABLE);
 
        ret = devm_add_action_or_reset(xe->drm.dev, guc_fini_hw, guc);
@@ -702,8 +717,6 @@ int xe_guc_init(struct xe_guc *guc)
 
        guc_init_params(guc);
 
-       xe_guc_comm_init_early(guc);
-
        return 0;
 
 out:
index 58338be4455856994df1d7e026b3f0fa7cc03fe9..965bf72912009fef7c525ca33e6df2534d885579 100644 (file)
@@ -26,6 +26,7 @@
 struct drm_printer;
 
 void xe_guc_comm_init_early(struct xe_guc *guc);
+int xe_guc_init_noalloc(struct xe_guc *guc);
 int xe_guc_init(struct xe_guc *guc);
 int xe_guc_init_post_hwconfig(struct xe_guc *guc);
 int xe_guc_post_load_init(struct xe_guc *guc);
index bc4646964c4010b9f2fa70662b4edbbb40ac7239..209372e8f732fab22847c7bd20fb0986a785e1a0 100644 (file)
@@ -209,12 +209,10 @@ static void primelockdep(struct xe_guc_ct *ct)
        fs_reclaim_release(GFP_KERNEL);
 }
 
-int xe_guc_ct_init(struct xe_guc_ct *ct)
+int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct)
 {
        struct xe_device *xe = ct_to_xe(ct);
        struct xe_gt *gt = ct_to_gt(ct);
-       struct xe_tile *tile = gt_to_tile(gt);
-       struct xe_bo *bo;
        int err;
 
        xe_gt_assert(gt, !(guc_ct_size() % PAGE_SIZE));
@@ -240,6 +238,23 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
 
        primelockdep(ct);
 
+       err = drmm_add_action_or_reset(&xe->drm, guc_ct_fini, ct);
+       if (err)
+               return err;
+
+       xe_gt_assert(gt, ct->state == XE_GUC_CT_STATE_NOT_INITIALIZED);
+       ct->state = XE_GUC_CT_STATE_DISABLED;
+       return 0;
+}
+ALLOW_ERROR_INJECTION(xe_guc_ct_init_noalloc, ERRNO); /* See xe_pci_probe() */
+
+int xe_guc_ct_init(struct xe_guc_ct *ct)
+{
+       struct xe_device *xe = ct_to_xe(ct);
+       struct xe_gt *gt = ct_to_gt(ct);
+       struct xe_tile *tile = gt_to_tile(gt);
+       struct xe_bo *bo;
+
        bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
                                          XE_BO_FLAG_SYSTEM |
                                          XE_BO_FLAG_GGTT |
@@ -249,13 +264,6 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
                return PTR_ERR(bo);
 
        ct->bo = bo;
-
-       err = drmm_add_action_or_reset(&xe->drm, guc_ct_fini, ct);
-       if (err)
-               return err;
-
-       xe_gt_assert(gt, ct->state == XE_GUC_CT_STATE_NOT_INITIALIZED);
-       ct->state = XE_GUC_CT_STATE_DISABLED;
        return 0;
 }
 ALLOW_ERROR_INJECTION(xe_guc_ct_init, ERRNO); /* See xe_pci_probe() */
index 99c5dec446f2325ce820a0519866f2dfee2efbfa..18d4225e65024cc942311d4c773252dd05f311de 100644 (file)
@@ -11,6 +11,7 @@
 struct drm_printer;
 struct xe_device;
 
+int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct);
 int xe_guc_ct_init(struct xe_guc_ct *ct);
 int xe_guc_ct_enable(struct xe_guc_ct *ct);
 void xe_guc_ct_disable(struct xe_guc_ct *ct);
index 3a8751a8b92ddefd91d9948cc8cbfa7cc6dd3301..5badba6f85fa5221271694360aa7bb6d691e13dd 100644 (file)
@@ -33,6 +33,22 @@ uc_to_xe(struct xe_uc *uc)
 }
 
 /* Should be called once at driver load only */
+int xe_uc_init_noalloc(struct xe_uc *uc)
+{
+       int ret;
+
+       ret = xe_guc_init_noalloc(&uc->guc);
+       if (ret)
+               goto err;
+
+       /* HuC and GSC have no early dependencies and will be initialized during xe_uc_init(). */
+       return 0;
+
+err:
+       xe_gt_err(uc_to_gt(uc), "Failed to early initialize uC (%pe)\n", ERR_PTR(ret));
+       return ret;
+}
+
 int xe_uc_init(struct xe_uc *uc)
 {
        int ret;
index c23e6f5e2514174a83b2a6a8119f53f8099ec25a..b573b7731f62eb9c198340744c4d960800962f0a 100644 (file)
@@ -8,6 +8,7 @@
 
 struct xe_uc;
 
+int xe_uc_init_noalloc(struct xe_uc *uc);
 int xe_uc_init(struct xe_uc *uc);
 int xe_uc_init_hwconfig(struct xe_uc *uc);
 int xe_uc_init_post_hwconfig(struct xe_uc *uc);