Message ID | 1311613829-4990-1-git-send-email-keithp@keithp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, 25 Jul 2011 10:10:29 -0700 Keith Packard <keithp@keithp.com> wrote: > Hotplug detection is a mode setting operation and must hold the > struct_mutex or risk colliding with other mode setting operations. > > In particular, the display port hotplug function attempts to re-train > the link if the monitor is supposed to be running when plugged back > in. If that happens while mode setting is underway, the link will get > scrambled, leaving it in an inconsistent state. > > Signed-off-by: Keith Packard <keithp@keithp.com> > --- > drivers/gpu/drm/i915/i915_irq.c | 3 +++ > 1 files changed, 3 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 3b03f85..5fe8f28 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) > struct drm_mode_config *mode_config = &dev->mode_config; > struct intel_encoder *encoder; > > + mutex_lock(&dev_priv->dev->struct_mutex); > DRM_DEBUG_KMS("running encoder hotplug functions\n"); > > list_for_each_entry(encoder, &mode_config->encoder_list, base.head) > if (encoder->hot_plug) > encoder->hot_plug(encoder); > > + mutex_unlock(&dev_priv->dev->struct_mutex); > + > /* Just fire off a uevent and let userspace tell us what to do */ > drm_helper_hpd_irq_event(dev); > } yay, sounds like this will fix Andrew's problem and probably lots of other random DP related failures. Looks like the ->detect function is similarly protected at the call site (though one level up in ->fill_modes), so it should be safe. Looks like all the call sites in the link_status function are safe too. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Let's get this one upstream asap. Should probably be cc'd to stable@kernel.org as well.
Will test tonight. It looks like there is a lot of hotplug activity when 'xset dpms force off' gets run. (That's not a typo. I do mean "off," not "on." See attached trace. perf rocks, even over ssh :) --Andy On Mon, Jul 25, 2011 at 1:37 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > On Mon, 25 Jul 2011 10:10:29 -0700 > Keith Packard <keithp@keithp.com> wrote: > >> Hotplug detection is a mode setting operation and must hold the >> struct_mutex or risk colliding with other mode setting operations. >> >> In particular, the display port hotplug function attempts to re-train >> the link if the monitor is supposed to be running when plugged back >> in. If that happens while mode setting is underway, the link will get >> scrambled, leaving it in an inconsistent state. >> >> Signed-off-by: Keith Packard <keithp@keithp.com> >> --- >> drivers/gpu/drm/i915/i915_irq.c | 3 +++ >> 1 files changed, 3 insertions(+), 0 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c >> index 3b03f85..5fe8f28 100644 >> --- a/drivers/gpu/drm/i915/i915_irq.c >> +++ b/drivers/gpu/drm/i915/i915_irq.c >> @@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) >> struct drm_mode_config *mode_config = &dev->mode_config; >> struct intel_encoder *encoder; >> >> + mutex_lock(&dev_priv->dev->struct_mutex); >> DRM_DEBUG_KMS("running encoder hotplug functions\n"); >> >> list_for_each_entry(encoder, &mode_config->encoder_list, base.head) >> if (encoder->hot_plug) >> encoder->hot_plug(encoder); >> >> + mutex_unlock(&dev_priv->dev->struct_mutex); >> + >> /* Just fire off a uevent and let userspace tell us what to do */ >> drm_helper_hpd_irq_event(dev); >> } > > yay, sounds like this will fix Andrew's problem and probably lots of > other random DP related failures. > > Looks like the ->detect function is similarly protected at the call > site (though one level up in ->fill_modes), so it should be safe. > Looks like all the call sites in the link_status function are safe too. > > Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > Let's get this one upstream asap. Should probably be cc'd to > stable@kernel.org as well. > > -- > Jesse Barnes, Intel Open Source Technology Center > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > Xorg 1463/1463 [000] 8894.988115: intel_dp_dpms: (ffffffffa0093026) ffffffffa0093027 intel_dp_dpms (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8895.005199: intel_dp_dpms_return: (ffffffffa0093026 <- ffffffffa006321b) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8905.765634: intel_dp_dpms: (ffffffffa0093026) ffffffffa0093027 intel_dp_dpms (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8905.765650: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8905.817808: intel_dp_complete_link_train: (ffffffffa0092919) ffffffffa009291a intel_dp_complete_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8905.819069: intel_dp_dpms_return: (ffffffffa0093026 <- ffffffffa00631f5) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8920.030535: intel_dp_dpms: (ffffffffa0093026) ffffffffa0093027 intel_dp_dpms (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [000] 8920.048507: intel_dp_dpms_return: (ffffffffa0093026 <- ffffffffa006321b) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) kworker/u:5 82/82 [000] 8921.555293: intel_dp_hot_plug: (ffffffffa0092b5d) ffffffffa0092b5e intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.555297: intel_dp_check_link_status: (ffffffffa0092b6b) ffffffffa0092b6c intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.555298: intel_dp_hot_plug_return: (ffffffffa0092b5d <- ffffffffa006eb6c) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.555300: intel_dp_hot_plug: (ffffffffa0092b5d) ffffffffa0092b5e intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.555301: intel_dp_check_link_status: (ffffffffa0092b6b) ffffffffa0092b6c intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.555734: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.610002: intel_dp_complete_link_train: (ffffffffa0092919) ffffffffa009291a intel_dp_complete_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.611037: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.666002: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.720970: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.775934: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.830905: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.885873: intel_dp_start_link_train: (ffffffffa009225f) ffffffffa0092260 intel_dp_start_link_train (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0092c6a intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.957591: intel_dp_hot_plug_return: (ffffffffa0092b5d <- ffffffffa006eb6c) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.957594: intel_dp_hot_plug: (ffffffffa0092b5d) ffffffffa0092b5e intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.957596: intel_dp_check_link_status: (ffffffffa0092b6b) ffffffffa0092b6c intel_dp_hot_plug (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kworker/u:5 82/82 [000] 8921.957597: intel_dp_hot_plug_return: (ffffffffa0092b5d <- ffffffffa006eb6c) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kthreadd 8526/8526 [000] 8921.970066: ironlake_dp_detect: (ffffffffa0092443) ffffffffa0092444 intel_dp_detect (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0063313 output_poll_execute (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm_kms_helper.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kthreadd 8526/8526 [000] 8922.001120: ironlake_dp_detect: (ffffffffa0092443) ffffffffa0092444 intel_dp_detect (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0063313 output_poll_execute (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm_kms_helper.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) kthreadd 8526/8526 [000] 8922.057433: ironlake_dp_detect: (ffffffffa0092443) ffffffffa0092444 intel_dp_detect (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa0063313 output_poll_execute (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm_kms_helper.ko) ffffffff8105c783 process_one_work ([kernel.kallsyms]) ffffffff8105d2f4 worker_thread ([kernel.kallsyms]) ffffffff81060722 kthread ([kernel.kallsyms]) ffffffff81438414 kernel_thread_helper ([kernel.kallsyms]) Xorg 1463/1463 [006] 8924.761468: intel_dp_dpms: (ffffffffa0093026) ffffffffa0093027 intel_dp_dpms (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/i915/i915.ko) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) Xorg 1463/1463 [006] 8924.761480: intel_dp_dpms_return: (ffffffffa0093026 <- ffffffffa00631f5) ffffffff81433108 kretprobe_trampoline_holder ([kernel.kallsyms]) ffffffffa002d6e8 drm_mode_connector_property_set_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffffa002085f drm_ioctl (/lib/modules/3.0.0-rc6-bpp+/kernel/drivers/gpu/drm/drm.ko) ffffffff811049a5 do_vfs_ioctl ([kernel.kallsyms]) ffffffff81104a3c sys_ioctl ([kernel.kallsyms]) ffffffff814376bb system_call ([kernel.kallsyms]) 30260d8957 __GI_ioctl (/lib64/libc-2.14.so) [ 8894.988133] [drm:intel_dp_link_down], [ 8895.005211] [drm:ironlake_crtc_dpms], crtc 0/0 dpms off [ 8895.057169] [drm:intel_wait_for_vblank], vblank wait timed out [ 8895.091566] [drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 13, cursor: 6 [ 8895.091572] [drm:ironlake_check_srwm], watermark 1: display plane 25, fbc lines 3, cursor 6 [ 8895.091577] [drm:ironlake_check_srwm], watermark 2: display plane 33, fbc lines 3, cursor 6 [ 8895.091581] [drm:ironlake_check_srwm], watermark 3: display plane 169, fbc lines 4, cursor 10 [ 8895.091586] [drm:intel_update_fbc], [ 8905.658955] [drm:ironlake_crtc_dpms], crtc 0/0 dpms on [ 8905.658962] [drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 13, cursor: 6 [ 8905.658967] [drm:ironlake_check_srwm], watermark 1: display plane 25, fbc lines 3, cursor 6 [ 8905.658971] [drm:ironlake_check_srwm], watermark 2: display plane 33, fbc lines 3, cursor 6 [ 8905.658975] [drm:ironlake_check_srwm], watermark 3: display plane 169, fbc lines 4, cursor 10 [ 8905.710915] [drm:intel_wait_for_vblank], vblank wait timed out [ 8905.762883] [drm:intel_wait_for_vblank], vblank wait timed out [ 8905.763697] [drm:gen6_fdi_link_train], FDI_RX_IIR 0x100 [ 8905.763701] [drm:gen6_fdi_link_train], FDI train 1 done. [ 8905.764360] [drm:gen6_fdi_link_train], FDI_RX_IIR 0x600 [ 8905.764364] [drm:gen6_fdi_link_train], FDI train 2 done. [ 8905.764366] [drm:gen6_fdi_link_train], FDI train done. [ 8905.765627] [drm:intel_update_fbc], [ 8905.816858] [drm:intel_wait_for_vblank], vblank wait timed out [ 8905.818850] [drm:intel_dp_complete_link_train], Training worked. DPCD=110A8401 [ 8920.030552] [drm:intel_dp_link_down], [ 8920.048519] [drm:ironlake_crtc_dpms], crtc 0/0 dpms off [ 8920.100481] [drm:intel_wait_for_vblank], vblank wait timed out [ 8920.122880] [drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 13, cursor: 6 [ 8920.122887] [drm:ironlake_check_srwm], watermark 1: display plane 25, fbc lines 3, cursor 6 [ 8920.122892] [drm:ironlake_check_srwm], watermark 2: display plane 33, fbc lines 3, cursor 6 [ 8920.122896] [drm:ironlake_check_srwm], watermark 3: display plane 169, fbc lines 4, cursor 10 [ 8920.122900] [drm:intel_update_fbc], [ 8921.555286] [drm:i915_hotplug_work_func], running encoder hotplug functions [ 8921.555514] [drm:intel_dp_check_link_status], DPCD was 110A8401 [ 8921.555730] [drm:intel_dp_check_link_status], DPCD is now 110A8401 [ 8921.607586] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.662555] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.717522] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.772487] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.827456] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.882426] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.937393] [drm:intel_wait_for_vblank], vblank wait timed out [ 8921.939808] [drm:intel_dp_complete_link_train] *ERROR* failed to train DP, aborting [ 8921.939813] [drm:intel_dp_complete_link_train], DPCD is 110A8401 [ 8921.939818] [drm:intel_dp_link_down], [ 8921.957373] [drm:intel_dp_complete_link_train], Training worked. DPCD=110A8401 [ 8921.957605] [drm:intel_ironlake_crt_detect_hotplug], ironlake hotplug adpa=0xf40000, result 0 [ 8921.957609] [drm:intel_crt_detect], CRT not detected via hotplug [ 8921.957613] [drm:output_poll_execute], [CONNECTOR:5:VGA-1] status updated from 2 to 2 [ 8921.970060] [drm:output_poll_execute], [CONNECTOR:8:HDMI-A-1] status updated from 2 to 2 [ 8921.970072] [drm:ironlake_dp_detect], DPCD was 00000000 [ 8921.970588] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8921.970592] [drm:ironlake_dp_detect], Try 0: ret=-110 DPCD=00000000 [ 8921.972865] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8921.972866] [drm:ironlake_dp_detect], Try 1: ret=-110 DPCD=00000000 [ 8921.974867] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8921.974869] [drm:ironlake_dp_detect], Try 2: ret=-110 DPCD=00000000 [ 8921.976354] [drm:ironlake_dp_detect], No link. DPCD: 00000000 [ 8921.976360] [drm:output_poll_execute], [CONNECTOR:11:DP-1] status updated from 2 to 2 [ 8921.988736] [drm:output_poll_execute], [CONNECTOR:14:HDMI-A-2] status updated from 2 to 2 [ 8922.001117] [drm:output_poll_execute], [CONNECTOR:16:HDMI-A-3] status updated from 2 to 2 [ 8922.001123] [drm:ironlake_dp_detect], DPCD was 110A8401 [ 8922.001337] [drm:ironlake_dp_detect], Try 0: ret=4 DPCD=110A8401 [ 8922.001339] [drm:ironlake_dp_detect], Happy now! [ 8922.001341] [drm:ironlake_dp_detect], No link. DPCD: 110a8401 [ 8922.002389] [drm:i2c_algo_dp_aux_xfer], dp_aux_xfer return 2 [ 8922.029953] [drm:i2c_algo_dp_aux_xfer], dp_aux_xfer return 2 [ 8922.057428] [drm:i2c_algo_dp_aux_xfer], dp_aux_xfer return 2 [ 8922.057429] [drm:drm_detect_monitor_audio], Monitor has basic audio support [ 8922.057431] [drm:output_poll_execute], [CONNECTOR:17:DP-2] status updated from 1 to 1 [ 8922.057435] [drm:ironlake_dp_detect], DPCD was 00000000 [ 8922.057948] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8922.057949] [drm:ironlake_dp_detect], Try 0: ret=-110 DPCD=00000000 [ 8922.059815] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8922.059818] [drm:ironlake_dp_detect], Try 1: ret=-110 DPCD=00000000 [ 8922.061817] [drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5143003e [ 8922.061823] [drm:ironlake_dp_detect], Try 2: ret=-110 DPCD=00000000 [ 8922.063303] [drm:ironlake_dp_detect], No link. DPCD: 00000000 [ 8922.063309] [drm:output_poll_execute], [CONNECTOR:19:DP-3] status updated from 2 to 2 [ 8924.655081] [drm:ironlake_crtc_dpms], crtc 0/0 dpms on [ 8924.655087] [drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 13, cursor: 6 [ 8924.655091] [drm:ironlake_check_srwm], watermark 1: display plane 25, fbc lines 3, cursor 6 [ 8924.655096] [drm:ironlake_check_srwm], watermark 2: display plane 33, fbc lines 3, cursor 6 [ 8924.655100] [drm:ironlake_check_srwm], watermark 3: display plane 169, fbc lines 4, cursor 10 [ 8924.706753] [drm:intel_wait_for_vblank], vblank wait timed out [ 8924.758721] [drm:intel_wait_for_vblank], vblank wait timed out [ 8924.759533] [drm:gen6_fdi_link_train], FDI_RX_IIR 0x100 [ 8924.759537] [drm:gen6_fdi_link_train], FDI train 1 done. [ 8924.760196] [drm:gen6_fdi_link_train], FDI_RX_IIR 0x600 [ 8924.760200] [drm:gen6_fdi_link_train], FDI train 2 done. [ 8924.760202] [drm:gen6_fdi_link_train], FDI train done. [ 8924.761462] [drm:intel_update_fbc],
On Mon, 25 Jul 2011 13:40:58 -0400, Andrew Lutomirski <luto@mit.edu> wrote: > Will test tonight. Thanks. > It looks like there is a lot of hotplug activity when 'xset dpms force > off' gets run. (That's not a typo. I do mean "off," not "on." Yup, that's what I've seen as well -- do a mode set to turn stuff off and you get spammed with hotplug events. > See attached trace. perf rocks, even over ssh :) Wow. You're nested about three deep in the mode setting code due to overlapping hotplug events. What could possibly go wrong? Makes me optimistic that a bit of locking will help a lot here.
Two things I've noticed: - Why not dev->mode_config.mutex? I was under the impression that mode_config.mutex protects most of the modesetting state and dev->struct_mutex protects things related to the gpu execution cores (i.e. all things gem), with struct_mutex nested within mode_config.mutex. It's hazy at the edges and likely broken in tons of corner cases, but still ... This has also the benefit that it won't stall execbuf. - And a nitpick: Why the dev_priv->dev indirection, when dev is already lying around? -Daniel
On Tue, 26 Jul 2011 09:24:39 +0200, Daniel Vetter <daniel@ffwll.ch> wrote: > Two things I've noticed: > - Why not dev->mode_config.mutex? You're right, of course. I noticed that just after posting that version and updated it; the updated version is on my drm-intel-fixes branch already (having been reviewed by Jesse). > - And a nitpick: Why the dev_priv->dev indirection, when dev is > already lying around? All nicely cleaned up by using &mode_config->mutex instead :-) Thanks for looking it over!
On Tue, 26 Jul 2011 08:23:13 -0700 Keith Packard <keithp@keithp.com> wrote: > On Tue, 26 Jul 2011 09:24:39 +0200, Daniel Vetter <daniel@ffwll.ch> wrote: > > Two things I've noticed: > > > - Why not dev->mode_config.mutex? > > You're right, of course. I noticed that just after posting that version > and updated it; the updated version is on my drm-intel-fixes branch > already (having been reviewed by Jesse). > > > - And a nitpick: Why the dev_priv->dev indirection, when dev is > > already lying around? > > All nicely cleaned up by using &mode_config->mutex instead :-) > > Thanks for looking it over! I'd like to amend my reviewed by and say the lock shouldn't be held around the call to the drm helper function. It queues some work that also takes the mode config lock, which will break. So you can drop it before that... Previously I had only checked our internal driver callbacks but missed that the lock was held across the helper too.
On Tue, 26 Jul 2011 12:12:25 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > I'd like to amend my reviewed by and say the lock shouldn't be held > around the call to the drm helper function. It queues some work that > also takes the mode config lock, which will break. So you can drop it > before that... Previously I had only checked our internal driver > callbacks but missed that the lock was held across the helper too. So the work may get executed immediately rather than being run later at some point?
On Wed, 27 Jul 2011 02:21:24 -0700 Keith Packard <keithp@keithp.com> wrote: > On Tue, 26 Jul 2011 12:12:25 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > > > I'd like to amend my reviewed by and say the lock shouldn't be held > > around the call to the drm helper function. It queues some work that > > also takes the mode config lock, which will break. So you can drop it > > before that... Previously I had only checked our internal driver > > callbacks but missed that the lock was held across the helper too. > > So the work may get executed immediately rather than being run later at > some point? It sure looks that way... but I don't remember any rule about work queue items having inter dependencies like this.
On Wed, 27 Jul 2011 09:03:31 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > On Wed, 27 Jul 2011 02:21:24 -0700 > Keith Packard <keithp@keithp.com> wrote: > > > On Tue, 26 Jul 2011 12:12:25 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > > > > > I'd like to amend my reviewed by and say the lock shouldn't be held > > > around the call to the drm helper function. It queues some work that > > > also takes the mode config lock, which will break. So you can drop it > > > before that... Previously I had only checked our internal driver > > > callbacks but missed that the lock was held across the helper too. > > > > So the work may get executed immediately rather than being run later at > > some point? > > It sure looks that way... but I don't remember any rule about work > queue items having inter dependencies like this. Sounds fine; I've stuck a fixup that moves the mutex_unlock: if (encoder->hot_plug) encoder->hot_plug(encoder); + mutex_unlock(&mode_config->mutex); + /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); - - mutex_unlock(&mode_config->mutex); }
On Thu, Jul 28, 2011 at 03:50:00PM -0700, Keith Packard wrote: > On Wed, 27 Jul 2011 09:03:31 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > > On Wed, 27 Jul 2011 02:21:24 -0700 > > Keith Packard <keithp@keithp.com> wrote: > > > So the work may get executed immediately rather than being run later at > > > some point? > > > > It sure looks that way... but I don't remember any rule about work > > queue items having inter dependencies like this. I've checked the workqueue code and haven't found it to run a work immediately, it's always queued. Further this problem is very easy to diagnose: Even without lockdep the scheduler will notice the stuck task after about 120s and the backtrace should make matters extremely clear. On the other hand if somebody adds some nice state clobbering in the drm helper, we have a very hard bug to track down. Generally modesetting isn't perf critical, so I vote for more locking, just in case. -Daniel
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3b03f85..5fe8f28 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; + mutex_lock(&dev_priv->dev->struct_mutex); DRM_DEBUG_KMS("running encoder hotplug functions\n"); list_for_each_entry(encoder, &mode_config->encoder_list, base.head) if (encoder->hot_plug) encoder->hot_plug(encoder); + mutex_unlock(&dev_priv->dev->struct_mutex); + /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); }
Hotplug detection is a mode setting operation and must hold the struct_mutex or risk colliding with other mode setting operations. In particular, the display port hotplug function attempts to re-train the link if the monitor is supposed to be running when plugged back in. If that happens while mode setting is underway, the link will get scrambled, leaving it in an inconsistent state. Signed-off-by: Keith Packard <keithp@keithp.com> --- drivers/gpu/drm/i915/i915_irq.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)