On Mon, 19 Mar 2018 10:53:36 +0100, Michał Winiarski <[email protected]> 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 <[email protected]>
Cc: Chris Wilson <[email protected]>
Cc: Daniele Ceraolo Spurio <[email protected]>
Cc: Sagar Arun Kamble <[email protected]>
Cc: Michal Wajdeczko <[email protected]>
Reviewed-by: Sagar Arun Kamble <[email protected]> (v2)
---
 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);

please try to init members in definition order,
and try to avoid putting inside other init groups
(here 'send' related members)

        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);
+}
+

hmm, these functions take "guc" and operate on "struct guc",
so why they are located in intel_guc_log.c ?

maybe better option would be to declare them as

intel_guc.h:

static inline void intel_guc_event_enable(struct intel_guc *guc, u32 mask)
{
        spin_lock_irq(&guc->irq_lock);
        guc->msg_enabled_mask |= mask;
        spin_unlock_irq(&guc->irq_lock);
}

intel_guc_log.c:

static void guc_log_enable_flush(struct intel_guc_log *log)
{
        intel_guc_event_enable(log_to_guc(log),
                        INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
                        INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
}

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to