critical logging in GuC to enable capturing minimal important logs in production systems. i915.guc_log_level controls the verbosity and logging in GuC for logs other than critical logs. By default, logging in GuC is disabled through i915.guc_log_level. This patch introduces new kernel param i915.enable_guc_critical_logging. For Linux release builds, if needed critical GuC logs can be enabled separately through this parameter. GuC log snapshot captured in error state will have these minimal critical events logged. Default value for this parameter is currently set to false. This patch updates the initialization parameter sent during GuC load to disable critical logging unless i915.guc_log_level is set to enable logging and ensures it is enabled/disabling while enabling/disabling through debugfs based on i915.enable_guc_critical_logging. v2: Emulating GuC critical logging through i915.guc_log_level. Setting this to 0 will make GuC critical logging ON and setting it to 1-4 will communicate log level of 0-3 to GuC. Cc: Arkadiusz Hiler <arkadiusz.hiler@xxxxxxxxx> Cc: Spotswood John A <john.a.spotswood@xxxxxxxxx> Cc: Anusha Srivatsa <anusha.srivatsa@xxxxxxxxx> Signed-off-by: Jeff McGee <jeff.mcgee@xxxxxxxxx> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_params.c | 3 ++- drivers/gpu/drm/i915/intel_guc_fwif.h | 24 +++++++++++++++++++++--- drivers/gpu/drm/i915/intel_guc_loader.c | 31 +++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_guc_log.c | 26 +++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 8ab003d..38dd283 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -234,7 +234,8 @@ struct i915_params i915 __read_mostly = { module_param_named(guc_log_level, i915.guc_log_level, int, 0400); MODULE_PARM_DESC(guc_log_level, - "GuC firmware logging level (-1:disabled (default), 0-3:enabled)"); + "GuC firmware logging level (-1:disabled (default), " + "0: Critical Logging enabled, 1-4:Normal Logging enabled)"); module_param_named_unsafe(guc_firmware_path, i915.guc_firmware_path, charp, 0400); MODULE_PARM_DESC(guc_firmware_path, diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 5fa2860..0aac8e8 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -122,9 +122,15 @@ #define GUC_LOG_VERBOSITY_MED (1 << GUC_LOG_VERBOSITY_SHIFT) #define GUC_LOG_VERBOSITY_HIGH (2 << GUC_LOG_VERBOSITY_SHIFT) #define GUC_LOG_VERBOSITY_ULTRA (3 << GUC_LOG_VERBOSITY_SHIFT) -/* Verbosity range-check limits, without the shift */ +/* + * Verbosity range-check limits, without the shift. + * GuC log verbosity supported by firmware are 0 to 3. + * However, in order to treat the critical GuC logging similar to + * other logging levels we have incresed GuC verbosity levels by 1 + * with Level 0 corresponding to critical GuC logging. + */ #define GUC_LOG_VERBOSITY_MIN 0 -#define GUC_LOG_VERBOSITY_MAX 3 +#define GUC_LOG_VERBOSITY_MAX 4 #define GUC_LOG_VERBOSITY_MASK 0x0000000f #define GUC_LOG_DESTINATION_MASK (3 << 4) #define GUC_LOG_DISABLED (1 << 6) @@ -132,6 +138,7 @@ #define GUC_WQ_TRACK_ENABLED (1 << 8) #define GUC_ADS_ENABLED (1 << 9) #define GUC_DEBUG_RESERVED (1 << 10) +#define GUC_V9_CRITICAL_LOGGING_DISABLED (1 << 10) #define GUC_ADS_ADDR_SHIFT 11 #define GUC_ADS_ADDR_MASK 0xfffff800 @@ -139,6 +146,16 @@ #define GUC_CTL_MAX_DWORDS (SOFT_SCRATCH_COUNT - 2) /* [1..14] */ +/* + * Critical logging in GuC is to be enabled always from GuC v9+. + * (for KBL - v9.39+) + */ +#define NEEDS_GUC_CRITICAL_LOGGING(dev_priv, guc_fw) \ + (((IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) && \ + guc_fw->major_ver_found >= 9) || \ + (IS_KABYLAKE(dev_priv) && guc_fw->major_ver_found >= 9 && \ + guc_fw->minor_ver_found >= 39)) + /** * DOC: GuC Firmware Layout * @@ -539,7 +556,8 @@ struct guc_log_buffer_state { u32 logging_enabled:1; u32 reserved1:3; u32 verbosity:4; - u32 reserved2:24; + u32 critical_logging_enabled:1; + u32 reserved2:23; }; u32 value; } __packed; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 81e03a6..0b8d7b2 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -106,6 +106,8 @@ static u32 get_core_family(struct drm_i915_private *dev_priv) static void guc_params_init(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; + struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; + bool enable_critical_logging = false; u32 params[GUC_CTL_MAX_DWORDS]; int i; @@ -130,11 +132,32 @@ static void guc_params_init(struct drm_i915_private *dev_priv) params[GUC_CTL_LOG_PARAMS] = guc->log.flags; + params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; + + /* + * GuC has critical logging level which is currently not being enabled + * through other log level interfaces. We are emulating that by making + * i915.guc_log_level value 1 more than GuC's log level values to make + * value 0 correspond to GuC critical logging level. Once GuC fixes + * the implementation this needs to be updated. + */ if (i915.guc_log_level >= 0) { - params[GUC_CTL_DEBUG] = - i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; - } else - params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; + if (i915.guc_log_level >= 1) { + params[GUC_CTL_DEBUG] = (i915.guc_log_level-1) << + GUC_LOG_VERBOSITY_SHIFT; + params[GUC_CTL_DEBUG] &= ~GUC_LOG_DISABLED; + } + enable_critical_logging = true; + } + + if (NEEDS_GUC_CRITICAL_LOGGING(dev_priv, guc_fw)) { + if (enable_critical_logging) + params[GUC_CTL_DEBUG] &= + ~GUC_V9_CRITICAL_LOGGING_DISABLED; + else + params[GUC_CTL_DEBUG] |= + GUC_V9_CRITICAL_LOGGING_DISABLED; + } /* If GuC submission is enabled, set up additional parameters here */ if (i915.enable_guc_submission) { diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c index 16d3b87..2d467b0 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.c +++ b/drivers/gpu/drm/i915/intel_guc_log.c @@ -589,8 +589,8 @@ void intel_guc_log_destroy(struct intel_guc *guc) int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) { struct intel_guc *guc = &dev_priv->guc; - - union guc_log_control log_param; + struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; + union guc_log_control log_param, tmp; int ret; log_param.value = control_val; @@ -603,14 +603,34 @@ int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) if (!log_param.logging_enabled && (i915.guc_log_level < 0)) return 0; + if (NEEDS_GUC_CRITICAL_LOGGING(dev_priv, guc_fw)) { + tmp.value = log_param.value; + if (log_param.logging_enabled) { + log_param.critical_logging_enabled = 1; + if (log_param.verbosity == GUC_LOG_VERBOSITY_MIN) + log_param.logging_enabled = 0; + else + log_param.verbosity -= 1; + } + } + ret = guc_log_control(guc, log_param.value); if (ret < 0) { DRM_DEBUG_DRIVER("guc_logging_control action failed %d\n", ret); return ret; } + if (NEEDS_GUC_CRITICAL_LOGGING(dev_priv, guc_fw)) + log_param.logging_enabled = tmp.logging_enabled; + if (log_param.logging_enabled) { - i915.guc_log_level = log_param.verbosity; + if (NEEDS_GUC_CRITICAL_LOGGING(dev_priv, guc_fw)) { + if (tmp.verbosity == GUC_LOG_VERBOSITY_MIN) + i915.guc_log_level = 0; + else + i915.guc_log_level = log_param.verbosity + 1; + } else + i915.guc_log_level = log_param.verbosity; /* If log_level was set as -1 at boot time, then the relay channel file * wouldn't have been created by now and interrupts also would not have -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx