drm/xe: Simplify GuC early initialization

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>
This commit is contained in:
Maarten Lankhorst 2025-06-19 12:49:02 +02:00
parent b3412d7233
commit 396044c9d8
7 changed files with 70 additions and 30 deletions

View 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)

View 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:

View 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);

View 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() */

View 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);

View 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;

View 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);