All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@linux.intel.com>
To: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>,
	intel-gfx@lists.freedesktop.org, John.C.Harrison@Intel.com,
	alan.previn.teres.alexis@intel.com
Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915/pmu: Use PM timestamp instead of RING TIMESTAMP for reference
Date: Tue, 25 Jan 2022 07:47:34 +0200	[thread overview]
Message-ID: <87r18w1i4p.fsf@intel.com> (raw)
In-Reply-To: <20220125020124.788679-1-umesh.nerlige.ramappa@intel.com>

On Mon, 24 Jan 2022, Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com> wrote:
> All timestamps returned by GuC for GuC PMU busyness are captured from
> GUC PM TIMESTAMP. Since this timestamp does not tick when GuC goes idle,
> kmd uses RING_TIMESTAMP to measure busyness of an engine with an active
> context. In further stress testing, the MMIO read of the RING_TIMESTAMP
> is seen to cause a rare hang. Resolve the issue by using gt specific
> timestamp from PM which is in sync with the GuC PM timestamp.
>
> Fixes: 77cdd054dd2c ("drm/i915/pmu: Connect engine busyness stats from GuC to pmu")
> Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h        |  5 ++
>  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 56 ++++++++++++++-----
>  drivers/gpu/drm/i915/i915_reg.h               |  3 +-
>  3 files changed, 50 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index d59bbf49d1c2..697d9d66acef 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> @@ -215,6 +215,11 @@ struct intel_guc {
>  		 * context usage for overflows.
>  		 */
>  		struct delayed_work work;
> +
> +		/**
> +		 * @shift: Right shift value for the gpm timestamp
> +		 */
> +		u32 shift;
>  	} timestamp;
>  
>  #ifdef CONFIG_DRM_I915_SELFTEST
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index 1331ff91c5b0..66760f5df0c1 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -1150,23 +1150,51 @@ static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
>  	}
>  }
>  
> -static void guc_update_pm_timestamp(struct intel_guc *guc,
> -				    struct intel_engine_cs *engine,
> -				    ktime_t *now)
> +static u32 gpm_timestamp_shift(struct intel_gt *gt)
>  {
> -	u32 gt_stamp_now, gt_stamp_hi;
> +	intel_wakeref_t wakeref;
> +	u32 reg, shift;
> +
> +	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
> +		reg = intel_uncore_read(gt->uncore, RPM_CONFIG0);
> +
> +	shift = (reg & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
> +		GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT;
> +
> +	return 3 - shift;
> +}
> +
> +static u64 gpm_timestamp(struct intel_gt *gt)
> +{
> +	u32 lo, hi, old_hi, loop = 0;
> +
> +	hi = intel_uncore_read(gt->uncore, MISC_STATUS1);
> +	do {
> +		lo = intel_uncore_read(gt->uncore, MISC_STATUS0);
> +		old_hi = hi;
> +		hi = intel_uncore_read(gt->uncore, MISC_STATUS1);
> +	} while (old_hi != hi && loop++ < 2);
> +
> +	return ((u64)hi << 32) | lo;
> +}

See intel_uncore_read64_2x32().

> +
> +static void guc_update_pm_timestamp(struct intel_guc *guc, ktime_t *now)
> +{
> +	struct intel_gt *gt = guc_to_gt(guc);
> +	u32 gt_stamp_lo, gt_stamp_hi;
> +	u64 gpm_ts;
>  
>  	lockdep_assert_held(&guc->timestamp.lock);
>  
>  	gt_stamp_hi = upper_32_bits(guc->timestamp.gt_stamp);
> -	gt_stamp_now = intel_uncore_read(engine->uncore,
> -					 RING_TIMESTAMP(engine->mmio_base));
> +	gpm_ts = gpm_timestamp(gt) >> guc->timestamp.shift;
> +	gt_stamp_lo = lower_32_bits(gpm_ts);
>  	*now = ktime_get();
>  
> -	if (gt_stamp_now < lower_32_bits(guc->timestamp.gt_stamp))
> +	if (gt_stamp_lo < lower_32_bits(guc->timestamp.gt_stamp))
>  		gt_stamp_hi++;
>  
> -	guc->timestamp.gt_stamp = ((u64)gt_stamp_hi << 32) | gt_stamp_now;
> +	guc->timestamp.gt_stamp = ((u64)gt_stamp_hi << 32) | gt_stamp_lo;
>  }
>  
>  /*
> @@ -1210,7 +1238,7 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
>  		stats_saved = *stats;
>  		gt_stamp_saved = guc->timestamp.gt_stamp;
>  		guc_update_engine_gt_clks(engine);
> -		guc_update_pm_timestamp(guc, engine, now);
> +		guc_update_pm_timestamp(guc, now);
>  		intel_gt_pm_put_async(gt);
>  		if (i915_reset_count(gpu_error) != reset_count) {
>  			*stats = stats_saved;
> @@ -1242,8 +1270,8 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
>  
>  	spin_lock_irqsave(&guc->timestamp.lock, flags);
>  
> +	guc_update_pm_timestamp(guc, &unused);
>  	for_each_engine(engine, gt, id) {
> -		guc_update_pm_timestamp(guc, engine, &unused);
>  		guc_update_engine_gt_clks(engine);
>  		engine->stats.guc.prev_total = 0;
>  	}
> @@ -1260,10 +1288,11 @@ static void __update_guc_busyness_stats(struct intel_guc *guc)
>  	ktime_t unused;
>  
>  	spin_lock_irqsave(&guc->timestamp.lock, flags);
> -	for_each_engine(engine, gt, id) {
> -		guc_update_pm_timestamp(guc, engine, &unused);
> +
> +	guc_update_pm_timestamp(guc, &unused);
> +	for_each_engine(engine, gt, id)
>  		guc_update_engine_gt_clks(engine);
> -	}
> +
>  	spin_unlock_irqrestore(&guc->timestamp.lock, flags);
>  }
>  
> @@ -1757,6 +1786,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
>  	spin_lock_init(&guc->timestamp.lock);
>  	INIT_DELAYED_WORK(&guc->timestamp.work, guc_timestamp_ping);
>  	guc->timestamp.ping_delay = (POLL_TIME_CLKS / gt->clock_frequency + 1) * HZ;
> +	guc->timestamp.shift = gpm_timestamp_shift(gt);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 23b7c6930453..655517eb90ab 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1848,7 +1848,8 @@
>  #define BLT_HWS_PGA_GEN7	_MMIO(0x04280)
>  #define VEBOX_HWS_PGA_GEN7	_MMIO(0x04380)
>  
> -#define GUCPMTIMESTAMP          _MMIO(0xC3E8)
> +#define MISC_STATUS0		_MMIO(0xA500)
> +#define MISC_STATUS1		_MMIO(0xA504)
>  
>  #define GEN7_TLB_RD_ADDR	_MMIO(0x4700)

-- 
Jani Nikula, Intel Open Source Graphics Center

  parent reply	other threads:[~2022-01-25  5:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-25  2:01 [Intel-gfx] [PATCH 1/2] drm/i915/pmu: Use PM timestamp instead of RING TIMESTAMP for reference Umesh Nerlige Ramappa
2022-01-25  2:01 ` [Intel-gfx] [PATCH 2/2] drm/i915/pmu: Fix KMD and GuC race on accessing busyness Umesh Nerlige Ramappa
2022-01-26 20:06   ` [Intel-gfx] [2/2] " Teres Alexis, Alan Previn
2022-01-25  2:24 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [1/2] drm/i915/pmu: Use PM timestamp instead of RING TIMESTAMP for reference Patchwork
2022-01-25  2:54 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-01-25  5:47 ` Jani Nikula [this message]
2022-01-26 10:18   ` [Intel-gfx] [PATCH 1/2] " Tvrtko Ursulin
2022-01-25  7:23 ` [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [1/2] " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r18w1i4p.fsf@intel.com \
    --to=jani.nikula@linux.intel.com \
    --cc=John.C.Harrison@Intel.com \
    --cc=alan.previn.teres.alexis@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=umesh.nerlige.ramappa@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.