[Intel-gfx] [PATCH] drm/i915/pmu: Do not assume fixed hrtimer period
Chris Wilson
chris at chris-wilson.co.uk
Mon Jun 4 12:59:12 UTC 2018
Quoting Tvrtko Ursulin (2018-06-04 13:52:39)
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>
> As Chris has discovered on his Ivybridge, and later automated test runs
> have confirmed, on most of our platforms hrtimer faced with heavy GPU load
> ca occasionally become sufficiently imprecise to affect PMU sampling
s/ca/can/
> calculations.
>
> This means we cannot assume sampling frequency is what we asked for, but
> we need to measure the interval ourselves.
>
> This patch is similar to Chris' original proposal for per-engine counters,
> but instead of introducing a new set to work around the problem with
> frequency sampling, it swaps around the way internal frequency accounting
> is done. Instead of accumulating current frequency and dividing by
> sampling frequency on readout, it accumulates frequency scaled by each
> period.
My ulterior motive failed to win favour ;)
> Testcase: igt/perf_pmu/*busy* # snb, ivb, hsw
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Suggested-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
> @@ -237,14 +251,21 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
> {
> struct drm_i915_private *i915 =
> container_of(hrtimer, struct drm_i915_private, pmu.timer);
> + unsigned int period_ns;
> + ktime_t now;
>
> if (!READ_ONCE(i915->pmu.timer_enabled))
> return HRTIMER_NORESTART;
>
> - engines_sample(i915);
> - frequency_sample(i915);
> + now = ktime_get();
> + period_ns = ktime_to_ns(ktime_sub(now, i915->pmu.timer_last));
> + i915->pmu.timer_last = now;
Maybe worth a comment about the lag coming from the timer outweighs our
concern with using a single timestamp over multiple samplers, with
indeterminate delays due to forcewake.
> + engines_sample(i915, period_ns);
> + frequency_sample(i915, period_ns);
> +
> + hrtimer_forward(hrtimer, now, ns_to_ktime(PERIOD));
>
> - hrtimer_forward_now(hrtimer, ns_to_ktime(PERIOD));
> return HRTIMER_RESTART;
> }
>
> @@ -519,12 +540,12 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
> case I915_PMU_ACTUAL_FREQUENCY:
> val =
> div_u64(i915->pmu.sample[__I915_SAMPLE_FREQ_ACT].cur,
> - FREQUENCY);
> + 1000000 /* to MHz */);
USEC_PER_SECS /* to MHz */
Storage in sample[] is MHz.usec, so here we cancel out the usec to leave
MHz.
-Chris
More information about the Intel-gfx
mailing list