[Intel-gfx] [PATCH v5] drm/i915: Fix assert_plane() warning on bootup with external display

Shaikh, Azhar azhar.shaikh at intel.com
Fri Jun 29 17:54:34 UTC 2018



>-----Original Message-----
>From: Intel-gfx [mailto:intel-gfx-bounces at lists.freedesktop.org] On Behalf Of
>Shaikh, Azhar
>Sent: Friday, June 29, 2018 10:45 AM
>To: Ville Syrjälä <ville.syrjala at linux.intel.com>
>Cc: intel-gfx at lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH v5] drm/i915: Fix assert_plane() warning on
>bootup with external display
>
>
>
>>-----Original Message-----
>>From: Ville Syrjälä [mailto:ville.syrjala at linux.intel.com]
>>Sent: Friday, June 29, 2018 5:07 AM
>>To: Shaikh, Azhar <azhar.shaikh at intel.com>
>>Cc: intel-gfx at lists.freedesktop.org; Navare, Manasi D
>><manasi.d.navare at intel.com>
>>Subject: Re: [PATCH v5] drm/i915: Fix assert_plane() warning on bootup
>>with external display
>>
>>On Wed, Jun 27, 2018 at 05:11:05PM -0700, Azhar Shaikh wrote:
>>> On KBL, WHL RVPs, booting up with an external display connected,
>>> triggers below warning, when the BiOS brings up the external display too.
>>> This warning is not seen during hotplug.
>>>
>>> [    3.615226] ------------[ cut here ]------------
>>> [    3.619829] plane 1A assertion failure (expected on, current off)
>>> [    3.632039] WARNING: CPU: 2 PID: 354 at
>>drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
>>> [    3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0
>>op_mode iwlmvm
>>> [    3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel
>>bluetooth ecdh_generic
>>> [    3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-
>>g655af12d39c2 #3
>>> [    3.647165] Hardware name: Intel Corporation CoffeeLake Client
>>Platform/WhiskeyLake U DDR4 ERB, BIOS
>>CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
>>> [    3.684509] RIP: 0010:assert_plane+0x71/0xbb
>>> [    3.764451] Call Trace:
>>> [    3.766888]  intel_atomic_commit_tail+0xa97/0xb77
>>> [    3.771569]  intel_atomic_commit+0x26a/0x279
>>> [    3.771572]  drm_atomic_helper_set_config+0x5c/0x76
>>> [    3.780670]  __drm_mode_set_config_internal+0x66/0x109
>>> [    3.780672]  drm_mode_setcrtc+0x4c9/0x5cc
>>> [    3.780674]  ? drm_mode_getcrtc+0x162/0x162
>>> [    3.789774]  ? drm_mode_getcrtc+0x162/0x162
>>> [    3.798108]  drm_ioctl_kernel+0x8d/0xe4
>>> [    3.801926]  drm_ioctl+0x27d/0x368
>>> [    3.805311]  ? drm_mode_getcrtc+0x162/0x162
>>> [    3.805314]  ? selinux_file_ioctl+0x14e/0x199
>>> [    3.805317]  vfs_ioctl+0x21/0x2f
>>> [    3.813812]  do_vfs_ioctl+0x491/0x4b4
>>> [    3.813813]  ? security_file_ioctl+0x37/0x4b
>>> [    3.813816]  ksys_ioctl+0x55/0x75
>>> [    3.820672]  __x64_sys_ioctl+0x1a/0x1e
>>> [    3.820674]  do_syscall_64+0x51/0x5f
>>> [    3.820678]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>> [    3.828221] RIP: 0033:0x7b5e04953967
>>> [    3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX:
>>0000000000000010
>>> [    3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX:
>>00007b5e04953967
>>> [    3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI:
>>000000000000000f
>>> [    3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09:
>>0000000000000000
>>> [    3.835507] R10: 0000000000000070 R11: 0000000000000246 R12:
>>000000000000000f
>>> [    3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15:
>>00000000c06864a2
>>> [    3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48
>0f
>>44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f>
>>0b eb 2b 48
>>c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
>>> [    3.905845] WARNING: CPU: 2 PID: 354 at
>>drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
>>> [    3.920964] ---[ end trace dac692f4ac46391a ]---
>>>
>>> The warning is seen when mode_setcrtc() is called for pipeB during
>>> bootup and before we get a mode_setcrtc() for pipeA, while doing
>>> update_crtcs() in intel_atomic_commit_tail().
>>> Now since, plane1A is still active after commit, update_crtcs() is
>>> done for pipeA and eventually update_plane() for plane1A.
>>>
>>> intel_plane_state->ctl for plane1A is not updated since
>>> set_modecrtc() is called for pipeB. So intel_plane_state->ctl for plane 1A
>will be 0x0.
>>> So doing an update_plane() for plane1A, will result in clearing
>>> PLANE_CTL_ENABLE bit, and hence the warning.
>>>
>>> To fix this warning, force all active planes to recompute their
>>> states in probe.
>>>
>>> Changes in v5:
>>> - Drop drm_modeset_lock_all_ctx() since locks will be taken later.
>>>
>>> Changes in v4:
>>> - Handle locking in intel_initial_commit()
>>> - Move the for loop inside intel_initial_commit() so that
>>>   drm_atomic_commit() is called only once
>>> - Call intel_initial_commit() only for more than one active crtc on boot.
>>> - Save the return value of intel_initial_commit() and print a message in
>>>   case of an error
>>>
>>> Changes in v3:
>>> - Add comments
>>>
>>> Changes in v2:
>>> - Force all planes to recompute their states.(Ville Syrjälä)
>>> - Update the commit message
>>>
>>> Signed-off-by: Azhar Shaikh <azhar.shaikh at intel.com>
>>> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
>>> Cc: Radhakrishna Sripada <radhakrishna.sripada at intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/intel_display.c | 71
>>> +++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 69 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_display.c
>>> b/drivers/gpu/drm/i915/intel_display.c
>>> index 3709fa1b6318..866ebbac30e9 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>> @@ -15092,12 +15092,66 @@ static void
>>> intel_update_fdi_pll_freq(struct
>>drm_i915_private *dev_priv)
>>>  	DRM_DEBUG_DRIVER("FDI PLL freq=%d\n", dev_priv->fdi_pll_freq);
>>}
>>>
>>> +static int intel_initial_commit(struct drm_device *dev) {
>>> +	struct drm_atomic_state *state = NULL;
>>> +	struct drm_modeset_acquire_ctx ctx;
>>> +	struct drm_crtc_state *crtc_state;
>>> +	struct intel_crtc *intel_crtc;
>>
>>Just 'crtc'
>>
>>> +	int ret = 0;
>>> +
>>> +	state = drm_atomic_state_alloc(dev);
>>> +	if (!state)
>>> +		return -ENOMEM;
>>> +
>>> +	drm_modeset_acquire_init(&ctx, 0);
>>> +
>>> +retry:
>>> +	state->acquire_ctx = &ctx;
>>> +
>>> +	for_each_intel_crtc(dev, intel_crtc) {
>>> +		struct drm_crtc *crtc = &intel_crtc->base;
>>
>>Please don't add aliasing pointers for the same thing. It's much easier
>>to figure out what's what when you don't have N names for the same thing
>essentially.
>>I've been trying to slowly elimninate this kind of mess all over.
>>
>>Since you don't have any use for intel_ types in this function I'd just
>>go with
>>drm_for_each_crtc() here.
>
>Ok, will use that and get rid of all intel_types.
>
>>
>>> +
>>> +		crtc_state = drm_atomic_get_crtc_state(state, crtc);
>>> +		if (IS_ERR(crtc_state)) {
>>> +			ret = PTR_ERR(crtc_state);
>>> +			goto out;
>>> +		}
>>> +
>>> +		if (crtc_state->active) {
>>> +			ret = drm_atomic_add_affected_planes(state, crtc);
>>> +			if (ret)
>>> +				goto out;
>>> +		}
>>> +	}
>>> +
>>> +	ret = drm_atomic_commit(state);
>>> +	if (ret == -EDEADLK) {
>>> +		drm_atomic_state_clear(state);
>>> +		drm_modeset_backoff(&ctx);
>>> +		goto retry;
>>> +	}
>>> +
>>> +out:
>>
>>The label should be before the EDEADLK handling.
>
>Oh yes! Just checked get_crtc_state() or add_affected_planes() can return
>EDEADLK.
>Will move it before the EDEADLK handling.
>
>>
>>> +	if (state) {
>>
>>'state' will never be NULL.
>>
>>> +		drm_atomic_state_put(state);
>>> +		state = NULL;
>>
>>Pointless assignment.
>
>Ok, will call only drm_atomic_state_put() unconditionally.
>>
>>> +	}
>>> +
>>> +	drm_modeset_drop_locks(&ctx);
>>> +	drm_modeset_acquire_fini(&ctx);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>>  int intel_modeset_init(struct drm_device *dev)  {
>>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>>  	struct i915_ggtt *ggtt = &dev_priv->ggtt;
>>>  	enum pipe pipe;
>>>  	struct intel_crtc *crtc;
>>> +	u16 num_active_crtcs;
>>> +	int ret;
>>>
>>>  	dev_priv->modeset_wq =
>>alloc_ordered_workqueue("i915_modeset", 0);
>>>
>>> @@ -15172,8 +15226,6 @@ int intel_modeset_init(struct drm_device
>*dev)
>>>  		      INTEL_INFO(dev_priv)->num_pipes > 1 ? "s" : "");
>>>
>>>  	for_each_pipe(dev_priv, pipe) {
>>> -		int ret;
>>> -
>>>  		ret = intel_crtc_init(dev_priv, pipe);
>>>  		if (ret) {
>>>  			drm_mode_config_cleanup(dev);
>>> @@ -15203,6 +15255,8 @@ int intel_modeset_init(struct drm_device
>>> *dev)
>>>
>>>  		if (!crtc->active)
>>>  			continue;
>>> +		else
>>> +			num_active_crtcs++;
>>
>>This seems like needless complexity. There's no harm in doing this
>>thing unconditionally.
>>
>
>This was to avoid increase in boot time by 20-30msecs when there is only one
>crtc active during probe.

Which is the case most of the time.

>
>
>>>
>>>  		/*
>>>  		 * Note that reserving the BIOS fb up front prevents us @@ -
>>15222,6
>>> +15276,19 @@ int intel_modeset_init(struct drm_device *dev)
>>>  	}
>>>
>>>  	/*
>>> +	 * Only in case of more than one active crtc in probe, force
>>> +	 * all active planes to recompute their states. So that on
>>> +	 * mode_setcrtc after probe, all the intel_plane_state variables
>>> +	 * are already calculated and there is no assert_plane warnings
>>> +	 * during bootup.
>>> +	 */
>>> +	if (num_active_crtcs > 1) {
>>> +		ret = intel_initial_commit(dev);
>>> +		if (ret)
>>> +			DRM_DEBUG_KMS("Initial commit in probe
>>failed.\n");
>>> +	}
>>> +
>>> +	/*
>>>  	 * Make sure hardware watermarks really match the state we read
>>out.
>>>  	 * Note that we need to do this after reconstructing the BIOS fb's
>>>  	 * since the watermark calculation done here will use pstate->fb.
>>> --
>>> 1.9.1
>>
>>--
>>Ville Syrjälä
>>Intel
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx at lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list