diff mbox series

[4/4] drm/i915/display: Add cdclk checks to atomic check

Message ID 20220315194712.2113450-5-anusha.srivatsa@intel.com (mailing list archive)
State New, archived
Headers show
Series Add CDCLK checks to atomic check phase | expand

Commit Message

Srivatsa, Anusha March 15, 2022, 7:47 p.m. UTC
Checking cdclk conditions during atomic check and preparing
for commit phase so we can have atomic commit as simple
as possible. Add the specific steps to be taken during
cdclk changes, prepare for squashing, crawling and modeset
scenarios.

v2: Add intel_cdclk_modeset() similar to intel_cdclk_squash()
and intel_cdclk_crawl().

Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 115 +++++++++++++++------
 1 file changed, 81 insertions(+), 34 deletions(-)

Comments

Oliver Sang March 25, 2022, 8:06 a.m. UTC | #1
Greeting,

FYI, we noticed the following commit (built with gcc-9):

commit: 0936eaf045dff09fd4e51f6e871226aef65a9ad5 ("[Intel-gfx] [PATCH 4/4] drm/i915/display: Add cdclk checks to atomic check")
url: https://github.com/intel-lab-lkp/linux/commits/Anusha-Srivatsa/drm-i915-display-Add-CDCLK-actions-to-intel_cdclk_state/20220316-044745
patch link: https://lore.kernel.org/intel-gfx/20220315194712.2113450-5-anusha.srivatsa@intel.com

in testcase: igt
version: igt-x86_64-0fcd59ad-1_20220320
with following parameters:

	group: group-20
	ucode: 0xc2



on test machine: 20 threads 1 sockets Commet Lake with 16G memory

caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace):



If you fix the issue, kindly add following tag
Reported-by: kernel test robot <oliver.sang@intel.com>



[   41.187164][ T1875] [IGT] kms_plane_scaling: starting subtest downscale-with-pixel-format-factor-0-5
[   41.189354][  T504] ext4_io_end_vec        0      0     48   85    1 : tunables    0    0    0 : slabdata      0      0      0
[   41.190178][ T1875] [IGT] kms_plane_scaling: starting dynamic subtest pipe-A-HDMI-A-2-downscale-with-pixel-format
[   41.199300][  T504]
[   41.200720][  T504] ext4_io_end            0      0     96   42    1 : tunables    0    0    0 : slabdata      0      0      0
[   41.212146][ T1875] general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
[   41.220991][  T504]
[   41.223199][ T1875] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
[   41.223201][ T1875] CPU: 6 PID: 1875 Comm: kms_plane_scali Not tainted 5.17.0-rc6-01408-g0936eaf045df #1
[   41.223204][ T1875] Hardware name: Intel Corporation CometLake Client Platform/CometLake S UDIMM (ERB/CRB), BIOS CMLSFWR1.R00.2212.D00.2104290922 04/29/2021
[   41.236082][  T504] ext4_bio_post_read_ctx    128    128     64   64    1 : tunables    0    0    0 : slabdata      2      2      0
[ 41.246022][ T1875] RIP: 0010:intel_modeset_calc_cdclk (kbuild/src/consumer/drivers/gpu/drm/i915/display/intel_cdclk.c:2031 kbuild/src/consumer/drivers/gpu/drm/i915/display/intel_cdclk.c:2843) i915
[   41.248233][  T504]
[ 41.256508][ T1875] Code: 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 5e 0a 00 00 48 b8 00 00 00 00 00 fc ff df 48 8b 6d 08 48 8d 7d 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 5f 0a 00 00 48 8b 45 08 48 89 ef 4c 89 0c 24 48
All code
========
   0:	48 89 fa             	mov    %rdi,%rdx
   3:	48 c1 ea 03          	shr    $0x3,%rdx
   7:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1)
   b:	0f 85 5e 0a 00 00    	jne    0xa6f
  11:	48 b8 00 00 00 00 00 	movabs $0xdffffc0000000000,%rax
  18:	fc ff df 
  1b:	48 8b 6d 08          	mov    0x8(%rbp),%rbp
  1f:	48 8d 7d 08          	lea    0x8(%rbp),%rdi
  23:	48 89 fa             	mov    %rdi,%rdx
  26:	48 c1 ea 03          	shr    $0x3,%rdx
  2a:*	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1)		<-- trapping instruction
  2e:	0f 85 5f 0a 00 00    	jne    0xa93
  34:	48 8b 45 08          	mov    0x8(%rbp),%rax
  38:	48 89 ef             	mov    %rbp,%rdi
  3b:	4c 89 0c 24          	mov    %r9,(%rsp)
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1)
   4:	0f 85 5f 0a 00 00    	jne    0xa69
   a:	48 8b 45 08          	mov    0x8(%rbp),%rax
   e:	48 89 ef             	mov    %rbp,%rdi
  11:	4c 89 0c 24          	mov    %r9,(%rsp)
  15:	48                   	rex.W
[   41.256510][ T1875] RSP: 0018:ffffc900045bf8b0 EFLAGS: 00010202
[   41.256512][ T1875] RAX: dffffc0000000000 RBX: ffff88844f31ea00 RCX: 000000000005265c
[   41.267534][  T504] ext4_pending_reservation      0      0     48   85    1 : tunables    0    0    0 : slabdata      0      0      0
[   41.280019][ T1875] RDX: 0000000000000001 RSI: ffffc900045bfc38 RDI: 0000000000000008
[   41.280021][ T1875] RBP: 0000000000000000 R08: 000000000006ddd0 R09: ffff88844f31ea2c
[   41.280022][ T1875] R10: ffff888116fc072c R11: fffff520008b7ee4 R12: ffff8881057e1000
[   41.291865][  T504]
[   41.298844][ T1875] R13: ffff888116fc0000 R14: 0000000000000000 R15: 00000000ffffffff
[   41.298846][ T1875] FS:  00007fdbcc21cc00(0000) GS:ffff8883a4100000(0000) knlGS:0000000000000000
[   41.298848][ T1875] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   41.298849][ T1875] CR2: 000056393a1f25d8 CR3: 0000000450a4e006 CR4: 00000000003706e0
[   41.298850][ T1875] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   41.298851][ T1875] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   41.302466][  T504] ext4_extent_status      0      0     56   73    1 : tunables    0    0    0 : slabdata      0      0      0
[   41.320531][ T1875] Call Trace:
[   41.320532][ T1875]  <TASK>
[ 41.320533][ T1875] intel_atomic_check (kbuild/src/consumer/drivers/gpu/drm/i915/display/intel_display.c:7831) i915
[   41.326469][  T504]
[ 41.334310][ T1875] ? skl_plane_format_mod_supported (kbuild/src/consumer/drivers/gpu/drm/i915/display/skl_universal_plane.c:1921) i915
[   41.347684][  T504] mbcache                0      0     88   46    1 : tunables    0    0    0 : slabdata      0      0      0


To reproduce:

        git clone https://github.com/intel/lkp-tests.git
        cd lkp-tests
        sudo bin/lkp install job.yaml           # job file is attached in this email
        bin/lkp split-job --compatible job.yaml # generate the yaml file for lkp run
        sudo bin/lkp run generated-yaml-file

        # if come across any failure that blocks the test,
        # please remove ~/.lkp and /lkp dir to run from a clean state.
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 3007710984d4..1efeee4200f0 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1700,12 +1700,23 @@  static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 			  const struct intel_cdclk_config *cdclk_config,
 			  enum pipe pipe)
 {
+	struct intel_atomic_state *state;
+	struct intel_cdclk_state *new_cdclk_state;
+	struct cdclk_step *cdclk_steps;
+	struct intel_cdclk_state *cdclk_state;
 	int cdclk = cdclk_config->cdclk;
 	int vco = cdclk_config->vco;
+	u32 squash_ctl = 0;
 	u32 val;
 	u16 waveform;
 	int clock;
 	int ret;
+	int i;
+
+	cdclk_state =  to_intel_cdclk_state(dev_priv->cdclk.obj.state);
+	state = cdclk_state->base.state;
+	new_cdclk_state = intel_atomic_get_new_cdclk_state(state);
+	cdclk_steps = new_cdclk_state->steps;
 
 	/* Inform power controller of upcoming frequency change. */
 	if (DISPLAY_VER(dev_priv) >= 11)
@@ -1728,45 +1739,48 @@  static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		return;
 	}
 
-	if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) {
-		if (dev_priv->cdclk.hw.vco != vco)
+	for (i = 0; i < MAX_CDCLK_ACTIONS; i++) {
+		switch (cdclk_steps[i].action) {
+		case INTEL_CDCLK_MODESET:
+			if (DISPLAY_VER(dev_priv) >= 11) {
+				if (dev_priv->cdclk.hw.vco != 0 &&
+				    dev_priv->cdclk.hw.vco != vco)
+					icl_cdclk_pll_disable(dev_priv);
+
+				if (dev_priv->cdclk.hw.vco != vco)
+					icl_cdclk_pll_enable(dev_priv, vco);
+			} else {
+				if (dev_priv->cdclk.hw.vco != 0 &&
+				    dev_priv->cdclk.hw.vco != vco)
+					bxt_de_pll_disable(dev_priv);
+
+				if (dev_priv->cdclk.hw.vco != vco)
+					bxt_de_pll_enable(dev_priv, vco);
+			}
+			clock = cdclk;
+			break;
+		case INTEL_CDCLK_CRAWL:
 			adlp_cdclk_pll_crawl(dev_priv, vco);
-	} else if (DISPLAY_VER(dev_priv) >= 11) {
-		if (dev_priv->cdclk.hw.vco != 0 &&
-		    dev_priv->cdclk.hw.vco != vco)
-			icl_cdclk_pll_disable(dev_priv);
-
-		if (dev_priv->cdclk.hw.vco != vco)
-			icl_cdclk_pll_enable(dev_priv, vco);
-	} else {
-		if (dev_priv->cdclk.hw.vco != 0 &&
-		    dev_priv->cdclk.hw.vco != vco)
-			bxt_de_pll_disable(dev_priv);
-
-		if (dev_priv->cdclk.hw.vco != vco)
-			bxt_de_pll_enable(dev_priv, vco);
-	}
-
-	waveform = cdclk_squash_waveform(dev_priv, cdclk);
-
-	if (waveform)
-		clock = vco / 2;
-	else
-		clock = cdclk;
-
-	if (has_cdclk_squasher(dev_priv)) {
-		u32 squash_ctl = 0;
-
-		if (waveform)
+			clock = cdclk;
+			break;
+		case INTEL_CDCLK_SQUASH:
+			waveform =  cdclk_squash_waveform(dev_priv, cdclk_steps[i].cdclk);
+			clock = vco / 2;
 			squash_ctl = CDCLK_SQUASH_ENABLE |
-				CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
-
-		intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl);
+			CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
+			intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl);
+			break;
+		case INTEL_CDCLK_NOOP:
+			break;
+		default:
+			MISSING_CASE(cdclk_steps[i].action);
+			break;
+		}
 	}
 
 	val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) |
-		bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
-		skl_cdclk_decimal(cdclk);
+	      bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
+	      skl_cdclk_decimal(cdclk);
 
 	/*
 	 * Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -1956,6 +1970,7 @@  static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv,
 				  struct intel_cdclk_state *b)
 {
 	int a_div, b_div;
+	struct cdclk_step *cdclk_transition = b->steps;
 
 	if (!HAS_CDCLK_CRAWL(dev_priv))
 		return false;
@@ -1967,6 +1982,11 @@  static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv,
 	a_div = DIV_ROUND_CLOSEST(a->actual.vco, a->actual.cdclk);
 	b_div = DIV_ROUND_CLOSEST(b->actual.vco, b->actual.cdclk);
 
+	cdclk_transition[0].action = INTEL_CDCLK_CRAWL;
+	cdclk_transition[0].cdclk = b->actual.cdclk;
+	cdclk_transition[1].action = INTEL_CDCLK_NOOP;
+	cdclk_transition[1].cdclk = b->actual.cdclk;
+
 	return a->actual.vco != 0 && b->actual.vco != 0 &&
 		a->actual.vco != b->actual.vco &&
 		a_div == b_div &&
@@ -1978,6 +1998,7 @@  static bool intel_cdclk_squash(struct drm_i915_private *dev_priv,
 			       struct intel_cdclk_state *b)
 {
 
+	struct cdclk_step *cdclk_transition = b->steps;
 	/*
 	 * FIXME should store a bit more state in intel_cdclk_config
 	 * to differentiate squasher vs. cd2x divider properly. For
@@ -1987,12 +2008,35 @@  static bool intel_cdclk_squash(struct drm_i915_private *dev_priv,
 	if (!has_cdclk_squasher(dev_priv))
 		return false;
 
+	cdclk_transition[0].action = INTEL_CDCLK_SQUASH;
+	cdclk_transition[0].cdclk = b->actual.cdclk;
+	cdclk_transition[1].action = INTEL_CDCLK_NOOP;
+	cdclk_transition[1].cdclk = b->actual.cdclk;
+
 	return a->actual.cdclk != b->actual.cdclk &&
 		a->actual.vco != 0 &&
 		a->actual.vco == b->actual.vco &&
 		a->actual.ref == b->actual.ref;
 }
 
+static void intel_cdclk_modeset(struct drm_i915_private *i915,
+				const struct intel_cdclk_config *a,
+				const struct intel_cdclk_config *b)
+{
+	struct intel_cdclk_state *new_cdclk_state;
+	struct cdclk_step *cdclk_transition;
+	struct intel_cdclk_state *cdclk_state =  to_intel_cdclk_state(i915->cdclk.obj.state);
+	struct intel_atomic_state *state = cdclk_state->base.state;
+
+	new_cdclk_state = intel_atomic_get_new_cdclk_state(state);
+	cdclk_transition = new_cdclk_state->steps;
+
+	cdclk_transition[0].action = INTEL_CDCLK_MODESET;
+	cdclk_transition[0].cdclk = b->cdclk;
+	cdclk_transition[1].action = INTEL_CDCLK_NOOP;
+	cdclk_transition[1].cdclk = b->cdclk;
+}
+
 /**
  * intel_cdclk_needs_modeset - Determine if changong between the CDCLK
  *                             configurations requires a modeset on all pipes
@@ -2006,6 +2050,7 @@  static bool intel_cdclk_squash(struct drm_i915_private *dev_priv,
 bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a,
 			       const struct intel_cdclk_config *b)
 {
+
 	return a->cdclk != b->cdclk ||
 		a->vco != b->vco ||
 		a->ref != b->ref;
@@ -2795,6 +2840,8 @@  int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
 			    pipe_name(pipe));
 	} else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
 					     &new_cdclk_state->actual)) {
+		intel_cdclk_modeset(dev_priv, &old_cdclk_state->actual,
+				    &new_cdclk_state->actual);
 		/* All pipes must be switched off while we change the cdclk. */
 		ret = intel_modeset_all_pipes(state);
 		if (ret)