[Intel-gfx] [PATCH v3 01/13] drm/i915/guc: Keep GuC interrupts enabled when using GuC
Sagar Arun Kamble
sagar.a.kamble at intel.com
Mon Mar 19 11:17:32 UTC 2018
On 3/19/2018 3:23 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.
>
> v2: Move guc_log_flush_irq_disable up to avoid movement in following
> patches (Sagar).
> v3: s/guc_log_flush_irq_*/guc_flush_log_msg_*, rebase after mass rename
>
> Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Cc: Sagar Arun Kamble <sagar.a.kamble at intel.com>
> Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
> Reviewed-by: Sagar Arun Kamble <sagar.a.kamble at intel.com> (v2)
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
> ---
> drivers/gpu/drm/i915/intel_guc.c | 25 ++++++++++---------------
> drivers/gpu/drm/i915/intel_guc.h | 2 ++
> drivers/gpu/drm/i915/intel_guc_log.c | 31 +++++++++++++++++++------------
> drivers/gpu/drm/i915/intel_uc.c | 14 +++++---------
> 4 files changed, 36 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
> index e70bf654d21e..3af603536b1b 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->log);
>
> mutex_init(&guc->send_mutex);
> + spin_lock_init(&guc->irq_lock);
> guc->send = intel_guc_send_nop;
> guc->notify = gen8_guc_raise_irq;
> }
> @@ -368,7 +369,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
> void intel_guc_to_host_event_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
> @@ -381,24 +382,18 @@ void intel_guc_to_host_event_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.
> - */
> }
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
> index cdb649a9a4cf..9a95d1518aa9 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -56,7 +56,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 1c2127bc3878..1e209fcf90e1 100644
> --- a/drivers/gpu/drm/i915/intel_guc_log.c
> +++ b/drivers/gpu/drm/i915/intel_guc_log.c
> @@ -73,6 +73,22 @@ static int guc_log_control(struct intel_guc *guc, bool enable, u32 verbosity)
> return intel_guc_send(guc, action, ARRAY_SIZE(action));
> }
>
> +static void guc_flush_log_msg_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_flush_log_msg_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);
> +}
> +
> static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
> {
> return container_of(log, struct intel_guc, log);
> @@ -709,12 +725,7 @@ int intel_guc_log_register(struct intel_guc_log *log)
> if (ret)
> goto err_runtime;
>
> - /* GuC logging is currently the only user of Guc2Host interrupts */
> - mutex_lock(&i915->drm.struct_mutex);
> - intel_runtime_pm_get(i915);
> - gen9_enable_guc_interrupts(i915);
> - intel_runtime_pm_put(i915);
> - mutex_unlock(&i915->drm.struct_mutex);
> + guc_flush_log_msg_enable(guc);
>
> return 0;
>
> @@ -733,6 +744,8 @@ void intel_guc_log_unregister(struct intel_guc_log *log)
> struct intel_guc *guc = log_to_guc(log);
> struct drm_i915_private *i915 = guc_to_i915(guc);
>
> + guc_flush_log_msg_disable(guc);
> +
> /*
> * Once logging is disabled, GuC won't generate logs & send an
> * interrupt. But there could be some data in the log buffer
> @@ -742,12 +755,6 @@ void intel_guc_log_unregister(struct intel_guc_log *log)
> guc_flush_logs(log);
>
> mutex_lock(&i915->drm.struct_mutex);
> -
> - /* GuC logging is currently the only user of Guc2Host interrupts */
> - intel_runtime_pm_get(i915);
> - gen9_disable_guc_interrupts(i915);
> - intel_runtime_pm_put(i915);
> -
> guc_log_runtime_destroy(log);
> mutex_unlock(&i915->drm.struct_mutex);
>
> diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
> index 104c03ae2742..765b86a53f19 100644
> --- a/drivers/gpu/drm/i915/intel_uc.c
> +++ b/drivers/gpu/drm/i915/intel_uc.c
> @@ -247,6 +247,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);
>
> @@ -261,6 +263,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;
> }
>
> @@ -413,12 +417,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",
> @@ -433,8 +434,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:
> @@ -464,9 +463,6 @@ 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);
> }
>
> int intel_uc_suspend(struct drm_i915_private *i915)
--
Thanks,
Sagar
More information about the Intel-gfx
mailing list