drm/i915/uc: Abort early on uc_init failure
Now that we can differentiate wants vs uses GuC/HuC, intel_uc_init is restricted to running only if we have successfully fetched the required blob(s) and are committed to using the microcontroller(s). The only remaining thing that can go wrong in uc_init is the allocation of GuC/HuC related objects; if we get such a failure better to bail out immediately instead of wedging later, like we do for e.g. intel_engines_init, since without objects we can't use the HW, including not being able to attempt the firmware load. While at it, remove the unneeded fw_cleanup call (this is handled outside of gt_init) and add a probe failure injection point for testing. Also, update the logs for <g/h>uc_init failures to probe_failure() since they will cause the driver load to fail. Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Fernando Pacheco <fernando.pacheco@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Andi Shyti <andi.shyti@intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20200218223327.11058-8-daniele.ceraolospurio@intel.com
This commit is contained in:
parent
202c98e716
commit
3acffa8cba
@ -592,7 +592,9 @@ int intel_gt_init(struct intel_gt *gt)
|
||||
if (err)
|
||||
goto err_engines;
|
||||
|
||||
intel_uc_init(>->uc);
|
||||
err = intel_uc_init(>->uc);
|
||||
if (err)
|
||||
goto err_engines;
|
||||
|
||||
err = intel_gt_resume(gt);
|
||||
if (err)
|
||||
|
@ -376,7 +376,7 @@ err_fw:
|
||||
intel_uc_fw_fini(&guc->fw);
|
||||
err_fetch:
|
||||
intel_uc_fw_cleanup_fetch(&guc->fw);
|
||||
DRM_DEV_DEBUG_DRIVER(gt->i915->drm.dev, "failed with %d\n", ret);
|
||||
i915_probe_error(gt->i915, "failed with %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ out_fini:
|
||||
intel_uc_fw_fini(&huc->fw);
|
||||
out:
|
||||
intel_uc_fw_cleanup_fetch(&huc->fw);
|
||||
DRM_DEV_DEBUG_DRIVER(i915->drm.dev, "failed with %d\n", err);
|
||||
i915_probe_error(i915, "failed with %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ static void __uc_cleanup_firmwares(struct intel_uc *uc)
|
||||
intel_uc_fw_cleanup_fetch(&uc->guc.fw);
|
||||
}
|
||||
|
||||
static void __uc_init(struct intel_uc *uc)
|
||||
static int __uc_init(struct intel_uc *uc)
|
||||
{
|
||||
struct intel_guc *guc = &uc->guc;
|
||||
struct intel_huc *huc = &uc->huc;
|
||||
@ -282,19 +282,29 @@ static void __uc_init(struct intel_uc *uc)
|
||||
GEM_BUG_ON(!intel_uc_wants_guc(uc));
|
||||
|
||||
if (!intel_uc_uses_guc(uc))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (i915_inject_probe_failure(uc_to_gt(uc)->i915))
|
||||
return -ENOMEM;
|
||||
|
||||
/* XXX: GuC submission is unavailable for now */
|
||||
GEM_BUG_ON(intel_uc_uses_guc_submission(uc));
|
||||
|
||||
ret = intel_guc_init(guc);
|
||||
if (ret) {
|
||||
intel_uc_fw_cleanup_fetch(&huc->fw);
|
||||
return;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (intel_uc_uses_huc(uc)) {
|
||||
ret = intel_huc_init(huc);
|
||||
if (ret)
|
||||
goto out_guc;
|
||||
}
|
||||
|
||||
if (intel_uc_uses_huc(uc))
|
||||
intel_huc_init(huc);
|
||||
return 0;
|
||||
|
||||
out_guc:
|
||||
intel_guc_fini(guc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __uc_fini(struct intel_uc *uc)
|
||||
|
@ -17,7 +17,7 @@ struct intel_uc_ops {
|
||||
int (*sanitize)(struct intel_uc *uc);
|
||||
void (*init_fw)(struct intel_uc *uc);
|
||||
void (*fini_fw)(struct intel_uc *uc);
|
||||
void (*init)(struct intel_uc *uc);
|
||||
int (*init)(struct intel_uc *uc);
|
||||
void (*fini)(struct intel_uc *uc);
|
||||
int (*init_hw)(struct intel_uc *uc);
|
||||
void (*fini_hw)(struct intel_uc *uc);
|
||||
@ -90,7 +90,7 @@ static inline _TYPE intel_uc_##_NAME(struct intel_uc *uc) \
|
||||
intel_uc_ops_function(sanitize, sanitize, int, 0);
|
||||
intel_uc_ops_function(fetch_firmwares, init_fw, void, );
|
||||
intel_uc_ops_function(cleanup_firmwares, fini_fw, void, );
|
||||
intel_uc_ops_function(init, init, void, );
|
||||
intel_uc_ops_function(init, init, int, 0);
|
||||
intel_uc_ops_function(fini, fini, void, );
|
||||
intel_uc_ops_function(init_hw, init_hw, int, 0);
|
||||
intel_uc_ops_function(fini_hw, fini_hw, void, );
|
||||
|
Loading…
x
Reference in New Issue
Block a user