diff mbox

[RFC,2/2] drm/i915/tracing: Enable user interrupts while intel_engine_notify is active

Message ID 20180625173237.7930-2-tvrtko.ursulin@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tvrtko Ursulin June 25, 2018, 5:32 p.m. UTC
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Keep the user interrupt enabled while intel_engine_notify tracepoint is
enabled.

We use tracepoint (de)registration callbacks to enable user interrupts on
all devices (future proofing and avoiding ugly global pointers) and all
engines.

Premise is that if someone is listening, they want to see interrupts
logged.

Commit to be improved...

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/Makefile       |  1 +
 drivers/gpu/drm/i915/i915_drv.c     |  2 +
 drivers/gpu/drm/i915/i915_drv.h     |  2 +
 drivers/gpu/drm/i915/i915_trace.h   | 50 ++++++++-------
 drivers/gpu/drm/i915/i915_tracing.c | 96 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_tracing.h | 13 ++++
 6 files changed, 141 insertions(+), 23 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_tracing.c
 create mode 100644 drivers/gpu/drm/i915/i915_tracing.h

Comments

Tvrtko Ursulin Aug. 8, 2018, 10:58 a.m. UTC | #1
ping!

On 25/06/2018 18:32, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Keep the user interrupt enabled while intel_engine_notify tracepoint is
> enabled.
> 
> We use tracepoint (de)registration callbacks to enable user interrupts on
> all devices (future proofing and avoiding ugly global pointers) and all
> engines.
> 
> Premise is that if someone is listening, they want to see interrupts
> logged.
> 
> Commit to be improved...
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/Makefile       |  1 +
>   drivers/gpu/drm/i915/i915_drv.c     |  2 +
>   drivers/gpu/drm/i915/i915_drv.h     |  2 +
>   drivers/gpu/drm/i915/i915_trace.h   | 50 ++++++++-------
>   drivers/gpu/drm/i915/i915_tracing.c | 96 +++++++++++++++++++++++++++++
>   drivers/gpu/drm/i915/i915_tracing.h | 13 ++++
>   6 files changed, 141 insertions(+), 23 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/i915_tracing.c
>   create mode 100644 drivers/gpu/drm/i915/i915_tracing.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 4c6adae23e18..ee082addd328 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -77,6 +77,7 @@ i915-y += i915_cmd_parser.o \
>   	  i915_request.o \
>   	  i915_timeline.o \
>   	  i915_trace_points.o \
> +	  i915_tracing.o \
>   	  i915_vma.o \
>   	  intel_breadcrumbs.o \
>   	  intel_engine_cs.o \
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 8a3ea18d8416..c634583baf57 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1271,6 +1271,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
>   	INIT_LIST_HEAD(&dev_priv->driver_list_link);
>   	mutex_lock(&i915_driver_list_lock);
>   	list_add_tail(&dev_priv->driver_list_link, &i915_driver_list);
> +	i915_tracing_register(dev_priv);
>   	mutex_unlock(&i915_driver_list_lock);
>   }
>   
> @@ -1285,6 +1286,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
>   
>   	mutex_lock(&i915_driver_list_lock);
>   	list_del(&dev_priv->driver_list_link);
> +	i915_tracing_unregister(dev_priv);
>   	mutex_unlock(&i915_driver_list_lock);
>   
>   	/*
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 685bfdca3a72..4e3230713491 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2144,6 +2144,8 @@ struct drm_i915_private {
>   
>   	struct list_head driver_list_link;
>   
> +	bool engine_notify_tracepoint;
> +
>   	/*
>   	 * 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_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..a9f486278109
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_tracing.c
> @@ -0,0 +1,96 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + */
> +
> +#include "i915_tracing.h"
> +
> +#include "i915_drv.h"
> +#include "intel_ringbuffer.h"
> +
> +void i915_tracing_register(struct drm_i915_private *i915)
> +{
> +	struct intel_engine_cs *engine;
> +	struct drm_i915_private *p;
> +	enum intel_engine_id id;
> +	bool enable = false;
> +
> +	lockdep_assert_held(&i915_driver_list_lock);
> +
> +	list_for_each_entry(p, &i915_driver_list, driver_list_link) {
> +		enable = p->engine_notify_tracepoint;
> +		if (enable)
> +			break;
> +	}
> +
> +	if (!enable)
> +		return;
> +
> +	for_each_engine(engine, i915, id)
> +		intel_engine_pin_breadcrumbs_irq(engine);
> +
> +	i915->engine_notify_tracepoint = true;
> +}
> +
> +void i915_tracing_unregister(struct drm_i915_private *i915)
> +{
> +	struct intel_engine_cs *engine;
> +	enum intel_engine_id id;
> +
> +	lockdep_assert_held(&i915_driver_list_lock);
> +
> +	if (!i915->engine_notify_tracepoint)
> +		return;
> +
> +	for_each_engine(engine, i915, id)
> +		intel_engine_unpin_breadcrumbs_irq(engine);
> +
> +	i915->engine_notify_tracepoint = false;
> +}
> +
> +int intel_engine_notify_tracepoint_register(void)
> +{
> +	struct drm_i915_private *i915;
> +
> +	mutex_lock(&i915_driver_list_lock);
> +	list_for_each_entry(i915, &i915_driver_list, driver_list_link) {
> +		struct intel_engine_cs *engine;
> +		enum intel_engine_id id;
> +
> +		intel_runtime_pm_get(i915);
> +
> +		for_each_engine(engine, i915, id)
> +			intel_engine_pin_breadcrumbs_irq(engine);
> +
> +		intel_runtime_pm_put(i915);
> +
> +		GEM_BUG_ON(i915->engine_notify_tracepoint);
> +		i915->engine_notify_tracepoint = true;
> +	}
> +	mutex_unlock(&i915_driver_list_lock);
> +
> +	return 0;
> +}
> +
> +void intel_engine_notify_tracepoint_unregister(void)
> +{
> +	struct drm_i915_private *i915;
> +
> +	mutex_lock(&i915_driver_list_lock);
> +	list_for_each_entry(i915, &i915_driver_list, driver_list_link) {
> +		struct intel_engine_cs *engine;
> +		enum intel_engine_id id;
> +
> +		intel_runtime_pm_get(i915);
> +
> +		for_each_engine(engine, i915, id)
> +			intel_engine_unpin_breadcrumbs_irq(engine);
> +
> +		intel_runtime_pm_put(i915);
> +
> +		GEM_BUG_ON(!i915->engine_notify_tracepoint);
> +		i915->engine_notify_tracepoint = false;
> +	}
> +	mutex_unlock(&i915_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"
> +
> +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);
>
Chris Wilson Aug. 8, 2018, 11:11 a.m. UTC | #2
Quoting Tvrtko Ursulin (2018-06-25 18:32:37)
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Keep the user interrupt enabled while intel_engine_notify tracepoint is
> enabled.
> 
> We use tracepoint (de)registration callbacks to enable user interrupts on
> all devices (future proofing and avoiding ugly global pointers) and all
> engines.
> 
> Premise is that if someone is listening, they want to see interrupts
> logged.
> 
> Commit to be improved...
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/Makefile       |  1 +
>  drivers/gpu/drm/i915/i915_drv.c     |  2 +
>  drivers/gpu/drm/i915/i915_drv.h     |  2 +
>  drivers/gpu/drm/i915/i915_trace.h   | 50 ++++++++-------
>  drivers/gpu/drm/i915/i915_tracing.c | 96 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_tracing.h | 13 ++++
>  6 files changed, 141 insertions(+), 23 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/i915_tracing.c
>  create mode 100644 drivers/gpu/drm/i915/i915_tracing.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 4c6adae23e18..ee082addd328 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -77,6 +77,7 @@ i915-y += i915_cmd_parser.o \
>           i915_request.o \
>           i915_timeline.o \
>           i915_trace_points.o \
> +         i915_tracing.o \

No fancy obj-$(TRACING) ? :)

>           i915_vma.o \
>           intel_breadcrumbs.o \
>           intel_engine_cs.o \
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 8a3ea18d8416..c634583baf57 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1271,6 +1271,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
>         INIT_LIST_HEAD(&dev_priv->driver_list_link);
>         mutex_lock(&i915_driver_list_lock);
>         list_add_tail(&dev_priv->driver_list_link, &i915_driver_list);
> +       i915_tracing_register(dev_priv);
>         mutex_unlock(&i915_driver_list_lock);
>  }
>  
> @@ -1285,6 +1286,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
>  
>         mutex_lock(&i915_driver_list_lock);
>         list_del(&dev_priv->driver_list_link);
> +       i915_tracing_unregister(dev_priv);
>         mutex_unlock(&i915_driver_list_lock);
>  
>         /*
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 685bfdca3a72..4e3230713491 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2144,6 +2144,8 @@ struct drm_i915_private {
>  
>         struct list_head driver_list_link;
>  
> +       bool engine_notify_tracepoint;
> +
>         /*
>          * 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_tracing.c b/drivers/gpu/drm/i915/i915_tracing.c
> new file mode 100644
> index 000000000000..a9f486278109
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_tracing.c
> @@ -0,0 +1,96 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + */
> +
> +#include "i915_tracing.h"
> +
> +#include "i915_drv.h"
> +#include "intel_ringbuffer.h"
> +
> +void i915_tracing_register(struct drm_i915_private *i915)
> +{
> +       struct intel_engine_cs *engine;
> +       struct drm_i915_private *p;
> +       enum intel_engine_id id;
> +       bool enable = false;
> +
> +       lockdep_assert_held(&i915_driver_list_lock);
> +
> +       list_for_each_entry(p, &i915_driver_list, driver_list_link) {
> +               enable = p->engine_notify_tracepoint;
> +               if (enable)
> +                       break;
> +       }

All on this list are expected to have the same value of
engine_notify_tracepoint. As far as I can tell, engine_notify_tracepoint
is just a global and there's no particular advantage in having it
per-device. The caveat is that i915_tracing_register/unregister must be
called under the same lock as the list_add/del -- I wonder if that
device list should just be moved to i915_tracing.c and kept entirely
private? (Then any future use case would also likely instantiate their
own mutex and list?)
-Chris
Tvrtko Ursulin Aug. 8, 2018, 12:23 p.m. UTC | #3
On 08/08/2018 12:11, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-06-25 18:32:37)
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Keep the user interrupt enabled while intel_engine_notify tracepoint is
>> enabled.
>>
>> We use tracepoint (de)registration callbacks to enable user interrupts on
>> all devices (future proofing and avoiding ugly global pointers) and all
>> engines.
>>
>> Premise is that if someone is listening, they want to see interrupts
>> logged.
>>
>> Commit to be improved...
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> ---
>>   drivers/gpu/drm/i915/Makefile       |  1 +
>>   drivers/gpu/drm/i915/i915_drv.c     |  2 +
>>   drivers/gpu/drm/i915/i915_drv.h     |  2 +
>>   drivers/gpu/drm/i915/i915_trace.h   | 50 ++++++++-------
>>   drivers/gpu/drm/i915/i915_tracing.c | 96 +++++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/i915_tracing.h | 13 ++++
>>   6 files changed, 141 insertions(+), 23 deletions(-)
>>   create mode 100644 drivers/gpu/drm/i915/i915_tracing.c
>>   create mode 100644 drivers/gpu/drm/i915/i915_tracing.h
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index 4c6adae23e18..ee082addd328 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -77,6 +77,7 @@ i915-y += i915_cmd_parser.o \
>>            i915_request.o \
>>            i915_timeline.o \
>>            i915_trace_points.o \
>> +         i915_tracing.o \
> 
> No fancy obj-$(TRACING) ? :)

Just a miss, marking as TODO.

> 
>>            i915_vma.o \
>>            intel_breadcrumbs.o \
>>            intel_engine_cs.o \
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>> index 8a3ea18d8416..c634583baf57 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -1271,6 +1271,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
>>          INIT_LIST_HEAD(&dev_priv->driver_list_link);
>>          mutex_lock(&i915_driver_list_lock);
>>          list_add_tail(&dev_priv->driver_list_link, &i915_driver_list);
>> +       i915_tracing_register(dev_priv);
>>          mutex_unlock(&i915_driver_list_lock);
>>   }
>>   
>> @@ -1285,6 +1286,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
>>   
>>          mutex_lock(&i915_driver_list_lock);
>>          list_del(&dev_priv->driver_list_link);
>> +       i915_tracing_unregister(dev_priv);
>>          mutex_unlock(&i915_driver_list_lock);
>>   
>>          /*
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 685bfdca3a72..4e3230713491 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2144,6 +2144,8 @@ struct drm_i915_private {
>>   
>>          struct list_head driver_list_link;
>>   
>> +       bool engine_notify_tracepoint;
>> +
>>          /*
>>           * 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_tracing.c b/drivers/gpu/drm/i915/i915_tracing.c
>> new file mode 100644
>> index 000000000000..a9f486278109
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/i915_tracing.c
>> @@ -0,0 +1,96 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright © 2018 Intel Corporation
>> + *
>> + */
>> +
>> +#include "i915_tracing.h"
>> +
>> +#include "i915_drv.h"
>> +#include "intel_ringbuffer.h"
>> +
>> +void i915_tracing_register(struct drm_i915_private *i915)
>> +{
>> +       struct intel_engine_cs *engine;
>> +       struct drm_i915_private *p;
>> +       enum intel_engine_id id;
>> +       bool enable = false;
>> +
>> +       lockdep_assert_held(&i915_driver_list_lock);
>> +
>> +       list_for_each_entry(p, &i915_driver_list, driver_list_link) {
>> +               enable = p->engine_notify_tracepoint;
>> +               if (enable)
>> +                       break;
>> +       }
> 
> All on this list are expected to have the same value of
> engine_notify_tracepoint. As far as I can tell, engine_notify_tracepoint
> is just a global and there's no particular advantage in having it
> per-device. The caveat is that i915_tracing_register/unregister must be
> called under the same lock as the list_add/del -- I wonder if that
> device list should just be moved to i915_tracing.c and kept entirely
> private? (Then any future use case would also likely instantiate their
> own mutex and list?)

Agreed, probably better to keep it private since exported list is 
totally useless now. If there are no fundamental objections on the idea 
I'll re-spin with that change.

Regards,

Tvrtko
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4c6adae23e18..ee082addd328 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -77,6 +77,7 @@  i915-y += i915_cmd_parser.o \
 	  i915_request.o \
 	  i915_timeline.o \
 	  i915_trace_points.o \
+	  i915_tracing.o \
 	  i915_vma.o \
 	  intel_breadcrumbs.o \
 	  intel_engine_cs.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8a3ea18d8416..c634583baf57 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1271,6 +1271,7 @@  static void i915_driver_register(struct drm_i915_private *dev_priv)
 	INIT_LIST_HEAD(&dev_priv->driver_list_link);
 	mutex_lock(&i915_driver_list_lock);
 	list_add_tail(&dev_priv->driver_list_link, &i915_driver_list);
+	i915_tracing_register(dev_priv);
 	mutex_unlock(&i915_driver_list_lock);
 }
 
@@ -1285,6 +1286,7 @@  static void i915_driver_unregister(struct drm_i915_private *dev_priv)
 
 	mutex_lock(&i915_driver_list_lock);
 	list_del(&dev_priv->driver_list_link);
+	i915_tracing_unregister(dev_priv);
 	mutex_unlock(&i915_driver_list_lock);
 
 	/*
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 685bfdca3a72..4e3230713491 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2144,6 +2144,8 @@  struct drm_i915_private {
 
 	struct list_head driver_list_link;
 
+	bool engine_notify_tracepoint;
+
 	/*
 	 * 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_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..a9f486278109
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_tracing.c
@@ -0,0 +1,96 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ */
+
+#include "i915_tracing.h"
+
+#include "i915_drv.h"
+#include "intel_ringbuffer.h"
+
+void i915_tracing_register(struct drm_i915_private *i915)
+{
+	struct intel_engine_cs *engine;
+	struct drm_i915_private *p;
+	enum intel_engine_id id;
+	bool enable = false;
+
+	lockdep_assert_held(&i915_driver_list_lock);
+
+	list_for_each_entry(p, &i915_driver_list, driver_list_link) {
+		enable = p->engine_notify_tracepoint;
+		if (enable)
+			break;
+	}
+
+	if (!enable)
+		return;
+
+	for_each_engine(engine, i915, id)
+		intel_engine_pin_breadcrumbs_irq(engine);
+
+	i915->engine_notify_tracepoint = true;
+}
+
+void i915_tracing_unregister(struct drm_i915_private *i915)
+{
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+
+	lockdep_assert_held(&i915_driver_list_lock);
+
+	if (!i915->engine_notify_tracepoint)
+		return;
+
+	for_each_engine(engine, i915, id)
+		intel_engine_unpin_breadcrumbs_irq(engine);
+
+	i915->engine_notify_tracepoint = false;
+}
+
+int intel_engine_notify_tracepoint_register(void)
+{
+	struct drm_i915_private *i915;
+
+	mutex_lock(&i915_driver_list_lock);
+	list_for_each_entry(i915, &i915_driver_list, driver_list_link) {
+		struct intel_engine_cs *engine;
+		enum intel_engine_id id;
+
+		intel_runtime_pm_get(i915);
+
+		for_each_engine(engine, i915, id)
+			intel_engine_pin_breadcrumbs_irq(engine);
+
+		intel_runtime_pm_put(i915);
+
+		GEM_BUG_ON(i915->engine_notify_tracepoint);
+		i915->engine_notify_tracepoint = true;
+	}
+	mutex_unlock(&i915_driver_list_lock);
+
+	return 0;
+}
+
+void intel_engine_notify_tracepoint_unregister(void)
+{
+	struct drm_i915_private *i915;
+
+	mutex_lock(&i915_driver_list_lock);
+	list_for_each_entry(i915, &i915_driver_list, driver_list_link) {
+		struct intel_engine_cs *engine;
+		enum intel_engine_id id;
+
+		intel_runtime_pm_get(i915);
+
+		for_each_engine(engine, i915, id)
+			intel_engine_unpin_breadcrumbs_irq(engine);
+
+		intel_runtime_pm_put(i915);
+
+		GEM_BUG_ON(!i915->engine_notify_tracepoint);
+		i915->engine_notify_tracepoint = false;
+	}
+	mutex_unlock(&i915_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"
+
+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);