Bug 70839 - [IVB] Undocking laptop causes warning in intel_dp_link_down+0x1d2/0x210
Summary: [IVB] Undocking laptop causes warning in intel_dp_link_down+0x1d2/0x210
Status: CLOSED FIXED
Alias: None
Product: DRI
Classification: Unclassified
Component: DRM/Intel (show other bugs)
Version: XOrg git
Hardware: x86-64 (AMD64) Linux (All)
: low minor
Assignee: Jani Nikula
QA Contact: Intel GFX Bugs mailing list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-24 12:21 UTC by Jan-Michael Brummer
Modified: 2017-07-24 22:57 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
dmesg output with drm.debug=0xe on latest drm-intel-nightly (410.72 KB, text/plain)
2013-10-24 12:21 UTC, Jan-Michael Brummer
no flags Details

Description Jan-Michael Brummer 2013-10-24 12:21:52 UTC
Created attachment 88079 [details]
dmesg output with drm.debug=0xe on latest drm-intel-nightly

Undocking my HP 8470p laptop causes a kernel warning using the latest drm-intel-nightly git tree.

[  102.569997] ------------[ cut here ]------------
[  102.570069] WARNING: CPU: 1 PID: 969 at drivers/gpu/drm/i915/intel_dp.c:2675 intel_dp_link_down+0x1d2/0x210 [i915]()
[  102.570072] Modules linked in: fuse nf_conntrack_netbios_ns nf_conntrack_broadcast ipt_MASQUERADE ip6t_REJECT xt_conntrack vboxpci(OF) vboxnetadp(OF) vboxnetflt(OF) ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack vboxdrv(OF) iptable_mangle iptable_security iptable_raw bnep arc4 iwldvm mac80211 iwlwifi cfg80211 snd_hda_codec_hdmi snd_hda_codec_idt btusb tpm_infineon bluetooth uvcvideo videobuf2_vmalloc videobuf2_memops iTCO_wdt ppdev videobuf2_core iTCO_vendor_support x86_pkg_temp_thermal videodev coretemp kvm_intel kvm media hp_wmi sparse_keymap crc32_pclmul snd_hda_intel crc32c_intel
[  102.570145]  snd_hda_codec ghash_clmulni_intel microcode snd_hwdep snd_seq joydev serio_raw pcspkr snd_seq_device sdhci_pci snd_pcm sdhci mmc_core e1000e rfkill snd_page_alloc snd_timer snd lpc_ich mfd_core tpm_tis shpchp parport_pc soundcore mei_me ptp parport mei pps_core tpm tpm_bios wmi hp_accel lis3lv02d nfsd input_polldev acpi_cpufreq auth_rpcgss nfs_acl lockd sunrpc binfmt_misc i915 i2c_algo_bit drm_kms_helper drm firewire_ohci firewire_core i2c_core crc_itu_t video
[  102.570205] CPU: 1 PID: 969 Comm: Xorg Tainted: GF          O 3.12.0-rc5-jbr+ #2
[  102.570209] Hardware name: Hewlett-Packard HP EliteBook 8470p/179B, BIOS 68ICF Ver. F.43 07/16/2013
[  102.570213]  0000000000000009 ffff88022fee1c08 ffffffff8165ecbd 0000000000000000
[  102.570221]  ffff88022fee1c40 ffffffff810680ad ffff88022e6608c8 ffff88022e269000
[  102.570228]  ffff880232b0e000 0000000080180344 ffff880035f40000 ffff88022fee1c50
[  102.570236] Call Trace:
[  102.570248]  [<ffffffff8165ecbd>] dump_stack+0x45/0x56
[  102.570257]  [<ffffffff810680ad>] warn_slowpath_common+0x7d/0xa0
[  102.570264]  [<ffffffff8106818a>] warn_slowpath_null+0x1a/0x20
[  102.570303]  [<ffffffffa00f3402>] intel_dp_link_down+0x1d2/0x210 [i915]
[  102.570335]  [<ffffffffa00f7578>] intel_disable_dp+0x68/0x70 [i915]
[  102.570365]  [<ffffffffa00dc76e>] ironlake_crtc_disable+0x1ae/0x960 [i915]
[  102.570394]  [<ffffffffa00e2b8f>] intel_crtc_update_dpms+0x6f/0xa0 [i915]
[  102.570423]  [<ffffffffa00e6209>] intel_connector_dpms+0x59/0x70 [i915]
[  102.570450]  [<ffffffffa0054598>] drm_mode_obj_set_property_ioctl+0x308/0x320 [drm]
[  102.570471]  [<ffffffffa00545e0>] drm_mode_connector_property_set_ioctl+0x30/0x40 [drm]
[  102.570490]  [<ffffffffa0043bf2>] drm_ioctl+0x522/0x650 [drm]
[  102.570505]  [<ffffffff811bb7dd>] do_vfs_ioctl+0x2dd/0x4b0
[  102.570511]  [<ffffffff811bba31>] SyS_ioctl+0x81/0xa0
[  102.570519]  [<ffffffff8166dca9>] system_call_fastpath+0x16/0x1b
[  102.570523] ---[ end trace 81ef030c236dabb3 ]---
Comment 1 Daniel Vetter 2013-10-27 19:08:39 UTC
Cool, now we have the last dupe for ivb, for reference see bug #67462 	and bug #54687 Docking station unplugging is like cable pulling in this way ;-)
Comment 2 Yuly Novikov 2013-11-04 21:35:32 UTC
I encounter a similar stack in ChromeOS when unplugging DP cable.
The reason it happens for me is that intel_dp_link_down() is called first time from intel_dp_check_link_status() from intel_dp_hot_plug().
Then, during hot plug uevent processing, we decide to DPMS OFF the DP, and then intel_dp_link_down() is called a second time, so there is a warning for
WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0).

I am also getting a warning in intel_modeset_check_state(), since we reconfigure internal LVDS before we DPMS OFF the DP, and during the check we hit the warning for DP:
active = encoder->get_hw_state(encoder, &pipe);
WARN(active != encoder->connectors_active,

I'd be happy to upload a fix for that, but I am not sure what would be the right direction to take with it.
From reading commit messages for intel_dp_hot_plug(), I understand that it calls intel_dp_check_link_status() "for userspace apps that don't respond to hot plug uevents". But that causes the warnings for apps that do respond to them.

I think that the warnings are irrelevant in this case. I'd like to keep track of hot plug detection, and then not warn about the DP link being down as a result of hot unplug.
Daniel, what do you think?
Comment 3 Daniel Vetter 2013-11-05 07:45:30 UTC
(In reply to comment #2)
> I think that the warnings are irrelevant in this case. I'd like to keep
> track of hot plug detection, and then not warn about the DP link being down
> as a result of hot unplug.

The dp link training code is botched since if it disables the port if it doesn't work out. Which results in warns like yours but on some systems also in deadlocks since the display pipe stops working when we expect it to run. The fix is to gracefully fail the link training by simple enabling the link at conservative settings and keep on pumping pixels into the air (like we do with all other outputs).

The comment in dp_hotplug is simply historical bonghits.
Comment 4 Yuly Novikov 2013-11-05 14:42:12 UTC
But wouldn't "enabling the link at conservative settings and keep on pumping pixels into the air" waste power?
Sounds to me that bringing the link down when unplug is detected is the power efficient way to go.
That is, if there is a safe way to do so.

As I understand, the problem with display pipe stopping is not a hardware one, but the other parts of the driver, right?
I've tried to DPMS OFF the crtc instead of intel_dp_link_down(), and it worked for me.
But, marcheu@ told me that X caches DPMS state, and the only reason it worked is because in ChromeOS we re-probe once we receive hotplug uevent, so the cache is updated properly.

Sounds to me that a better solution would be to devise a mechanism by which drm state can be updated from the hardware side.
I mean, the usual configuration flow is that userspace configures crtc, which enables / disables encoder and connector.
But, it sound reasonable to me that when a connector detects that the hardware configuration changed, it will reconfigure encoder / crtc on it's own, and notify the userspace about the change.

I've tried calling intel_modeset_setup_hw_state(force_restore==true) for that effect, and it worked, but it took a few seconds and the internal screen turned on / off twice instead of once, that I'd expect from reconfiguration.

Perhaps what we need is a more light-weight intel_modeset_setup_hw_state(), which would not touch hardware which is already in the right state, but only turn off the relevant one?

How does that sound from "right thing to do" and feasibility perspectives?

If I am just talking nonsense here, what would you suggest as "conservative settings"? 640x480@60Hz?
Comment 5 Jani Nikula 2014-01-23 11:40:04 UTC
Please try current drm-intel-nightly, I think we've merged some patches to address this.
Comment 6 Ben Widawsky 2014-01-28 01:59:31 UTC
Yuly, are you still there? Will close if not.
Comment 7 Yuly Novikov 2014-01-28 02:04:15 UTC
Sorry, I didn't have time to test this.
Would be helpful if I knew what commits address this, so I could cherry-pick them into our branch.
BTW, I am not the original reporter of the bug, Jan-Michael is.
Comment 8 Ben Widawsky 2014-01-29 19:17:09 UTC
Jani, would you be able to come up with a list of potential commits that may already fix the issue?
Comment 9 Yuly Novikov 2014-01-30 01:56:50 UTC
I've been trying to find commits that might affect it by myself, looking at drm-intel-next branch, and I believe with the current code, the warning will still occur. The sequence of events leading to the warning is as follows:

ironlake_irq_handler()
  ilk_display_irq_handler()
    cpt_irq_handler()
      intel_hpd_irq_handler()
        i915_hotplug_work_func()
          intel_dp_hot_plug()
            intel_dp_check_link_status()
              intel_dp_get_link_status()
              intel_dp_link_down() 
          drm_helper_hpd_irq_event()
            drm_kms_helper_hotplug_event()
              drm_sysfs_hotplug_event()
                kobject_uevent_env()
<userspace uevent processing>
drm_mode_obj_set_property_ioctl()
  drm_mode_connector_set_obj_prop()
    intel_connector_dpms()
      intel_encoder_dpms()
        intel_crtc_update_dpms()
          ironlake_crtc_disable()
            intel_disable_dp()
              intel_dp_link_down()

There were several changes on these paths, but I fail to find there a change that would prevent from intel_dp_link_down() to be called twice on SNB or IVB.
Comment 10 Jani Nikula 2014-01-30 07:19:18 UTC
(In reply to comment #8)
> Jani, would you be able to come up with a list of potential commits that may
> already fix the issue?

commit 5d6a1116c6475404e6505b708320f9579ae19acd
Author: Imre Deak <imre.deak@intel.com>
Date:   Thu Jan 16 18:35:57 2014 +0200

    drm/i915: don't disable the DP port if the link is lost

comes to mind, and it does change the analysis in comment #9. Do note that the branch to test is drm-intel-nightly, not -next.
Comment 11 Yuly Novikov 2014-01-30 20:32:00 UTC
Ah, sorry that I was looking in a wrong branch.
Indeed, the commit in question will remove the warning, as it removes the call to intel_dp_link_down() from intel_dp_check_link_status().
However, my understanding is that this call was there to support cases where userspace doesn't handle uevents, and removing it will leave DP link on and consuming power in such systems, and probably lead to errors when one monitor is plugged out and another is plugged in. Hope you are keeping track of this in some other bug.
But, for me the problem is fixed, so you can close this one.

BTW, if relying on uevents is the direction you want to proceed with, I think you can remove intel_dp_hot_plug() altogether, since currently it does nothing in case of unplug, and in case of plug, the dp link will be enabled in intel_enable_dp() anyway, when userspace decides to DPMS_ON.
Comment 12 Jani Nikula 2014-01-31 06:58:30 UTC
Thanks, closing.

Imre, please check comment #11 and see if there's anything to worry about.
Comment 13 Imre Deak 2014-01-31 07:25:42 UTC
(In reply to comment #11)
> Ah, sorry that I was looking in a wrong branch.
> Indeed, the commit in question will remove the warning, as it removes the
> call to intel_dp_link_down() from intel_dp_check_link_status().
> However, my understanding is that this call was there to support cases where
> userspace doesn't handle uevents, and removing it will leave DP link on and
> consuming power in such systems, and probably lead to errors when one
> monitor is plugged out and another is plugged in. Hope you are keeping track
> of this in some other bug.

In general we do depend on user space handling uevents, I don't know any reason why guaranteeing this would pose any problem. So the subsequent modeset disable should take care of disabling the port. Note that there is still a TODO identified by Chris, for the case where a modeset fails due to link training errors and we leave the whole pipeline enabled. But that's a somewhat separate issue.

> But, for me the problem is fixed, so you can close this one.
> 
> BTW, if relying on uevents is the direction you want to proceed with, I
> think you can remove intel_dp_hot_plug() altogether, since currently it does
> nothing in case of unplug, and in case of plug, the dp link will be enabled
> in intel_enable_dp() anyway, when userspace decides to DPMS_ON.

Afaics intel_dp_hot_plug() also handles link retraining.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.