Message ID | 20180227125230.13000-4-michal.winiarski@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 2/27/2018 6:22 PM, Michał Winiarski wrote: > The GuC log contains a separate space used for crash dump. > We even get a separate notification for it. While we're not handling > crash differently yet, it makes sense to decouple the two right now to > simplify the following patches. > > Signed-off-by: Michał Winiarski <michal.winiarski@intel.com> > Cc: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> > Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com> > Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com> > --- > drivers/gpu/drm/i915/intel_guc.c | 28 +++++++++++----------------- > drivers/gpu/drm/i915/intel_guc.h | 2 ++ > drivers/gpu/drm/i915/intel_guc_log.c | 29 ++++++++++++++++++----------- > drivers/gpu/drm/i915/intel_uc.c | 14 +++++--------- > 4 files changed, 36 insertions(+), 37 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c > index f622dd6009b6..41f2c3b3c482 100644 > --- a/drivers/gpu/drm/i915/intel_guc.c > +++ b/drivers/gpu/drm/i915/intel_guc.c > @@ -67,6 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc) > intel_guc_log_init_early(guc); > > mutex_init(&guc->send_mutex); > + spin_lock_init(&guc->irq_lock); > guc->send = intel_guc_send_nop; > guc->notify = gen8_guc_raise_irq; > } > @@ -367,7 +368,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) > void intel_guc_notification_handler(struct intel_guc *guc) > { > struct drm_i915_private *dev_priv = guc_to_i915(guc); > - u32 msg, flush; > + u32 msg, val; > > /* > * Sample the log buffer flush related bits & clear them out now > @@ -380,24 +381,18 @@ void intel_guc_notification_handler(struct intel_guc *guc) > * could happen that GuC sets the bit for 2nd interrupt but Host > * clears out the bit on handling the 1st interrupt. > */ > - > - msg = I915_READ(SOFT_SCRATCH(15)); > - flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | > - INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER); > - if (flush) { > - /* Clear the message bits that are handled */ > - I915_WRITE(SOFT_SCRATCH(15), msg & ~flush); > - > - /* Handle flush interrupt in bottom half */ > + spin_lock(&guc->irq_lock); > + val = I915_READ(SOFT_SCRATCH(15)); > + msg = val & guc->msg_enabled_mask; > + I915_WRITE(SOFT_SCRATCH(15), val & ~msg); > + spin_unlock(&guc->irq_lock); > + > + if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | > + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)) { > queue_work(guc->log.runtime.flush_wq, > &guc->log.runtime.flush_work); > > guc->log.flush_interrupt_count++; > - } else { > - /* > - * Not clearing of unhandled event bits won't result in > - * re-triggering of the interrupt. > - */ > } > } > > @@ -495,8 +490,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv) > if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) > return 0; > > - if (i915_modparams.guc_log_level) > - gen9_enable_guc_interrupts(dev_priv); > + gen9_enable_guc_interrupts(dev_priv); > > data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; > data[1] = GUC_POWER_D0; > diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h > index 5b905bae181d..d629bc5d5c0f 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -53,7 +53,9 @@ struct intel_guc { > struct drm_i915_gem_object *load_err_log; > > /* intel_guc_recv interrupt related state */ > + spinlock_t irq_lock; > bool interrupts_enabled; > + unsigned int msg_enabled_mask; > > struct i915_vma *ads_vma; > struct i915_vma *stage_desc_pool; > diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c > index f1cab43d334e..09be7340652b 100644 > --- a/drivers/gpu/drm/i915/intel_guc_log.c > +++ b/drivers/gpu/drm/i915/intel_guc_log.c > @@ -590,6 +590,22 @@ int intel_guc_log_create(struct intel_guc *guc) > return ret; > } > > +static void guc_log_flush_irq_enable(struct intel_guc *guc) > +{ > + spin_lock_irq(&guc->irq_lock); > + guc->msg_enabled_mask |= INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | > + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED; > + spin_unlock_irq(&guc->irq_lock); > +} > + > +static void guc_log_flush_irq_disable(struct intel_guc *guc) > +{ > + spin_lock_irq(&guc->irq_lock); > + guc->msg_enabled_mask &= ~(INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | > + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED); > + spin_unlock_irq(&guc->irq_lock); > +} > + > void intel_guc_log_destroy(struct intel_guc *guc) > { > guc_log_runtime_destroy(guc); > @@ -687,12 +703,7 @@ int intel_guc_log_register(struct intel_guc *guc) > if (ret) > goto err_runtime; > > - /* GuC logging is currently the only user of Guc2Host interrupts */ > - mutex_lock(&dev_priv->drm.struct_mutex); > - intel_runtime_pm_get(dev_priv); > - gen9_enable_guc_interrupts(dev_priv); > - intel_runtime_pm_put(dev_priv); > - mutex_unlock(&dev_priv->drm.struct_mutex); > + guc_log_flush_irq_enable(guc); > > return 0; > > @@ -717,13 +728,9 @@ void intel_guc_log_unregister(struct intel_guc *guc) > * buffer state and then collect the left over logs. > */ > guc_flush_logs(guc); > + guc_log_flush_irq_disable(guc); > > mutex_lock(&dev_priv->drm.struct_mutex); > - /* GuC logging is currently the only user of Guc2Host interrupts */ > - intel_runtime_pm_get(dev_priv); > - gen9_disable_guc_interrupts(dev_priv); > - intel_runtime_pm_put(dev_priv); > - > guc_log_runtime_destroy(guc); > mutex_unlock(&dev_priv->drm.struct_mutex); > > diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c > index 3f41ef525e26..e9aba3c35264 100644 > --- a/drivers/gpu/drm/i915/intel_uc.c > +++ b/drivers/gpu/drm/i915/intel_uc.c > @@ -239,6 +239,8 @@ static int guc_enable_communication(struct intel_guc *guc) > { > struct drm_i915_private *dev_priv = guc_to_i915(guc); > > + gen9_enable_guc_interrupts(dev_priv); > + > if (HAS_GUC_CT(dev_priv)) > return intel_guc_enable_ct(guc); > > @@ -253,6 +255,8 @@ static void guc_disable_communication(struct intel_guc *guc) > if (HAS_GUC_CT(dev_priv)) > intel_guc_disable_ct(guc); > > + gen9_disable_guc_interrupts(dev_priv); > + > guc->send = intel_guc_send_nop; > } > > @@ -391,12 +395,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) > } > > if (USES_GUC_SUBMISSION(dev_priv)) { > - if (i915_modparams.guc_log_level) > - gen9_enable_guc_interrupts(dev_priv); > - > ret = intel_guc_submission_enable(guc); > if (ret) > - goto err_interrupts; > + goto err_communication; > } > > dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n", > @@ -411,8 +412,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) > /* > * We've failed to load the firmware :( > */ > -err_interrupts: > - gen9_disable_guc_interrupts(dev_priv); > err_communication: > guc_disable_communication(guc); > err_log_capture: > @@ -442,7 +441,4 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) > intel_guc_submission_disable(guc); > > guc_disable_communication(guc); > - > - if (USES_GUC_SUBMISSION(dev_priv)) > - gen9_disable_guc_interrupts(dev_priv); > }
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index f622dd6009b6..41f2c3b3c482 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -67,6 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc) intel_guc_log_init_early(guc); mutex_init(&guc->send_mutex); + spin_lock_init(&guc->irq_lock); guc->send = intel_guc_send_nop; guc->notify = gen8_guc_raise_irq; } @@ -367,7 +368,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) void intel_guc_notification_handler(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - u32 msg, flush; + u32 msg, val; /* * Sample the log buffer flush related bits & clear them out now @@ -380,24 +381,18 @@ void intel_guc_notification_handler(struct intel_guc *guc) * could happen that GuC sets the bit for 2nd interrupt but Host * clears out the bit on handling the 1st interrupt. */ - - msg = I915_READ(SOFT_SCRATCH(15)); - flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | - INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER); - if (flush) { - /* Clear the message bits that are handled */ - I915_WRITE(SOFT_SCRATCH(15), msg & ~flush); - - /* Handle flush interrupt in bottom half */ + spin_lock(&guc->irq_lock); + val = I915_READ(SOFT_SCRATCH(15)); + msg = val & guc->msg_enabled_mask; + I915_WRITE(SOFT_SCRATCH(15), val & ~msg); + spin_unlock(&guc->irq_lock); + + if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)) { queue_work(guc->log.runtime.flush_wq, &guc->log.runtime.flush_work); guc->log.flush_interrupt_count++; - } else { - /* - * Not clearing of unhandled event bits won't result in - * re-triggering of the interrupt. - */ } } @@ -495,8 +490,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv) if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) return 0; - if (i915_modparams.guc_log_level) - gen9_enable_guc_interrupts(dev_priv); + gen9_enable_guc_interrupts(dev_priv); data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; data[1] = GUC_POWER_D0; diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 5b905bae181d..d629bc5d5c0f 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -53,7 +53,9 @@ struct intel_guc { struct drm_i915_gem_object *load_err_log; /* intel_guc_recv interrupt related state */ + spinlock_t irq_lock; bool interrupts_enabled; + unsigned int msg_enabled_mask; struct i915_vma *ads_vma; struct i915_vma *stage_desc_pool; diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c index f1cab43d334e..09be7340652b 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.c +++ b/drivers/gpu/drm/i915/intel_guc_log.c @@ -590,6 +590,22 @@ int intel_guc_log_create(struct intel_guc *guc) return ret; } +static void guc_log_flush_irq_enable(struct intel_guc *guc) +{ + spin_lock_irq(&guc->irq_lock); + guc->msg_enabled_mask |= INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED; + spin_unlock_irq(&guc->irq_lock); +} + +static void guc_log_flush_irq_disable(struct intel_guc *guc) +{ + spin_lock_irq(&guc->irq_lock); + guc->msg_enabled_mask &= ~(INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER | + INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED); + spin_unlock_irq(&guc->irq_lock); +} + void intel_guc_log_destroy(struct intel_guc *guc) { guc_log_runtime_destroy(guc); @@ -687,12 +703,7 @@ int intel_guc_log_register(struct intel_guc *guc) if (ret) goto err_runtime; - /* GuC logging is currently the only user of Guc2Host interrupts */ - mutex_lock(&dev_priv->drm.struct_mutex); - intel_runtime_pm_get(dev_priv); - gen9_enable_guc_interrupts(dev_priv); - intel_runtime_pm_put(dev_priv); - mutex_unlock(&dev_priv->drm.struct_mutex); + guc_log_flush_irq_enable(guc); return 0; @@ -717,13 +728,9 @@ void intel_guc_log_unregister(struct intel_guc *guc) * buffer state and then collect the left over logs. */ guc_flush_logs(guc); + guc_log_flush_irq_disable(guc); mutex_lock(&dev_priv->drm.struct_mutex); - /* GuC logging is currently the only user of Guc2Host interrupts */ - intel_runtime_pm_get(dev_priv); - gen9_disable_guc_interrupts(dev_priv); - intel_runtime_pm_put(dev_priv); - guc_log_runtime_destroy(guc); mutex_unlock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 3f41ef525e26..e9aba3c35264 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -239,6 +239,8 @@ static int guc_enable_communication(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); + gen9_enable_guc_interrupts(dev_priv); + if (HAS_GUC_CT(dev_priv)) return intel_guc_enable_ct(guc); @@ -253,6 +255,8 @@ static void guc_disable_communication(struct intel_guc *guc) if (HAS_GUC_CT(dev_priv)) intel_guc_disable_ct(guc); + gen9_disable_guc_interrupts(dev_priv); + guc->send = intel_guc_send_nop; } @@ -391,12 +395,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) } if (USES_GUC_SUBMISSION(dev_priv)) { - if (i915_modparams.guc_log_level) - gen9_enable_guc_interrupts(dev_priv); - ret = intel_guc_submission_enable(guc); if (ret) - goto err_interrupts; + goto err_communication; } dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n", @@ -411,8 +412,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) /* * We've failed to load the firmware :( */ -err_interrupts: - gen9_disable_guc_interrupts(dev_priv); err_communication: guc_disable_communication(guc); err_log_capture: @@ -442,7 +441,4 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) intel_guc_submission_disable(guc); guc_disable_communication(guc); - - if (USES_GUC_SUBMISSION(dev_priv)) - gen9_disable_guc_interrupts(dev_priv); }
The GuC log contains a separate space used for crash dump. We even get a separate notification for it. While we're not handling crash differently yet, it makes sense to decouple the two right now to simplify the following patches. Signed-off-by: Michał Winiarski <michal.winiarski@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> --- drivers/gpu/drm/i915/intel_guc.c | 28 +++++++++++----------------- drivers/gpu/drm/i915/intel_guc.h | 2 ++ drivers/gpu/drm/i915/intel_guc_log.c | 29 ++++++++++++++++++----------- drivers/gpu/drm/i915/intel_uc.c | 14 +++++--------- 4 files changed, 36 insertions(+), 37 deletions(-)