[Intel-gfx] [PATCH v2] drm/i915/tracing: Enable user interrupts while intel_engine_notify is active

Chris Wilson chris at chris-wilson.co.uk
Wed Aug 8 15:34:33 UTC 2018


Quoting Tvrtko Ursulin (2018-08-08 16:14:24)
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> 
> Keep the user interrupt enabled and emit intel_engine_notify tracepoint
> every time as long as it is enabled.
> 
> Premise is that if someone is listening, they want to see interrupts
> logged.
> 
> We use tracepoint (de)registration callbacks to enable user interrupts on
> all devices (future proofing and avoiding ugly global pointers) and all
> engines.
> 
> For this to work we also have to add another call site of
> trace_intel_engine_notify, notably to the early return from notify_ring
> otherwise we still depend on waiters being present.

That confused me. "We use... For this to work" I took as meaning we
needed the tracepoint in the irq to enable the user interrupts. But what
you meant was that we always want to fire the irq tracepoint when it is

being traced, irrespective of clients waiting.
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0b10a30b7d96..a15f8be0ece0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2141,6 +2141,8 @@ struct drm_i915_private {
>  
>         struct i915_pmu pmu;
>  
> +       struct list_head driver_list_link;

Nit: mostly we keep to _list being the list_head, and _link being the
node. Also link tends to indicate which list it is in, e.g
obj->vma_list and vma->obj_link -- but you'll be forgiven if that's
confusing and you have a better idea.

So i915_tracing_driver_list and tracing_link ?

> +
>         /*
>          * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
>          * will be rejected. Instead look for a better place.
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 8084e35b25c5..8cba798b666d 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1159,8 +1159,10 @@ static void notify_ring(struct intel_engine_cs *engine)
>         struct task_struct *tsk = NULL;
>         struct intel_wait *wait;
>  
> -       if (unlikely(!engine->breadcrumbs.irq_armed))
> +       if (unlikely(!engine->breadcrumbs.irq_armed)) {
> +               trace_intel_engine_notify(engine, false);
>                 return;
> +       }
>  
>         rcu_read_lock();
>  
> diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
> index c0352a1b036c..12555d2388fd 100644
> --- a/drivers/gpu/drm/i915/i915_trace.h
> +++ b/drivers/gpu/drm/i915/i915_trace.h
> @@ -8,6 +8,7 @@
>  
>  #include <drm/drmP.h>
>  #include "i915_drv.h"
> +#include "i915_tracing.h"
>  #include "intel_drv.h"
>  #include "intel_ringbuffer.h"
>  
> @@ -750,29 +751,32 @@ TRACE_EVENT(i915_request_out,
>                               __entry->global_seqno, __entry->completed)
>  );
>  
> -TRACE_EVENT(intel_engine_notify,
> -           TP_PROTO(struct intel_engine_cs *engine, bool waiters),
> -           TP_ARGS(engine, waiters),
> -
> -           TP_STRUCT__entry(
> -                            __field(u32, dev)
> -                            __field(u16, class)
> -                            __field(u16, instance)
> -                            __field(u32, seqno)
> -                            __field(bool, waiters)
> -                            ),
> -
> -           TP_fast_assign(
> -                          __entry->dev = engine->i915->drm.primary->index;
> -                          __entry->class = engine->uabi_class;
> -                          __entry->instance = engine->instance;
> -                          __entry->seqno = intel_engine_get_seqno(engine);
> -                          __entry->waiters = waiters;
> -                          ),
> -
> -           TP_printk("dev=%u, engine=%u:%u, seqno=%u, waiters=%u",
> -                     __entry->dev, __entry->class, __entry->instance,
> -                     __entry->seqno, __entry->waiters)
> +TRACE_EVENT_FN(intel_engine_notify,
> +              TP_PROTO(struct intel_engine_cs *engine, bool waiters),
> +              TP_ARGS(engine, waiters),
> +
> +              TP_STRUCT__entry(
> +                               __field(u32, dev)
> +                               __field(u16, class)
> +                               __field(u16, instance)
> +                               __field(u32, seqno)
> +                               __field(bool, waiters)
> +                               ),
> +
> +              TP_fast_assign(
> +                             __entry->dev = engine->i915->drm.primary->index;
> +                             __entry->class = engine->uabi_class;
> +                             __entry->instance = engine->instance;
> +                             __entry->seqno = intel_engine_get_seqno(engine);
> +                             __entry->waiters = waiters;
> +                             ),
> +
> +              TP_printk("dev=%u, engine=%u:%u, seqno=%u, waiters=%u",
> +                        __entry->dev, __entry->class, __entry->instance,
> +                        __entry->seqno, __entry->waiters),
> +
> +              intel_engine_notify_tracepoint_register,
> +              intel_engine_notify_tracepoint_unregister
>  );
>  
>  DEFINE_EVENT(i915_request, i915_request_retire,
> diff --git a/drivers/gpu/drm/i915/i915_tracing.c b/drivers/gpu/drm/i915/i915_tracing.c
> new file mode 100644
> index 000000000000..b7ca89fb61ce
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_tracing.c
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + */
> +
> +#include "i915_tracing.h"
> +
> +#include "i915_drv.h"
> +#include "intel_ringbuffer.h"
> +
> +static DEFINE_MUTEX(driver_list_lock);
> +static LIST_HEAD(driver_list);
> +static bool notify_enabled;
> +
> +static void __i915_enable_notify(struct drm_i915_private *i915)
> +{
> +       struct intel_engine_cs *engine;
> +       enum intel_engine_id id;
> +
> +       for_each_engine(engine, i915, id)
> +               intel_engine_pin_breadcrumbs_irq(engine);
> +}
> +
> +static void __i915_disable_notify(struct drm_i915_private *i915)
> +{
> +       struct intel_engine_cs *engine;
> +       enum intel_engine_id id;
> +
> +       for_each_engine(engine, i915, id)
> +               intel_engine_unpin_breadcrumbs_irq(engine);
> +}
> +
> +void i915_tracing_register(struct drm_i915_private *i915)
> +{
> +       INIT_LIST_HEAD(&i915->driver_list_link);
> +
> +       mutex_lock(&driver_list_lock);
> +
> +       list_add_tail(&i915->driver_list_link, &driver_list);
> +
> +       if (notify_enabled)
> +               __i915_enable_notify(i915);
> +
> +       mutex_unlock(&driver_list_lock);
> +}
> +
> +void i915_tracing_unregister(struct drm_i915_private *i915)
> +{
> +       mutex_lock(&driver_list_lock);
> +
> +       if (notify_enabled)
> +               __i915_disable_notify(i915);

The caller doesn't hold the rpm wakeref. I think it will be tidier to
push the rpm_get/rpm_put into
__i915_enable_notify/__i915_disable_notify.

> +
> +       list_del(&i915->driver_list_link);
> +
> +       mutex_unlock(&driver_list_lock);
> +}
> +
> +int intel_engine_notify_tracepoint_register(void)
> +{
> +       struct drm_i915_private *i915;
> +
> +       mutex_lock(&driver_list_lock);
> +
> +       GEM_BUG_ON(notify_enabled);
> +
> +       list_for_each_entry(i915, &driver_list, driver_list_link) {
> +               intel_runtime_pm_get(i915);
> +               __i915_enable_notify(i915);
> +               intel_runtime_pm_put(i915);
> +       }
> +
> +       notify_enabled = true;
> +
> +       mutex_unlock(&driver_list_lock);
> +
> +       return 0;
> +}
> +
> +void intel_engine_notify_tracepoint_unregister(void)
> +{
> +       struct drm_i915_private *i915;
> +
> +       mutex_lock(&driver_list_lock);
> +
> +       GEM_BUG_ON(!notify_enabled);
> +
> +       list_for_each_entry(i915, &driver_list, driver_list_link) {
> +               intel_runtime_pm_get(i915);
> +               __i915_disable_notify(i915);
> +               intel_runtime_pm_put(i915);
> +       }
> +
> +       notify_enabled = false;
> +
> +       mutex_unlock(&driver_list_lock);
> +}
> diff --git a/drivers/gpu/drm/i915/i915_tracing.h b/drivers/gpu/drm/i915/i915_tracing.h
> new file mode 100644
> index 000000000000..f5ed92428ff1
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_tracing.h
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + */
> +
> +#include "i915_drv.h"
> +

#if IS_ENABLED(CONFIG_TRACEPOINTS)

> +void i915_tracing_register(struct drm_i915_private *i915);
> +void i915_tracing_unregister(struct drm_i915_private *i915);
> +
> +int intel_engine_notify_tracepoint_register(void);
> +void intel_engine_notify_tracepoint_unregister(void);

#else

static inline void i915_tracing_register(struct drm_i915_private *i915) {}
static inline void i915_tracing_unregister(struct drm_i915_private *i915) {}

#endif

Otherwise, to the best of my knowledge this will just work. With the
fixes and any of the nits,
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
-Chris


More information about the Intel-gfx mailing list