Skip to contentSkip to conversation

i915 PMU and engine busy stats

PATCH Superseded Tvrtko Ursulin 3 participants 15 messages Oct 11, 2017 – Oct 17, 2017

Subsystems (3)

v7 of 13 Superseded Latest is v13 →

lore
Share & tools
lore

Tvrtko Ursulin

author maintainer
#0 lore raw

v7 cover i915 PMU and engine busy stats

From: Tvrtko Ursulin <[email protected]>

Headline change is removal of the static branch optimisation since I couldn't prove that it makes a significant difference in the real world. I was able to meaure a small CPU usage decrease in our lrc tasklet, in one micro-benchmark, but I did not feel that justified it.

There are also tweaks to engine busyness tracking and the delayed stats disable got moved to a different patch due to the above.

Patch 1 is a small refactor to make the following work easier.

Patch 2 is the main bit.

Patch 3 is a small optimisation on top, to only run the sampling timer when it is required. (Depending on GPU awake status and active PMU counters.)

Patches 4-6 add software engine busyness tracking, which is then used from the PMU. This allows more efficient and more accurate engine busyness metric.

Patches 7-9 add the RC6 and interrupt count metric.

Tvrtko Ursulin (9):
drm/i915: Extract intel_get_cagf drm/i915/pmu: Expose a PMU interface for perf queries drm/i915/pmu: Suspend sampling when GPU is idle drm/i915: Wrap context schedule notification drm/i915: Engine busy time tracking drm/i915/pmu: Wire up engine busy stats to PMU drm/i915/pmu: Add interrupt count metric drm/i915: Convert intel_rc6_residency_us to ns drm/i915/pmu: Add RC6 residency metrics

 drivers/gpu/drm/i915/Makefile           |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c     |   9 +-
 drivers/gpu/drm/i915/i915_drv.c         |   2 +
 drivers/gpu/drm/i915/i915_drv.h         |  28 +-
 drivers/gpu/drm/i915/i915_gem.c         |   1 +
 drivers/gpu/drm/i915/i915_gem_request.c |   1 +
 drivers/gpu/drm/i915/i915_pmu.c         | 855 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_pmu.h         | 100 ++++
 drivers/gpu/drm/i915/i915_reg.h         |   3 +
 drivers/gpu/drm/i915/i915_sysfs.c       |  20 +-
 drivers/gpu/drm/i915/intel_engine_cs.c  | 122 +++++
 drivers/gpu/drm/i915/intel_lrc.c        |  19 +-
 drivers/gpu/drm/i915/intel_pm.c         |  41 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h | 132 +++++
 include/uapi/drm/i915_drm.h             |  54 ++
 15 files changed, 1353 insertions(+), 35 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_pmu.c
 create mode 100644 drivers/gpu/drm/i915/i915_pmu.h
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#1 lore raw

PATCH v7 1/9 drm/i915: Extract intel_get_cagf

From: Tvrtko Ursulin <[email protected]>

Code to be shared between debugfs and the PMU implementation.

v2: Checkpatch cleanup.
v3: Also consolidate i915_sysfs.c/gt_act_freq_mhz_show.
v4: Rebase.

---
 drivers/gpu/drm/i915/i915_debugfs.c |  9 ++-------
 drivers/gpu/drm/i915/i915_drv.h     |  2 ++
 drivers/gpu/drm/i915/i915_sysfs.c   | 11 +++--------
 drivers/gpu/drm/i915/intel_pm.c     | 14 ++++++++++++++
 4 files changed, 21 insertions(+), 15 deletions(-)
drivers/gpu/drm/i915/i915_debugfs.c +2 -7
index 0bb6e01121fc..8d6b096891a5 100644
@@ -1178,13 +1178,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 		rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
 		rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
 		rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
-		if (INTEL_GEN(dev_priv) >= 9)
-			cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
-		else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-			cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
-		else
-			cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
-		cagf = intel_gpu_freq(dev_priv, cagf);
+		cagf = intel_gpu_freq(dev_priv,
+				      intel_get_cagf(dev_priv, rpstat));
 
 		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
drivers/gpu/drm/i915/i915_drv.h +2 -0
index 6bbc4b83aa0a..0f5e336a67f4 100644
@@ -4187,6 +4187,8 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
 u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
 			   const i915_reg_t reg);
 
+u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat1);
+
 #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
 #define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
 
drivers/gpu/drm/i915/i915_sysfs.c +3 -8
index 791759f632e1..450ac7d343ad 100644
@@ -252,14 +252,9 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 		ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
 	} else {
-		u32 rpstat = I915_READ(GEN6_RPSTAT1);
-		if (INTEL_GEN(dev_priv) >= 9)
-			ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
-		else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-			ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
-		else
-			ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
-		ret = intel_gpu_freq(dev_priv, ret);
+		ret = intel_gpu_freq(dev_priv,
+				     intel_get_cagf(dev_priv,
+						    I915_READ(GEN6_RPSTAT1)));
 	}
 	mutex_unlock(&dev_priv->pcu_lock);
 
drivers/gpu/drm/i915/intel_pm.c +14 -0
index 2fcff9788b6f..a06ab60847eb 100644
@@ -9513,3 +9513,17 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
 	intel_runtime_pm_put(dev_priv);
 	return DIV_ROUND_UP_ULL(time_hw * units, div);
 }
+
+u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat)
+{
+	u32 cagf;
+
+	if (INTEL_GEN(dev_priv) >= 9)
+		cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
+	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+		cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
+	else
+		cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
+
+	return  cagf;
+}
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#2 lore raw

PATCH v7 2/9 drm/i915/pmu: Expose a PMU interface for perf queries

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

From: Chris Wilson <[email protected]>
From: Tvrtko Ursulin <[email protected]>
From: Dmitry Rogozhkin <[email protected]>

The first goal is to be able to measure GPU (and invidual ring) busyness without having to poll registers from userspace. (Which not only incurs holding the forcewake lock indefinitely, perturbing the system, but also runs the risk of hanging the machine.) As an alternative we can use the perf event counter interface to sample the ring registers periodically and send those results to userspace.

Functionality we are exporting to userspace is via the existing perf PMU API and can be exercised via the existing tools. For example:

perf stat -a -e i915/rcs0-busy/ -I 1000

Will print the render engine busynnes once per second. All the performance counters can be enumerated (perf list) and have their unit of measure correctly reported in sysfs.

v1-v2 (Chris Wilson):

v2: Use a common timer for the ring sampling.

v3: (Tvrtko Ursulin)
* Decouple uAPI from i915 engine ids.
* Complete uAPI defines.
* Refactor some code to helpers for clarity.
* Skip sampling disabled engines.
* Expose counters in sysfs.
* Pass in fake regs to avoid null ptr deref in perf core.
* Convert to class/instance uAPI.
* Use shared driver code for rc6 residency, power and frequency.

v4: (Dmitry Rogozhkin)
* Register PMU with .task_ctx_nr=perf_invalid_context
* Expose cpumask for the PMU with the single CPU in the mask
* Properly support pmu->stop(): it should call pmu->read()
* Properly support pmu->del(): it should call stop(event, PERF_EF_UPDATE)
* Introduce refcounting of event subscriptions.
* Make pmu.busy_stats a refcounter to avoid busy stats going away with some deleted event.
* Expose cpumask for i915 PMU to avoid multiple events creation of the same type followed by counter aggregation by perf-stat.
* Track CPUs getting online/offline to migrate perf context. If (likely) cpumask will initially set CPU0, CONFIG_BOOTPARAM_HOTPLUG_CPU0 will be needed to see effect of CPU status tracking.
* End result is that only global events are supported and perf stat works correctly.
* Deny perf driver level sampling - it is prohibited for uncore PMU.

v5: (Tvrtko Ursulin)

* Don't hardcode number of engine samplers.
* Rewrite event ref-counting for correctness and simplicity.
* Store initial counter value when starting already enabled events to correctly report values to all listeners.
* Fix RC6 residency readout.
* Comments, GPL header.

v6:
* Add missing entry to v4 changelog.
* Fix accounting in CPU hotplug case by copying the approach from arch/x86/events/intel/cstate.c. (Dmitry Rogozhkin)

v7:
* Log failure message only on failure.
* Remove CPU hotplug notification state on unregister.

v8:
* Fix error unwind on failed registration.
* Checkpatch cleanup.

v9:
* Drop the energy metric, it is available via intel_rapl_perf. (Ville Syrjälä)
* Use HAS_RC6(p). (Chris Wilson)
* Handle unsupported non-engine events. (Dmitry Rogozhkin)
* Rebase for intel_rc6_residency_ns needing caller managed runtime pm.
* Drop HAS_RC6 checks from the read callback since creating those events will be rejected at init time already.
* Add counter units to sysfs so perf stat output is nicer.
* Cleanup the attribute tables for brevity and readability.

v10:
* Fixed queued accounting.

v11:
* Move intel_engine_lookup_user to intel_engine_cs.c
* Commit update. (Joonas Lahtinen)

v12:
* More accurate sampling. (Chris Wilson)
* Store and report frequency in MHz for better usability from perf stat.
* Removed metrics: queued, interrupts, rc6 counters.
* Sample engine busyness based on seqno difference only for less MMIO (and forcewake) on all platforms. (Chris Wilson)

v13:
* Comment spelling, use mul_u32_u32 to work around potential GCC issue and somne code alignment changes. (Chris Wilson)

v14:
* Rebase.

v15:
* Rebase for RPS refactoring.

---
 drivers/gpu/drm/i915/Makefile           |   1 +
 drivers/gpu/drm/i915/i915_drv.c         |   2 +
 drivers/gpu/drm/i915/i915_drv.h         |  14 +
 drivers/gpu/drm/i915/i915_pmu.c         | 659 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_pmu.h         |  96 +++++
 drivers/gpu/drm/i915/i915_reg.h         |   3 +
 drivers/gpu/drm/i915/intel_engine_cs.c  |  35 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h |  26 ++
 include/uapi/drm/i915_drm.h             |  48 +++
 9 files changed, 884 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_pmu.c
 create mode 100644 drivers/gpu/drm/i915/i915_pmu.h
drivers/gpu/drm/i915/Makefile +1 -0
index 66d23b619db1..e94cd69b715a 100644
@@ -26,6 +26,7 @@ i915-y := i915_drv.o \
 
 i915-$(CONFIG_COMPAT)   += i915_ioc32.o
 i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o intel_pipe_crc.o
+i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o
 
 # GEM code
 i915-y += i915_cmd_parser.o \
drivers/gpu/drm/i915/i915_drv.c +2 -0
index f1e651703764..65060bdc7b81 100644
@@ -1215,6 +1215,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
 	struct drm_device *dev = &dev_priv->drm;
 
 	i915_gem_shrinker_init(dev_priv);
+	i915_pmu_register(dev_priv);
 
 	/*
 	 * Notify a valid surface after modesetting,
@@ -1269,6 +1270,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
 	intel_opregion_unregister(dev_priv);
 
 	i915_perf_unregister(dev_priv);
+	i915_pmu_unregister(dev_priv);
 
 	i915_teardown_sysfs(dev_priv);
 	i915_guc_log_unregister(dev_priv);
drivers/gpu/drm/i915/i915_drv.h +14 -0
index 0f5e336a67f4..c577d811d560 100644
@@ -40,6 +40,7 @@
 #include <linux/hash.h>
 #include <linux/intel-iommu.h>
 #include <linux/kref.h>
+#include <linux/perf_event.h>
 #include <linux/pm_qos.h>
 #include <linux/reservation.h>
 #include <linux/shmem_fs.h>
@@ -2272,6 +2273,8 @@ struct drm_i915_private {
 	struct i915_gem_context *kernel_context;
 	/* Context only to be used for injecting preemption commands */
 	struct i915_gem_context *preempt_context;
+	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
+					    [MAX_ENGINE_INSTANCE + 1];
 	struct i915_vma *semaphore;
 
 	struct drm_dma_handle *status_page_dmah;
@@ -2742,6 +2745,8 @@ struct drm_i915_private {
 		int	irq;
 	} lpe_audio;
 
+	struct i915_pmu pmu;
+
 	/*
 	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 	 * will be rejected. Instead look for a better place.
@@ -3988,6 +3993,15 @@ extern void i915_perf_fini(struct drm_i915_private *dev_priv);
 extern void i915_perf_register(struct drm_i915_private *dev_priv);
 extern void i915_perf_unregister(struct drm_i915_private *dev_priv);
 
+/* i915_pmu.c */
+#ifdef CONFIG_PERF_EVENTS
+void i915_pmu_register(struct drm_i915_private *i915);
+void i915_pmu_unregister(struct drm_i915_private *i915);
+#else
+static inline void i915_pmu_register(struct drm_i915_private *i915) {}
+static inline void i915_pmu_unregister(struct drm_i915_private *i915) {}
+#endif
+
 /* i915_suspend.c */
 extern int i915_save_state(struct drm_i915_private *dev_priv);
 extern int i915_restore_state(struct drm_i915_private *dev_priv);
drivers/gpu/drm/i915/i915_pmu.c new file +659 -0

659 lines not on this page · raw message

drivers/gpu/drm/i915/i915_pmu.h new file +96 -0

96 lines not on this page · raw message

drivers/gpu/drm/i915/i915_reg.h +3 -0
index d2d0a83c09b6..41fe69943c02 100644
@@ -186,6 +186,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define VIDEO_ENHANCEMENT_CLASS	2
 #define COPY_ENGINE_CLASS	3
 #define OTHER_CLASS		4
+#define MAX_ENGINE_CLASS	4
+
+#define MAX_ENGINE_INSTANCE    1
 
 /* PCI config space */
 
drivers/gpu/drm/i915/intel_engine_cs.c +35 -0
index a59b2a30ff5a..4c7d7ade99d8 100644
@@ -202,6 +202,15 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
 	class_info = &intel_engine_classes[info->class];
 
+	if (GEM_WARN_ON(info->class > MAX_ENGINE_CLASS))
+		return -EINVAL;
+
+	if (GEM_WARN_ON(info->instance > MAX_ENGINE_INSTANCE))
+		return -EINVAL;
+
+	if (GEM_WARN_ON(dev_priv->engine_class[info->class][info->instance]))
+		return -EINVAL;
+
 	GEM_BUG_ON(dev_priv->engine[id]);
 	engine = kzalloc(sizeof(*engine), GFP_KERNEL);
 	if (!engine)
@@ -229,6 +238,7 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 
 	ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
 
+	dev_priv->engine_class[info->class][info->instance] = engine;
 	dev_priv->engine[id] = engine;
 	return 0;
 }
@@ -1776,6 +1786,31 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m)
 	drm_printf(m, "\n");
 }
 
+static u8 user_class_map[I915_ENGINE_CLASS_MAX] = {
+	[I915_ENGINE_CLASS_OTHER] = OTHER_CLASS,
+	[I915_ENGINE_CLASS_RENDER] = RENDER_CLASS,
+	[I915_ENGINE_CLASS_COPY] = COPY_ENGINE_CLASS,
+	[I915_ENGINE_CLASS_VIDEO] = VIDEO_DECODE_CLASS,
+	[I915_ENGINE_CLASS_VIDEO_ENHANCE] = VIDEO_ENHANCEMENT_CLASS,
+};
+
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
+{
+	if (class >= ARRAY_SIZE(user_class_map))
+		return NULL;
+
+	class = user_class_map[class];
+
+	if (WARN_ON_ONCE(class > MAX_ENGINE_CLASS))
+		return NULL;
+
+	if (instance > MAX_ENGINE_INSTANCE)
+		return NULL;
+
+	return i915->engine_class[class][instance];
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_engine.c"
 #endif
drivers/gpu/drm/i915/intel_ringbuffer.h +26 -0
index 17186f067408..289bb25dd964 100644
@@ -5,6 +5,7 @@
 #include "i915_gem_batch_pool.h"
 #include "i915_gem_request.h"
 #include "i915_gem_timeline.h"
+#include "i915_pmu.h"
 #include "i915_selftest.h"
 
 struct drm_printer;
@@ -337,6 +338,28 @@ struct intel_engine_cs {
 		I915_SELFTEST_DECLARE(bool mock : 1);
 	} breadcrumbs;
 
+	struct {
+		/**
+		 * @enable: Bitmask of enable sample events on this engine.
+		 *
+		 * Bits correspond to sample event types, for instance
+		 * I915_SAMPLE_QUEUED is bit 0 etc.
+		 */
+		u32 enable;
+		/**
+		 * @enable_count: Reference count for the enabled samplers.
+		 *
+		 * Index number corresponds to the bit number from @enable.
+		 */
+		unsigned int enable_count[I915_PMU_SAMPLE_BITS];
+		/**
+		 * @sample: Counter values for sampling events.
+		 *
+		 * Our internal timer stores the current counters in this field.
+		 */
+		struct i915_pmu_sample sample[I915_ENGINE_SAMPLE_MAX];
+	} pmu;
+
 	/*
 	 * A pool of objects to use as shadow copies of client batch buffers
 	 * when the command parser is enabled. Prevents the client from
@@ -843,4 +866,7 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine);
 
 void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *p);
 
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
+
 #endif /* _INTEL_RINGBUFFER_H_ */
include/uapi/drm/i915_drm.h +48 -0

54 lines not on this page · raw message

Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#3 lore raw

PATCH v7 3/9 drm/i915/pmu: Suspend sampling when GPU is idle

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

If only a subset of events is enabled we can afford to suspend the sampling timer when the GPU is idle and so save some cycles and power.

v2: Rebase and limit timer even more.
v3: Rebase.
v4: Rebase.
v5: Skip action if perf PMU failed to register.
v6: Checkpatch cleanup.
v7:
* Add a common helper to start the timer if needed. (Chris Wilson)
* Add comment explaining bitwise logic in pmu_needs_timer.
v8: Fix some comments styles. (Chris Wilson)
v9: Rebase.

---
 drivers/gpu/drm/i915/i915_drv.h         |  4 ++
 drivers/gpu/drm/i915/i915_gem.c         |  1 +
 drivers/gpu/drm/i915/i915_gem_request.c |  1 +
 drivers/gpu/drm/i915/i915_pmu.c         | 88 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/i915_pmu.h         |  4 ++
 5 files changed, 88 insertions(+), 10 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +4 -0
index c577d811d560..a8b565e1193e 100644
@@ -3997,9 +3997,13 @@ extern void i915_perf_unregister(struct drm_i915_private *dev_priv);
 #ifdef CONFIG_PERF_EVENTS
 void i915_pmu_register(struct drm_i915_private *i915);
 void i915_pmu_unregister(struct drm_i915_private *i915);
+void i915_pmu_gt_idle(struct drm_i915_private *i915);
+void i915_pmu_gt_active(struct drm_i915_private *i915);
 #else
 static inline void i915_pmu_register(struct drm_i915_private *i915) {}
 static inline void i915_pmu_unregister(struct drm_i915_private *i915) {}
+static inline void i915_pmu_gt_idle(struct drm_i915_private *i915) {}
+static inline void i915_pmu_gt_active(struct drm_i915_private *i915) {}
 #endif
 
 /* i915_suspend.c */
drivers/gpu/drm/i915/i915_gem.c +1 -0
index f76890b74d00..100398b10a8b 100644
@@ -3269,6 +3269,7 @@ i915_gem_idle_work_handler(struct work_struct *work)
 
 	intel_engines_mark_idle(dev_priv);
 	i915_gem_timelines_mark_idle(dev_priv);
+	i915_pmu_gt_idle(dev_priv);
 
 	GEM_BUG_ON(!dev_priv->gt.awake);
 	dev_priv->gt.awake = false;
drivers/gpu/drm/i915/i915_gem_request.c +1 -0
index d5f4023e5d63..fa9af1ed80bd 100644
@@ -258,6 +258,7 @@ static void mark_busy(struct drm_i915_private *i915)
 	i915_update_gfx_val(i915);
 	if (INTEL_GEN(i915) >= 6)
 		gen6_rps_busy(i915);
+	i915_pmu_gt_active(i915);
 
 	queue_delayed_work(i915->wq,
 			   &i915->gt.retire_work,
drivers/gpu/drm/i915/i915_pmu.c +78 -10

119 lines not on this page · raw message

drivers/gpu/drm/i915/i915_pmu.h +4 -0
index 0f884dd3496a..89be7eb4af1c 100644
@@ -83,6 +83,10 @@ struct i915_pmu {
 	 */
 	unsigned int enable_count[I915_PMU_MASK_BITS];
 	/**
+	 * @timer_enabled: Should the internal sampling timer be running.
+	 */
+	bool timer_enabled;
+	/**
 	 * @sample: Current and previous (raw) counters for sampling events.
 	 *
 	 * These counters are updated from the i915 PMU sampling timer.
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#4 lore raw

PATCH v7 4/9 drm/i915: Wrap context schedule notification

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

No functional change just something which will be handy in the following patch.

---
 drivers/gpu/drm/i915/intel_lrc.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/intel_lrc.c +14 -3
index fbfcf88d7fe3..52a7c741762d 100644
@@ -400,6 +400,18 @@ execlists_context_status_change(struct drm_i915_gem_request *rq,
 				   status, rq);
 }
 
+static inline void
+execlists_context_schedule_in(struct drm_i915_gem_request *rq)
+{
+	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
+}
+
+static inline void
+execlists_context_schedule_out(struct drm_i915_gem_request *rq)
+{
+	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
+}
+
 static void
 execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state)
 {
@@ -451,7 +463,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine)
 		if (rq) {
 			GEM_BUG_ON(count > !n);
 			if (!count++)
-				execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
+				execlists_context_schedule_in(rq);
 			port_set(&port[n], port_pack(rq, count));
 			desc = execlists_update_context(rq);
 			GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc));
@@ -879,8 +891,7 @@ static void intel_lrc_irq_handler(unsigned long data)
 			if (--count == 0) {
 				GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED);
 				GEM_BUG_ON(!i915_gem_request_completed(rq));
-				execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
-
+				execlists_context_schedule_out(rq);
 				trace_i915_gem_request_out(rq);
 				rq->priotree.priority = INT_MAX;
 				i915_gem_request_put(rq);
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#5 lore raw

PATCH v7 5/9 drm/i915: Engine busy time tracking

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Track total time requests have been executing on the hardware.

We add new kernel API to allow software tracking of time GPU engines are spending executing requests.

Both per-engine and global API is added with the latter also being exported for use by external users.

v2:
* Squashed with the internal API.
* Dropped static key.
* Made per-engine.
* Store time in monotonic ktime.

v3: Moved stats clearing to disable.

v4:
* Comments.
* Don't export the API just yet.

v5: Whitespace cleanup.

v6:
* Rename ref to active.
* Drop engine aggregate stats for now.
* Account initial busy period after enabling stats.

v7:
* Rebase.

v8:
* Move context in notification after the notifier. (Chris Wilson)

v9:

In cases where stats tracking is getting disabled while there is an active context on an engine, add up the current value to the total. This also implies we don't clear the total when tracking is disabled any longer. There is no real need to do so because we define the stats as relative while enabled, meaning comparison between two samples while tracking is enabled is the valid usage. However, when busy stats will later be plugged into the perf PMU API, it is beneficial to not reset the total, since the PMU core likes to do some counter disable/enable cycles on startup, and while doing so during a single long context executing on an engine we would lose some accuracy and so make unit testing more difficult than needs to be.

---
 drivers/gpu/drm/i915/intel_engine_cs.c  | 87 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.c        |  2 +
 drivers/gpu/drm/i915/intel_ringbuffer.h | 92 +++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
drivers/gpu/drm/i915/intel_engine_cs.c +87 -0
index 4c7d7ade99d8..1dbe99373057 100644
@@ -236,6 +236,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	/* Nothing to do here, execute in order of dependencies */
 	engine->schedule = NULL;
 
+	spin_lock_init(&engine->stats.lock);
+
 	ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
 
 	dev_priv->engine_class[info->class][info->instance] = engine;
@@ -1811,6 +1813,91 @@ intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
 	return i915->engine_class[class][instance];
 }
 
+/**
+ * intel_enable_engine_stats() - Enable engine busy tracking on engine
+ * @engine: engine to enable stats collection
+ *
+ * Start collecting the engine busyness data for @engine.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int intel_enable_engine_stats(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	if (!i915_modparams.enable_execlists)
+		return -ENODEV;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	if (engine->stats.enabled == ~0)
+		goto busy;
+	if (engine->stats.enabled++ == 0)
+		engine->stats.enabled_at = ktime_get();
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return 0;
+
+busy:
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return -EBUSY;
+}
+
+static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine)
+{
+	ktime_t total = engine->stats.total;
+
+	/*
+	 * If the engine is executing something at the moment
+	 * add it to the total.
+	 */
+	if (engine->stats.active)
+		total = ktime_add(total,
+				  ktime_sub(ktime_get(), engine->stats.start));
+
+	return total;
+}
+
+/**
+ * intel_engine_get_busy_time() - Return current accumulated engine busyness
+ * @engine: engine to report on
+ *
+ * Returns accumulated time @engine was busy since engine stats were enabled.
+ */
+ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine)
+{
+	ktime_t total;
+	unsigned long flags;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	total = __intel_engine_get_busy_time(engine);
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return total;
+}
+
+/**
+ * intel_disable_engine_stats() - Disable engine busy tracking on engine
+ * @engine: engine to disable stats collection
+ *
+ * Stops collecting the engine busyness data for @engine.
+ */
+void intel_disable_engine_stats(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	if (!i915_modparams.enable_execlists)
+		return;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	WARN_ON_ONCE(engine->stats.enabled == 0);
+	if (--engine->stats.enabled == 0) {
+		engine->stats.total = __intel_engine_get_busy_time(engine);
+		engine->stats.active = 0;
+	}
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_engine.c"
 #endif
drivers/gpu/drm/i915/intel_lrc.c +2 -0
index 52a7c741762d..145f2d9d0fe0 100644
@@ -404,11 +404,13 @@ static inline void
 execlists_context_schedule_in(struct drm_i915_gem_request *rq)
 {
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
+	intel_engine_context_in(rq->engine);
 }
 
 static inline void
 execlists_context_schedule_out(struct drm_i915_gem_request *rq)
 {
+	intel_engine_context_out(rq->engine);
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
 }
 
drivers/gpu/drm/i915/intel_ringbuffer.h +92 -0

102 lines not on this page · raw message

Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#6 lore raw

PATCH v10 5/9 drm/i915: Engine busy time tracking

From: Tvrtko Ursulin <[email protected]>

Track total time requests have been executing on the hardware.

We add new kernel API to allow software tracking of time GPU engines are spending executing requests.

Both per-engine and global API is added with the latter also being exported for use by external users.

v2:
* Squashed with the internal API.
* Dropped static key.
* Made per-engine.
* Store time in monotonic ktime.

v3: Moved stats clearing to disable.

v4:
* Comments.
* Don't export the API just yet.

v5: Whitespace cleanup.

v6:
* Rename ref to active.
* Drop engine aggregate stats for now.
* Account initial busy period after enabling stats.

v7:
* Rebase.

v8:
* Move context in notification after the notifier. (Chris Wilson)

v9:

In cases where stats tracking is getting disabled while there is an active context on an engine, add up the current value to the total. This also implies we don't clear the total when tracking is disabled any longer. There is no real need to do so because we define the stats as relative while enabled, meaning comparison between two samples while tracking is enabled is the valid usage. However, when busy stats will later be plugged into the perf PMU API, it is beneficial to not reset the total, since the PMU core likes to do some counter disable/enable cycles on startup, and while doing so during a single long context executing on an engine we would lose some accuracy and so make unit testing more difficult than needs to be.

v10:
* Fix accounting for preemption.

---
 drivers/gpu/drm/i915/intel_engine_cs.c  | 87 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.c        |  3 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h | 92 +++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+)
drivers/gpu/drm/i915/intel_engine_cs.c +87 -0
index 02ac8e1d415b..47d8ee347d2b 100644
@@ -237,6 +237,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	/* Nothing to do here, execute in order of dependencies */
 	engine->schedule = NULL;
 
+	spin_lock_init(&engine->stats.lock);
+
 	ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
 
 	dev_priv->engine_class[info->class][info->instance] = engine;
@@ -1815,6 +1817,91 @@ intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
 	return i915->engine_class[class][instance];
 }
 
+/**
+ * intel_enable_engine_stats() - Enable engine busy tracking on engine
+ * @engine: engine to enable stats collection
+ *
+ * Start collecting the engine busyness data for @engine.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int intel_enable_engine_stats(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	if (!i915_modparams.enable_execlists)
+		return -ENODEV;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	if (engine->stats.enabled == ~0)
+		goto busy;
+	if (engine->stats.enabled++ == 0)
+		engine->stats.enabled_at = ktime_get();
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return 0;
+
+busy:
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return -EBUSY;
+}
+
+static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine)
+{
+	ktime_t total = engine->stats.total;
+
+	/*
+	 * If the engine is executing something at the moment
+	 * add it to the total.
+	 */
+	if (engine->stats.active)
+		total = ktime_add(total,
+				  ktime_sub(ktime_get(), engine->stats.start));
+
+	return total;
+}
+
+/**
+ * intel_engine_get_busy_time() - Return current accumulated engine busyness
+ * @engine: engine to report on
+ *
+ * Returns accumulated time @engine was busy since engine stats were enabled.
+ */
+ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine)
+{
+	ktime_t total;
+	unsigned long flags;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	total = __intel_engine_get_busy_time(engine);
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+
+	return total;
+}
+
+/**
+ * intel_disable_engine_stats() - Disable engine busy tracking on engine
+ * @engine: engine to disable stats collection
+ *
+ * Stops collecting the engine busyness data for @engine.
+ */
+void intel_disable_engine_stats(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	if (!i915_modparams.enable_execlists)
+		return;
+
+	spin_lock_irqsave(&engine->stats.lock, flags);
+	WARN_ON_ONCE(engine->stats.enabled == 0);
+	if (--engine->stats.enabled == 0) {
+		engine->stats.total = __intel_engine_get_busy_time(engine);
+		engine->stats.active = 0;
+	}
+	spin_unlock_irqrestore(&engine->stats.lock, flags);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_engine.c"
 #endif
drivers/gpu/drm/i915/intel_lrc.c +3 -0
index 6713f4a2f581..8a7a9cc5f28d 100644
@@ -404,11 +404,13 @@ static inline void
 execlists_context_schedule_in(struct drm_i915_gem_request *rq)
 {
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
+	intel_engine_context_in(rq->engine);
 }
 
 static inline void
 execlists_context_schedule_out(struct drm_i915_gem_request *rq)
 {
+	intel_engine_context_out(rq->engine);
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
 }
 
@@ -708,6 +710,7 @@ execlist_cancel_port_requests(struct intel_engine_execlists *execlists)
 	while (num_ports-- && port_isset(port)) {
 		struct drm_i915_gem_request *rq = port_request(port);
 
+		intel_engine_context_out(rq->engine);
 		execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_PREEMPTED);
 		i915_gem_request_put(rq);
 
drivers/gpu/drm/i915/intel_ringbuffer.h +92 -0

102 lines not on this page · raw message

Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Reviewed-by on v10 5/9
#7 lore raw

Re: [PATCH v10 5/9] drm/i915: Engine busy time tracking

Quoting Tvrtko Ursulin (2017-10-17 11:46:21)

Quoted 37 lines

From: Tvrtko Ursulin <[email protected]>

Track total time requests have been executing on the hardware.

We add new kernel API to allow software tracking of time GPU engines are spending executing requests.

Both per-engine and global API is added with the latter also being exported for use by external users.

v2:
* Squashed with the internal API.
* Dropped static key.
* Made per-engine.
* Store time in monotonic ktime.

v3: Moved stats clearing to disable.

v4:
* Comments.
* Don't export the API just yet.

v5: Whitespace cleanup.

v6:
* Rename ref to active.
* Drop engine aggregate stats for now.
* Account initial busy period after enabling stats.

v7:
* Rebase.

v8:
* Move context in notification after the notifier. (Chris Wilson)

v9:

Quoted 12 lines

In cases where stats tracking is getting disabled while there is an active context on an engine, add up the current value to the total. This also implies we don't clear the total when tracking is disabled any longer. There is no real need to do so because we define the stats as relative while enabled, meaning comparison between two samples while tracking is enabled is the valid usage. However, when busy stats will later be plugged into the perf PMU API, it is beneficial to not reset the total, since the PMU core likes to do some counter disable/enable cycles on startup, and while doing so during a single long context executing on an engine we would lose some accuracy and so make unit testing more difficult than needs to be.

Ok, so it's a counter since boot and not reset on every pmu reload. We anticipate users are going to be doing (sampleB - sampleA)/delta_time so they aren't concerned with absolute values, just deltas.

Quoted 5 lines

v10:
* Fix accounting for preemption.

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

author maintainer
#8 lore raw

PATCH v7 6/9 drm/i915/pmu: Wire up engine busy stats to PMU

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

We can use engine busy stats instead of the sampling timer for better accuracy.

By doing this we replace the stohastic sampling with busyness metric derived directly from engine activity. This is context switch interrupt driven, so as accurate as we can get from software tracking.

As a secondary benefit, we can also not run the sampling timer in cases only busyness metric is enabled.

v2: Rebase.
v3:
* Rebase, comments.
* Leave engine busyness controls out of workers.
v4: Checkpatch cleanup.
v5: Added comment to pmu_needs_timer change.
v6:
* Rebase.
* Fix style of some comments. (Chris Wilson)
v7: Rebase and commit message update. (Chris Wilson)
v8: Add delayed stats disabling to improve accuracy in face of
CPU hotplug events.

---
 drivers/gpu/drm/i915/i915_pmu.c         | 78 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_ringbuffer.h | 14 ++++++
 2 files changed, 90 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/i915_pmu.c +76 -2
index bd394da47c7a..434895288094 100644
@@ -90,6 +90,11 @@ static unsigned int event_enabled_bit(struct perf_event *event)
 	return config_enabled_bit(event->attr.config);
 }
 
+static bool supports_busy_stats(void)
+{
+	return i915_modparams.enable_execlists;
+}
+
 static bool pmu_needs_timer(struct drm_i915_private *i915, bool gpu_active)
 {
 	u64 enable;
@@ -115,6 +120,12 @@ static bool pmu_needs_timer(struct drm_i915_private *i915, bool gpu_active)
 	 */
 	if (!gpu_active)
 		enable &= ~ENGINE_SAMPLE_MASK;
+	/*
+	 * Also there is software busyness tracking available we do not
+	 * need the timer for I915_SAMPLE_BUSY counter.
+	 */
+	else if (supports_busy_stats())
+		enable &= ~BIT(I915_SAMPLE_BUSY);
 
 	/*
 	 * If some bits remain it means we need the sampling timer running.
@@ -363,6 +374,9 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
 
 		if (WARN_ON_ONCE(!engine)) {
 			/* Do nothing */
+		} else if (sample == I915_SAMPLE_BUSY &&
+			   engine->pmu.busy_stats) {
+			val = ktime_to_ns(intel_engine_get_busy_time(engine));
 		} else {
 			val = engine->pmu.sample[sample].cur;
 		}
@@ -399,6 +413,12 @@ static void i915_pmu_event_read(struct perf_event *event)
 	local64_add(new - prev, &event->count);
 }
 
+static bool engine_needs_busy_stats(struct intel_engine_cs *engine)
+{
+	return supports_busy_stats() &&
+	       (engine->pmu.enable & BIT(I915_SAMPLE_BUSY));
+}
+
 static void i915_pmu_enable(struct perf_event *event)
 {
 	struct drm_i915_private *i915 =
@@ -438,7 +458,21 @@ static void i915_pmu_enable(struct perf_event *event)
 
 		GEM_BUG_ON(sample >= I915_PMU_SAMPLE_BITS);
 		GEM_BUG_ON(engine->pmu.enable_count[sample] == ~0);
-		engine->pmu.enable_count[sample]++;
+		if (engine->pmu.enable_count[sample]++ == 0) {
+			/*
+			 * Enable engine busy stats tracking if needed or
+			 * alternatively cancel the scheduled disable.
+			 *
+			 * If the delayed disable was pending, cancel it and
+			 * in this case do not enable since it already is.
+			 */
+			if (engine_needs_busy_stats(engine) &&
+			    !engine->pmu.busy_stats) {
+				engine->pmu.busy_stats = true;
+				if (!cancel_delayed_work(&engine->pmu.disable_busy_stats))
+					intel_enable_engine_stats(engine);
+			}
+		}
 	}
 
 	/*
@@ -474,8 +508,26 @@ static void i915_pmu_disable(struct perf_event *event)
 		 * Decrement the reference count and clear the enabled
 		 * bitmask when the last listener on an event goes away.
 		 */
-		if (--engine->pmu.enable_count[sample] == 0)
+		if (--engine->pmu.enable_count[sample] == 0) {
 			engine->pmu.enable &= ~BIT(sample);
+			if (!engine_needs_busy_stats(engine) &&
+			    engine->pmu.busy_stats) {
+				engine->pmu.busy_stats = false;
+				/*
+				 * We request a delayed disable to handle the
+				 * rapid on/off cycles on events, which can
+				 * happen when tools like perf stat start, in a
+				 * nicer way.
+				 *
+				 * In addition, this also helps with busy stats
+				 * accuracy with background CPU offline/online
+				 * migration events.
+				 */
+				queue_delayed_work(system_wq,
+						   &engine->pmu.disable_busy_stats,
+						   round_jiffies_up_relative(HZ));
+			}
+		}
 	}
 
 	GEM_BUG_ON(bit >= I915_PMU_MASK_BITS);
@@ -657,8 +709,18 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
 	return 0;
 }
 
+static void __disable_busy_stats(struct work_struct *work)
+{
+	struct intel_engine_cs *engine =
+	       container_of(work, typeof(*engine), pmu.disable_busy_stats.work);
+
+	intel_disable_engine_stats(engine);
+}
+
 void i915_pmu_register(struct drm_i915_private *i915)
 {
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
 	int ret;
 
 	if (INTEL_GEN(i915) <= 2) {
@@ -693,6 +755,10 @@ void i915_pmu_register(struct drm_i915_private *i915)
 	i915->pmu.timer.function = i915_sample;
 	i915->pmu.enable = 0;
 
+	for_each_engine(engine, i915, id)
+		INIT_DELAYED_WORK(&engine->pmu.disable_busy_stats,
+				  __disable_busy_stats);
+
 	ret = perf_pmu_register(&i915->pmu.base, "i915", -1);
 	if (ret == 0)
 		return;
@@ -711,6 +777,9 @@ void i915_pmu_register(struct drm_i915_private *i915)
 
 void i915_pmu_unregister(struct drm_i915_private *i915)
 {
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+
 	if (!i915->pmu.base.event_init)
 		return;
 
@@ -722,6 +791,11 @@ void i915_pmu_unregister(struct drm_i915_private *i915)
 
 	hrtimer_cancel(&i915->pmu.timer);
 
+	for_each_engine(engine, i915, id) {
+		GEM_BUG_ON(engine->pmu.busy_stats);
+		flush_delayed_work(&engine->pmu.disable_busy_stats);
+	}
+
 	perf_pmu_unregister(&i915->pmu.base);
 	i915->pmu.base.event_init = NULL;
 }
drivers/gpu/drm/i915/intel_ringbuffer.h +14 -0
index 850620699468..871dca7e82ba 100644
@@ -358,6 +358,20 @@ struct intel_engine_cs {
 		 * Our internal timer stores the current counters in this field.
 		 */
 		struct i915_pmu_sample sample[I915_ENGINE_SAMPLE_MAX];
+		/**
+		 * @busy_stats: Has enablement of engine stats tracking been
+		 * 		requested.
+		 */
+		bool busy_stats;
+		/**
+		 * @disable_busy_stats: Work item for busy stats disabling.
+		 *
+		 * Same as with @enable_busy_stats action, with the difference
+		 * that we delay it in case there are rapid enable-disable
+		 * actions, which can happen during tool startup (like perf
+		 * stat).
+		 */
+		struct delayed_work disable_busy_stats;
 	} pmu;
 
 	/*
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#9 lore raw

PATCH v7 7/9 drm/i915/pmu: Add interrupt count metric

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

For clients like intel-gpu-overlay it is easier to read the count via the perf API than having to parse /proc.

---
 drivers/gpu/drm/i915/i915_pmu.c | 23 +++++++++++++++++++++++
 include/uapi/drm/i915_drm.h     |  4 +++-
 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_pmu.c +23 -0
index 434895288094..97d489565cd1 100644
@@ -277,6 +277,22 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
 	return HRTIMER_RESTART;
 }
 
+static u64 count_interrupts(struct drm_i915_private *i915)
+{
+	/* open-coded kstat_irqs() */
+	struct irq_desc *desc = irq_to_desc(i915->drm.pdev->irq);
+	u64 sum = 0;
+	int cpu;
+
+	if (!desc || !desc->kstat_irqs)
+		return 0;
+
+	for_each_possible_cpu(cpu)
+		sum += *per_cpu_ptr(desc->kstat_irqs, cpu);
+
+	return sum;
+}
+
 static void i915_pmu_event_destroy(struct perf_event *event)
 {
 	WARN_ON(event->parent);
@@ -343,6 +359,8 @@ static int i915_pmu_event_init(struct perf_event *event)
 			if (INTEL_GEN(i915) < 6)
 				ret = -ENODEV;
 			break;
+		case I915_PMU_INTERRUPTS:
+			break;
 		default:
 			ret = -ENOENT;
 			break;
@@ -392,6 +410,9 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
 			   div_u64(i915->pmu.sample[__I915_SAMPLE_FREQ_REQ].cur,
 				   FREQUENCY);
 			break;
+		case I915_PMU_INTERRUPTS:
+			val = count_interrupts(i915);
+			break;
 		}
 	}
 
@@ -646,6 +667,8 @@ static struct attribute *i915_pmu_events_attrs[] = {
 	I915_EVENT(actual-frequency,    I915_PMU_ACTUAL_FREQUENCY,    "MHz"),
 	I915_EVENT(requested-frequency, I915_PMU_REQUESTED_FREQUENCY, "MHz"),
 
+	I915_EVENT_ATTR(interrupts, I915_PMU_INTERRUPTS),
+
 	NULL,
 };
 
include/uapi/drm/i915_drm.h +3 -1
index d35af9ff635c..8aceb7f57e0c 100644
@@ -132,7 +132,9 @@ enum drm_i915_pmu_engine_sample {
 #define I915_PMU_ACTUAL_FREQUENCY	__I915_PMU_OTHER(0)
 #define I915_PMU_REQUESTED_FREQUENCY	__I915_PMU_OTHER(1)
 
-#define I915_PMU_LAST I915_PMU_REQUESTED_FREQUENCY
+#define I915_PMU_INTERRUPTS		__I915_PMU_OTHER(2)
+
+#define I915_PMU_LAST I915_PMU_INTERRUPTS
 
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#10 lore raw

PATCH v7 8/9 drm/i915: Convert intel_rc6_residency_us to ns

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Will be used for exposing the PMU counters.

v2:
* Move intel_runtime_pm_get/put to the callers. (Chris Wilson)
* Restore full unit conversion precision.

---
 drivers/gpu/drm/i915/i915_drv.h   |  8 +++++++-
 drivers/gpu/drm/i915/i915_sysfs.c |  9 +++++++--
 drivers/gpu/drm/i915/intel_pm.c   | 27 +++++++++++++--------------
 3 files changed, 27 insertions(+), 17 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +7 -1
index a8b565e1193e..57d08ec5b6a3 100644
@@ -4202,11 +4202,17 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder);
 
 int intel_gpu_freq(struct drm_i915_private *dev_priv, int val);
 int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
-u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
+u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
 			   const i915_reg_t reg);
 
 u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat1);
 
+static inline u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
+					 const i915_reg_t reg)
+{
+	return DIV_ROUND_UP_ULL(intel_rc6_residency_ns(dev_priv, reg), 1000);
+}
+
 #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
 #define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
 
drivers/gpu/drm/i915/i915_sysfs.c +7 -2
index 450ac7d343ad..c290cb600eea 100644
@@ -42,8 +42,13 @@ static inline struct drm_i915_private *kdev_minor_to_i915(struct device *kdev)
 static u32 calc_residency(struct drm_i915_private *dev_priv,
 			  i915_reg_t reg)
 {
-	return DIV_ROUND_CLOSEST_ULL(intel_rc6_residency_us(dev_priv, reg),
-				     1000);
+	u64 res;
+
+	intel_runtime_pm_get(dev_priv);
+	res = intel_rc6_residency_us(dev_priv, reg);
+	intel_runtime_pm_put(dev_priv);
+
+	return DIV_ROUND_CLOSEST_ULL(res, 1000);
 }
 
 static ssize_t
drivers/gpu/drm/i915/intel_pm.c +13 -14
index a06ab60847eb..4787937757b8 100644
@@ -9482,36 +9482,35 @@ static u64 vlv_residency_raw(struct drm_i915_private *dev_priv,
 	return lower | (u64)upper << 8;
 }
 
-u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
+u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
 			   const i915_reg_t reg)
 {
-	u64 time_hw, units, div;
+	u64 time_hw;
+	u32 mul, div;
 
 	if (!intel_rc6_enabled())
 		return 0;
 
-	intel_runtime_pm_get(dev_priv);
-
 	/* On VLV and CHV, residency time is in CZ units rather than 1.28us */
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-		units = 1000;
+		mul = 1000000;
 		div = dev_priv->czclk_freq;
-
 		time_hw = vlv_residency_raw(dev_priv, reg);
-	} else if (IS_GEN9_LP(dev_priv)) {
-		units = 1000;
-		div = 1200;		/* 833.33ns */
 
-		time_hw = I915_READ(reg);
 	} else {
-		units = 128000; /* 1.28us */
-		div = 100000;
+		/* 833.33ns units on Gen9LP, 1.28us elsewhere. */
+		if (IS_GEN9_LP(dev_priv)) {
+			mul = 10000;
+			div = 12;
+		} else {
+			mul = 1280;
+			div = 1;
+		}
 
 		time_hw = I915_READ(reg);
 	}
 
-	intel_runtime_pm_put(dev_priv);
-	return DIV_ROUND_UP_ULL(time_hw * units, div);
+	return DIV_ROUND_UP_ULL(time_hw * mul, div);
 }
 
 u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat)
Signature · 6 lines
2.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
author maintainer
#11 lore raw

PATCH v7 9/9 drm/i915/pmu: Add RC6 residency metrics

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

For clients like intel-gpu-overlay it is easier to read the counters via the perf API than having to parse sysfs.

---
 drivers/gpu/drm/i915/i915_pmu.c | 31 +++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h     |  6 +++++-
 2 files changed, 36 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_pmu.c +31 -0
index 97d489565cd1..5d2c83a41b53 100644
@@ -361,6 +361,15 @@ static int i915_pmu_event_init(struct perf_event *event)
 			break;
 		case I915_PMU_INTERRUPTS:
 			break;
+		case I915_PMU_RC6_RESIDENCY:
+			if (!HAS_RC6(i915))
+				ret = -ENODEV;
+			break;
+		case I915_PMU_RC6p_RESIDENCY:
+		case I915_PMU_RC6pp_RESIDENCY:
+			if (!HAS_RC6p(i915))
+				ret = -ENODEV;
+			break;
 		default:
 			ret = -ENOENT;
 			break;
@@ -413,6 +422,24 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
 		case I915_PMU_INTERRUPTS:
 			val = count_interrupts(i915);
 			break;
+		case I915_PMU_RC6_RESIDENCY:
+			intel_runtime_pm_get(i915);
+			val = intel_rc6_residency_ns(i915,
+						     IS_VALLEYVIEW(i915) ?
+						     VLV_GT_RENDER_RC6 :
+						     GEN6_GT_GFX_RC6);
+			intel_runtime_pm_put(i915);
+			break;
+		case I915_PMU_RC6p_RESIDENCY:
+			intel_runtime_pm_get(i915);
+			val = intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6p);
+			intel_runtime_pm_put(i915);
+			break;
+		case I915_PMU_RC6pp_RESIDENCY:
+			intel_runtime_pm_get(i915);
+			val = intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6pp);
+			intel_runtime_pm_put(i915);
+			break;
 		}
 	}
 
@@ -669,6 +696,10 @@ static struct attribute *i915_pmu_events_attrs[] = {
 
 	I915_EVENT_ATTR(interrupts, I915_PMU_INTERRUPTS),
 
+	I915_EVENT(rc6-residency,   I915_PMU_RC6_RESIDENCY,   "ns"),
+	I915_EVENT(rc6p-residency,  I915_PMU_RC6p_RESIDENCY,  "ns"),
+	I915_EVENT(rc6pp-residency, I915_PMU_RC6pp_RESIDENCY, "ns"),
+
 	NULL,
 };
 
include/uapi/drm/i915_drm.h +5 -1
index 8aceb7f57e0c..709f28fc0970 100644
@@ -134,7 +134,11 @@ enum drm_i915_pmu_engine_sample {
 
 #define I915_PMU_INTERRUPTS		__I915_PMU_OTHER(2)
 
-#define I915_PMU_LAST I915_PMU_INTERRUPTS
+#define I915_PMU_RC6_RESIDENCY		__I915_PMU_OTHER(3)
+#define I915_PMU_RC6p_RESIDENCY		__I915_PMU_OTHER(4)
+#define I915_PMU_RC6pp_RESIDENCY	__I915_PMU_OTHER(5)
+
+#define I915_PMU_LAST I915_PMU_RC6pp_RESIDENCY
 
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
Signature · 6 lines
2.9.5

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

✗ Fi.CI.BAT: failure for i915 PMU and engine busy stats (rev17)

In reply to Tvrtko Ursulin
== Series Details ==

== Series Details ==

Series: i915 PMU and engine busy stats (rev17)
URL : https://patchwork.freedesktop.org/series/27488/
State : failure

== Summary ==

Series 27488v17 i915 PMU and engine busy stats
https://patchwork.freedesktop.org/api/1.0/series/27488/revisions/17/mbox/

Test gem_exec_suspend:

        Subgroup basic-s3:
                pass       -> INCOMPLETE (fi-byt-j1900)
                pass       -> INCOMPLETE (fi-glk-1)
                pass       -> INCOMPLETE (fi-cnl-y) fdo#103070

fdo#103070 https://bugs.freedesktop.org/show_bug.cgi?id=103070

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:456s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:477s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:399s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:579s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:287s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:526s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:525s
fi-byt-j1900     total:118  pass:96   dwarn:0   dfail:0   fail:0   skip:21 
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:516s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:562s
fi-cnl-y         total:118  pass:97   dwarn:0   dfail:0   fail:0   skip:20 
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:439s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:276s
fi-glk-1         total:118  pass:96   dwarn:0   dfail:0   fail:0   skip:21 
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:441s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:463s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:507s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:475s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:505s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:579s
fi-kbl-7567u     total:289  pass:265  dwarn:4   dfail:0   fail:0   skip:20  time:491s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:596s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:491s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:662s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:538s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:521s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:469s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:584s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:432s

fi-pnv-d510 failed to connect after reboot

36e0e803d3d7fb3d74e9086ad7c749123661589e drm-tip: 2017y-10m-11d-11h-31m-33s UTC integration manifest db3f415f88cf drm/i915/pmu: Add RC6 residency metrics
33009a52f106 drm/i915: Convert intel_rc6_residency_us to ns
e656a0d60d48 drm/i915/pmu: Add interrupt count metric
ffcd72f22bc7 drm/i915/pmu: Wire up engine busy stats to PMU
2f229eb2b5c0 drm/i915: Engine busy time tracking
6ae7caca1569 drm/i915: Wrap context schedule notification
3d949452bedc drm/i915/pmu: Suspend sampling when GPU is idle
f7931c3b3f7a drm/i915/pmu: Expose a PMU interface for perf queries
6f57d335b9df drm/i915: Extract intel_get_cagf

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_5992/
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#13 lore raw

✗ Fi.CI.BAT: failure for i915 PMU and engine busy stats (rev18)

In reply to Tvrtko Ursulin
== Series Details ==

== Series Details ==

Series: i915 PMU and engine busy stats (rev18)
URL : https://patchwork.freedesktop.org/series/27488/
State : failure

== Summary ==

Series 27488v18 i915 PMU and engine busy stats
https://patchwork.freedesktop.org/api/1.0/series/27488/revisions/18/mbox/

Test gem_exec_suspend:

        Subgroup basic-s3:
                pass       -> INCOMPLETE (fi-pnv-d510)
                pass       -> INCOMPLETE (fi-byt-j1900)
                pass       -> INCOMPLETE (fi-glk-1)
fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:445s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:453s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:369s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:528s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:262s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:491s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:494s
fi-byt-j1900     total:118  pass:96   dwarn:0   dfail:0   fail:0   skip:21 
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:473s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:558s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:416s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:250s
fi-glk-1         total:118  pass:96   dwarn:0   dfail:0   fail:0   skip:21 
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:422s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:430s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:490s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:457s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:476s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:573s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:474s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:580s
fi-pnv-d510      total:118  pass:76   dwarn:0   dfail:0   fail:0   skip:41 
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:444s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:646s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:520s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:491s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:455s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:562s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:420s

e4dedb9e7c81401239b67d07ed8ed07fcd2f5129 drm-tip: 2017y-10m-17d-07h-45m-57s UTC integration manifest 95bcd4c75126 drm/i915/pmu: Add RC6 residency metrics
732e239cdac9 drm/i915: Convert intel_rc6_residency_us to ns
1c77eab32884 drm/i915/pmu: Add interrupt count metric
3d1452e467e6 drm/i915/pmu: Wire up engine busy stats to PMU
8700ee5a9dd9 drm/i915: Engine busy time tracking
ee1a2044fdd9 drm/i915: Wrap context schedule notification
be2753dcb505 drm/i915/pmu: Suspend sampling when GPU is idle
d49f49c0559f drm/i915/pmu: Expose a PMU interface for perf queries
17e2471ae9e5 drm/i915: Extract intel_get_cagf

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_6068/
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#14 lore raw

Re: ✗ Fi.CI.BAT: failure for i915 PMU and engine busy stats (rev18)

Quoting Patchwork (2017-10-17 12:12:55)

Quoted 8 lines

== Series Details ==

Series: i915 PMU and engine busy stats (rev18)
URL : https://patchwork.freedesktop.org/series/27488/
State : failure

== Summary ==

Quoted 8 lines

Series 27488v18 i915 PMU and engine busy stats
https://patchwork.freedesktop.org/api/1.0/series/27488/revisions/18/mbox/

Test gem_exec_suspend:

        Subgroup basic-s3:
                pass       -> INCOMPLETE (fi-pnv-d510)
                pass       -> INCOMPLETE (fi-byt-j1900)
                pass       -> INCOMPLETE (fi-glk-1)

At least glk had pstore!

<6>[  251.557743] Disabling non-boot CPUs ...
<4>[  251.576367] IRQ 127: no longer affine to CPU1
<6>[  251.578495] smpboot: CPU 1 is now offline
<4>[  251.599991] IRQ 121: no longer affine to CPU2
<6>[  251.602337] smpboot: CPU 2 is now offline
<4>[  251.618470] INFO: trying to register non-static key.
<4>[  251.618472] the code is fine but needs lockdep annotation.
<4>[  251.618473] turning off the locking correctness validator.
<4>[  251.618481] CPU: 3 PID: 26 Comm: cpuhp/3 Tainted: G     U          4.14.0-rc5-CI-Patchwork_6068+ #1
<4>[  251.618483] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[  251.618486] Call Trace:
<4>[  251.618500]  dump_stack+0x68/0x9f
<4>[  251.618507]  register_lock_class+0x3fd/0x580
<4>[  251.618515]  ? __save_stack_trace+0x73/0xd0
<4>[  251.618522]  __lock_acquire+0xa4/0x1b00
<4>[  251.618527]  ? padata_cpu_prep_down+0x35/0x60
<4>[  251.618534]  ? __slab_free+0x3b4/0x540
<4>[  251.618539]  ? __this_cpu_preempt_check+0x13/0x20
<4>[  251.618545]  lock_acquire+0xb0/0x200
<4>[  251.618548]  ? lock_acquire+0xb0/0x200
<4>[  251.618552]  ? padata_cpu_prep_down+0x35/0x60
<4>[  251.618559]  __mutex_lock+0x86/0x9b0
<4>[  251.618562]  ? padata_cpu_prep_down+0x35/0x60
<4>[  251.618566]  ? padata_cpu_prep_down+0x35/0x60
<4>[  251.618570]  ? __lock_acquire+0x4ab/0x1b00
<4>[  251.618577]  mutex_lock_nested+0x1b/0x20
<4>[  251.618581]  ? mutex_lock_nested+0x1b/0x20
<4>[  251.618584]  padata_cpu_prep_down+0x35/0x60
<4>[  251.618590]  cpuhp_invoke_callback+0x161/0xbf0
<4>[  251.618594]  ? cpuhp_thread_fun+0x41/0x240
<4>[  251.618597]  ? padata_remove_cpu+0x80/0x80
<4>[  251.618602]  cpuhp_thread_fun+0x17b/0x240
<4>[  251.618609]  ? smpboot_thread_fn+0x2d/0x280
<4>[  251.618613]  smpboot_thread_fn+0x18a/0x280
<4>[  251.618617]  kthread+0x114/0x150
<4>[  251.618621]  ? sort_range+0x30/0x30
<4>[  251.618624]  ? kthread_create_on_node+0x40/0x40
<4>[  251.618630]  ret_from_fork+0x27/0x40
<3>[  251.618696] ODEBUG: assert_init not available (active state 0) object type: timer_list hint: ONEf+0x1741e/0xba963
<4>[  251.618737] ------------[ cut here ]------------
<4>[  251.618743] WARNING: CPU: 3 PID: 26 at lib/debugobjects.c:291 debug_print_object+0x76/0x80
<4>[  251.618746] Modules linked in: snd_hda_codec_realtek snd_hda_codec_generic i915 x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm mei_me r8169 prime_numbers mii mei i2c_hid pinctrl_geminilake pinctrl_intel
<4>[  251.618809] CPU: 3 PID: 26 Comm: cpuhp/3 Tainted: G     U          4.14.0-rc5-CI-Patchwork_6068+ #1
<4>[  251.618812] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[  251.618816] task: ffff88017ab5cec0 task.stack: ffffc90000140000
<4>[  251.618821] RIP: 0010:debug_print_object+0x76/0x80
<4>[  251.618825] RSP: 0018:ffffc90000143c78 EFLAGS: 00010296
<4>[  251.618830] RAX: 0000000000000065 RBX: ffffc90000143ca0 RCX: 0000000000000000
<4>[  251.618833] RDX: 0000000080000001 RSI: 0000000000000001 RDI: ffffffff810ee876
<4>[  251.618836] RBP: ffffc90000143c90 R08: 0000000000000001 R09: 0000000000000000
<4>[  251.618839] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff81e4f5e0
<4>[  251.618843] R13: ffffffff81cc1c4b R14: ffffffff82d63ba8 R15: 0000000000000000
<4>[  251.618847] FS:  0000000000000000(0000) GS:ffff88017fd80000(0000) knlGS:0000000000000000
<4>[  251.618850] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[  251.618854] CR2: 00007f830b4ddd70 CR3: 00000001733f7000 CR4: 00000000003406e0
<4>[  251.618857] Call Trace:
<4>[  251.618865]  debug_object_assert_init+0x129/0x140
<4>[  251.618873]  ? del_timer_sync+0x5/0xb0
<4>[  251.618880]  try_to_del_timer_sync+0x1f/0x70
<4>[  251.618884]  ? try_to_del_timer_sync+0x1f/0x70
<4>[  251.618889]  del_timer_sync+0x8c/0xb0
<4>[  251.618895]  padata_flush_queues+0x5a/0xc0
<4>[  251.618901]  padata_replace+0x58/0x110
<4>[  251.618907]  __padata_remove_cpu+0x82/0xb0
<4>[  251.618913]  padata_cpu_prep_down+0x40/0x60
<4>[  251.618919]  cpuhp_invoke_callback+0x161/0xbf0
<4>[  251.618925]  ? cpuhp_thread_fun+0x41/0x240
<4>[  251.618929]  ? padata_remove_cpu+0x80/0x80
<4>[  251.618937]  cpuhp_thread_fun+0x17b/0x240
<4>[  251.618944]  ? smpboot_thread_fn+0x2d/0x280
<4>[  251.618950]  smpboot_thread_fn+0x18a/0x280
<4>[  251.618956]  kthread+0x114/0x150
<4>[  251.618961]  ? sort_range+0x30/0x30
<4>[  251.618965]  ? kthread_create_on_node+0x40/0x40
<4>[  251.618973]  ret_from_fork+0x27/0x40
<4>[  251.618983] Code: 49 89 c1 8b 43 10 8b 4b 14 4c 89 ee 4d 8b 04 24 48 c7 c7 68 1a cc 81 83 05 1f 4e 87 01 01 48 8b 14 c5 80 c8 a6 81 e8 db ee c5 ff <0f> ff eb a5 45 31 c9 eb cf 90 55 48 89 e5 41 57 41 56 41 55 41 
<4>[  251.619153] ---[ end trace b31bdc7f94776dac ]---
<4>[  251.619178] ------------[ cut here ]------------
<4>[  251.619186] WARNING: CPU: 3 PID: 26 at mm/vmalloc.c:245 vmalloc_to_page+0x137/0x140
<4>[  251.619189] Modules linked in: snd_hda_codec_realtek snd_hda_codec_generic i915 x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm mei_me r8169 prime_numbers mii mei i2c_hid pinctrl_geminilake pinctrl_intel
<4>[  251.619242] CPU: 3 PID: 26 Comm: cpuhp/3 Tainted: G     U  W       4.14.0-rc5-CI-Patchwork_6068+ #1
<4>[  251.619245] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[  251.619248] task: ffff88017ab5cec0 task.stack: ffffc90000140000
<4>[  251.619253] RIP: 0010:vmalloc_to_page+0x137/0x140
<4>[  251.619257] RSP: 0018:ffffc90000143d48 EFLAGS: 00010082
<4>[  251.619262] RAX: 8000000101a001e3 RBX: ffff88017fff9a00 RCX: 8000000101a001e3
<4>[  251.619265] RDX: 00003fffffe00000 RSI: ffff880000000000 RDI: ffff880101be3c00
<4>[  251.619268] RBP: ffffc90000143d48 R08: 80000000000001e3 R09: ffffc000001fffff
<4>[  251.619271] R10: 000000010f11e000 R11: ffffffff811bd999 R12: ffff880101a63c00
<4>[  251.619274] R13: ffffffff81e63c00 R14: 0000000000000287 R15: 0000000000000000
<4>[  251.619278] FS:  0000000000000000(0000) GS:ffff88017fd80000(0000) knlGS:0000000000000000
<4>[  251.619282] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[  251.619285] CR2: 00007f830b4ddd70 CR3: 00000001733f7000 CR4: 00000000003406e0
<4>[  251.619287] Call Trace:
<4>[  251.619299]  free_percpu+0x120/0x290
<4>[  251.619306]  padata_replace+0x62/0x110
<4>[  251.619312]  __padata_remove_cpu+0x82/0xb0
<4>[  251.619317]  padata_cpu_prep_down+0x40/0x60
<4>[  251.619324]  cpuhp_invoke_callback+0x161/0xbf0
<4>[  251.619329]  ? cpuhp_thread_fun+0x41/0x240
<4>[  251.619334]  ? padata_remove_cpu+0x80/0x80
<4>[  251.619341]  cpuhp_thread_fun+0x17b/0x240
<4>[  251.619348]  ? smpboot_thread_fn+0x2d/0x280
<4>[  251.619353]  smpboot_thread_fn+0x18a/0x280
<4>[  251.619359]  kthread+0x114/0x150
<4>[  251.619364]  ? sort_range+0x30/0x30
<4>[  251.619368]  ? kthread_create_on_node+0x40/0x40
<4>[  251.619376]  ret_from_fork+0x27/0x40
<4>[  251.619386] Code: 01 01 00 00 74 1b 48 c1 e0 12 48 ba 00 00 00 00 00 ea ff ff 48 c1 e8 1e 48 c1 e0 06 48 01 d0 5d c3 31 c0 5d c3 0f ff 31 c0 5d c3 <0f> ff 31 c0 5d c3 0f 1f 00 0f 1f 44 00 00 55 48 89 e5 e8 b2 fe 
<4>[  251.619529] ---[ end trace b31bdc7f94776dad ]---
<1>[  251.619540] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
<1>[  251.619550] IP: free_percpu+0x120/0x290
<6>[  251.619554] PGD 0 P4D 0 
<4>[  251.619562] Oops: 0000 [#1] PREEMPT SMP
<4>[  251.619565] Modules linked in: snd_hda_codec_realtek snd_hda_codec_generic i915 x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm mei_me r8169 prime_numbers mii mei i2c_hid pinctrl_geminilake pinctrl_intel
<4>[  251.619617] CPU: 3 PID: 26 Comm: cpuhp/3 Tainted: G     U  W       4.14.0-rc5-CI-Patchwork_6068+ #1
<4>[  251.619620] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[  251.619623] task: ffff88017ab5cec0 task.stack: ffffc90000140000
<4>[  251.619628] RIP: 0010:free_percpu+0x120/0x290
<4>[  251.619631] RSP: 0018:ffffc90000143d58 EFLAGS: 00010046
<4>[  251.619637] RAX: 0000000000000000 RBX: ffff88017fff9a00 RCX: 8000000101a001e3
<4>[  251.619640] RDX: 00003fffffe00000 RSI: ffff880000000000 RDI: ffff880101be3c00
<4>[  251.619643] RBP: ffffc90000143d80 R08: 80000000000001e3 R09: ffffc000001fffff
<4>[  251.619646] R10: 000000010f11e000 R11: ffffffff811bd999 R12: ffff880101a63c00
<4>[  251.619649] R13: ffffffff81e63c00 R14: 0000000000000287 R15: 0000000000000000
<4>[  251.619653] FS:  0000000000000000(0000) GS:ffff88017fd80000(0000) knlGS:0000000000000000
<4>[  251.619656] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[  251.619659] CR2: 0000000000000010 CR3: 00000001733f7000 CR4: 00000000003406e0
<4>[  251.619662] Call Trace:
<4>[  251.619669]  padata_replace+0x62/0x110
<4>[  251.619675]  __padata_remove_cpu+0x82/0xb0
<4>[  251.619681]  padata_cpu_prep_down+0x40/0x60
<4>[  251.619687]  cpuhp_invoke_callback+0x161/0xbf0
<4>[  251.619692]  ? cpuhp_thread_fun+0x41/0x240
<4>[  251.619697]  ? padata_remove_cpu+0x80/0x80
<4>[  251.619704]  cpuhp_thread_fun+0x17b/0x240
<4>[  251.619711]  ? smpboot_thread_fn+0x2d/0x280
<4>[  251.619716]  smpboot_thread_fn+0x18a/0x280
<4>[  251.619722]  kthread+0x114/0x150
<4>[  251.619727]  ? sort_range+0x30/0x30
<4>[  251.619731]  ? kthread_create_on_node+0x40/0x40
<4>[  251.619739]  ret_from_fork+0x27/0x40
<4>[  251.619749] Code: 63 43 50 48 01 d0 49 39 c4 0f 83 72 ff ff ff 48 8b 15 bd 51 b7 00 4c 89 e7 65 8b 05 b3 c6 e4 7e 48 98 48 03 3c c2 e8 a0 2a 02 00 <48> 8b 58 10 48 8b 53 20 e9 49 ff ff ff 65 8b 05 94 c6 e4 7e 89 
<1>[  251.619894] RIP: free_percpu+0x120/0x290 RSP: ffffc90000143d58
<4>[  251.619897] CR2: 0000000000000010
<4>[  251.619903] ---[ end trace b31bdc7f94776dae ]---
<3>[  251.729960] BUG: sleeping function called from invalid context at ./include/linux/percpu-rwsem.h:33
<3>[  251.729963] in_atomic(): 1, irqs_disabled(): 1, pid: 26, name: cpuhp/3
<4>[  251.729964] INFO: lockdep is turned off.
<4>[  251.729965] irq event stamp: 2999
<4>[  251.729970] hardirqs last  enabled at (2999): [<ffffffff811fd794>] __slab_free+0x3b4/0x540
<4>[  251.729972] hardirqs last disabled at (2998): [<ffffffff811fd4f4>] __slab_free+0x114/0x540
<4>[  251.729975] softirqs last  enabled at (2752): [<ffffffff819122d6>] __do_softirq+0x3a6/0x4ae
<4>[  251.729978] softirqs last disabled at (2727): [<ffffffff8108619e>] irq_exit+0xae/0xc0
<3>[  251.729979] Preemption disabled at:
<4>[  251.729983] [<ffffffff811bd999>] free_percpu+0x39/0x290
<4>[  251.729987] CPU: 3 PID: 26 Comm: cpuhp/3 Tainted: G     UD W       4.14.0-rc5-CI-Patchwork_6068+ #1
<4>[  251.729988] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[  251.729989] Call Trace:
<4>[  251.729997]  dump_stack+0x68/0x9f
<4>[  251.729999]  ___might_sleep+0x1e5/0x240
<4>[  251.730001]  __might_sleep+0x4a/0x80
<4>[  251.730005]  exit_signals+0x24/0x2a0
<4>[  251.730008]  ? smpboot_thread_fn+0x18a/0x280
<4>[  251.730009]  do_exit+0x9a/0xca0
<4>[  251.730011]  ? kthread+0x114/0x150
<4>[  251.730013]  ? sort_range+0x30/0x30
<4>[  251.730015]  rewind_stack_do_exit+0x17/0x20
<6>[  251.730092] note: cpuhp/3[26] exited with preempt_count 1
<2>[  337.964669] softdog: Initiating panic
<0>[  337.964674] Kernel panic - not syncing: Software Watchdog Timer expired
<0>[  337.964698] Kernel Offset: disabled

All look like a bug you may have tickled rather than caused. Though I'd kasan for a use-after-free. But an odd mixtures of Atoms; presuming they are all the same.
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx