* FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree
@ 2018-02-26 16:07 gregkh
2018-02-26 16:13 ` Lukas Wunner
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2018-02-26 16:07 UTC (permalink / raw)
To: lukas, airlied, bskeggs, lyude; +Cc: stable
The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From d61a5c1063515e855bedb1b81e20e50b0ac3541e Mon Sep 17 00:00:00 2001
From: Lukas Wunner <lukas@wunner.de>
Date: Sun, 11 Feb 2018 10:38:28 +0100
Subject: [PATCH] drm/nouveau: Fix deadlock on runtime suspend
nouveau's ->runtime_suspend hook calls drm_kms_helper_poll_disable(),
which waits for the output poll worker to finish if it's running.
The output poll worker meanwhile calls pm_runtime_get_sync() in
nouveau_connector_detect() which waits for the ongoing suspend to finish,
causing a deadlock.
Fix by not acquiring a runtime PM ref if nouveau_connector_detect() is
called in the output poll worker's context. This is safe because
the poll worker is only enabled while runtime active and we know that
->runtime_suspend waits for it to finish.
Other contexts calling nouveau_connector_detect() do require a runtime
PM ref, these comprise:
status_store() drm sysfs interface
->fill_modes drm callback
drm_fb_helper_probe_connector_modes()
drm_mode_getconnector()
nouveau_connector_hotplug()
nouveau_display_hpd_work()
nv17_tv_set_property()
Stack trace for posterity:
INFO: task kworker/0:1:58 blocked for more than 120 seconds.
Workqueue: events output_poll_execute [drm_kms_helper]
Call Trace:
schedule+0x28/0x80
rpm_resume+0x107/0x6e0
__pm_runtime_resume+0x47/0x70
nouveau_connector_detect+0x7e/0x4a0 [nouveau]
nouveau_connector_detect_lvds+0x132/0x180 [nouveau]
drm_helper_probe_detect_ctx+0x85/0xd0 [drm_kms_helper]
output_poll_execute+0x11e/0x1c0 [drm_kms_helper]
process_one_work+0x184/0x380
worker_thread+0x2e/0x390
INFO: task kworker/0:2:252 blocked for more than 120 seconds.
Workqueue: pm pm_runtime_work
Call Trace:
schedule+0x28/0x80
schedule_timeout+0x1e3/0x370
wait_for_completion+0x123/0x190
flush_work+0x142/0x1c0
nouveau_pmops_runtime_suspend+0x7e/0xd0 [nouveau]
pci_pm_runtime_suspend+0x5c/0x180
vga_switcheroo_runtime_suspend+0x1e/0xa0
__rpm_callback+0xc1/0x200
rpm_callback+0x1f/0x70
rpm_suspend+0x13c/0x640
pm_runtime_work+0x6e/0x90
process_one_work+0x184/0x380
worker_thread+0x2e/0x390
Bugzilla: https://bugs.archlinux.org/task/53497
Bugzilla: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870523
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388#c33
Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
Cc: stable@vger.kernel.org # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Dave Airlie <airlied@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/b7d2cbb609a80f59ccabfdf479b9d5907c603ea1.1518338789.git.lukas@wunner.de
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 69d6e61a01ec..6ed9cb053dfa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -570,9 +570,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
nv_connector->edid = NULL;
}
- ret = pm_runtime_get_sync(connector->dev->dev);
- if (ret < 0 && ret != -EACCES)
- return conn_status;
+ /* Outputs are only polled while runtime active, so acquiring a
+ * runtime PM ref here is unnecessary (and would deadlock upon
+ * runtime suspend because it waits for polling to finish).
+ */
+ if (!drm_kms_helper_is_poll_worker()) {
+ ret = pm_runtime_get_sync(connector->dev->dev);
+ if (ret < 0 && ret != -EACCES)
+ return conn_status;
+ }
nv_encoder = nouveau_connector_ddc_detect(connector);
if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
@@ -647,8 +653,10 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
out:
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
+ if (!drm_kms_helper_is_poll_worker()) {
+ pm_runtime_mark_last_busy(connector->dev->dev);
+ pm_runtime_put_autosuspend(connector->dev->dev);
+ }
return conn_status;
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree
2018-02-26 16:07 FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree gregkh
@ 2018-02-26 16:13 ` Lukas Wunner
2018-03-12 14:56 ` Greg KH
0 siblings, 1 reply; 3+ messages in thread
From: Lukas Wunner @ 2018-02-26 16:13 UTC (permalink / raw)
To: gregkh; +Cc: airlied, bskeggs, lyude, stable
Hi Greg,
On Mon, Feb 26, 2018 at 05:07:55PM +0100, gregkh@linuxfoundation.org wrote:
> The patch below does not apply to the 4.14-stable tree.
The patch applies just fine, but it has two prerequisites, as specified
in the commit message:
Cc: stable@vger.kernel.org # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker
The radeon and amdgpu patches have the same prerequisites.
Thanks,
Lukas
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable@vger.kernel.org>.
>
> thanks,
>
> greg k-h
>
> ------------------ original commit in Linus's tree ------------------
>
> From d61a5c1063515e855bedb1b81e20e50b0ac3541e Mon Sep 17 00:00:00 2001
> From: Lukas Wunner <lukas@wunner.de>
> Date: Sun, 11 Feb 2018 10:38:28 +0100
> Subject: [PATCH] drm/nouveau: Fix deadlock on runtime suspend
>
> nouveau's ->runtime_suspend hook calls drm_kms_helper_poll_disable(),
> which waits for the output poll worker to finish if it's running.
>
> The output poll worker meanwhile calls pm_runtime_get_sync() in
> nouveau_connector_detect() which waits for the ongoing suspend to finish,
> causing a deadlock.
>
> Fix by not acquiring a runtime PM ref if nouveau_connector_detect() is
> called in the output poll worker's context. This is safe because
> the poll worker is only enabled while runtime active and we know that
> ->runtime_suspend waits for it to finish.
>
> Other contexts calling nouveau_connector_detect() do require a runtime
> PM ref, these comprise:
>
> status_store() drm sysfs interface
> ->fill_modes drm callback
> drm_fb_helper_probe_connector_modes()
> drm_mode_getconnector()
> nouveau_connector_hotplug()
> nouveau_display_hpd_work()
> nv17_tv_set_property()
>
> Stack trace for posterity:
>
> INFO: task kworker/0:1:58 blocked for more than 120 seconds.
> Workqueue: events output_poll_execute [drm_kms_helper]
> Call Trace:
> schedule+0x28/0x80
> rpm_resume+0x107/0x6e0
> __pm_runtime_resume+0x47/0x70
> nouveau_connector_detect+0x7e/0x4a0 [nouveau]
> nouveau_connector_detect_lvds+0x132/0x180 [nouveau]
> drm_helper_probe_detect_ctx+0x85/0xd0 [drm_kms_helper]
> output_poll_execute+0x11e/0x1c0 [drm_kms_helper]
> process_one_work+0x184/0x380
> worker_thread+0x2e/0x390
>
> INFO: task kworker/0:2:252 blocked for more than 120 seconds.
> Workqueue: pm pm_runtime_work
> Call Trace:
> schedule+0x28/0x80
> schedule_timeout+0x1e3/0x370
> wait_for_completion+0x123/0x190
> flush_work+0x142/0x1c0
> nouveau_pmops_runtime_suspend+0x7e/0xd0 [nouveau]
> pci_pm_runtime_suspend+0x5c/0x180
> vga_switcheroo_runtime_suspend+0x1e/0xa0
> __rpm_callback+0xc1/0x200
> rpm_callback+0x1f/0x70
> rpm_suspend+0x13c/0x640
> pm_runtime_work+0x6e/0x90
> process_one_work+0x184/0x380
> worker_thread+0x2e/0x390
>
> Bugzilla: https://bugs.archlinux.org/task/53497
> Bugzilla: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870523
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388#c33
> Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
> Cc: stable@vger.kernel.org # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
> Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker
> Cc: Ben Skeggs <bskeggs@redhat.com>
> Cc: Dave Airlie <airlied@redhat.com>
> Reviewed-by: Lyude Paul <lyude@redhat.com>
> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> Link: https://patchwork.freedesktop.org/patch/msgid/b7d2cbb609a80f59ccabfdf479b9d5907c603ea1.1518338789.git.lukas@wunner.de
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
> index 69d6e61a01ec..6ed9cb053dfa 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_connector.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
> @@ -570,9 +570,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
> nv_connector->edid = NULL;
> }
>
> - ret = pm_runtime_get_sync(connector->dev->dev);
> - if (ret < 0 && ret != -EACCES)
> - return conn_status;
> + /* Outputs are only polled while runtime active, so acquiring a
> + * runtime PM ref here is unnecessary (and would deadlock upon
> + * runtime suspend because it waits for polling to finish).
> + */
> + if (!drm_kms_helper_is_poll_worker()) {
> + ret = pm_runtime_get_sync(connector->dev->dev);
> + if (ret < 0 && ret != -EACCES)
> + return conn_status;
> + }
>
> nv_encoder = nouveau_connector_ddc_detect(connector);
> if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
> @@ -647,8 +653,10 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
>
> out:
>
> - pm_runtime_mark_last_busy(connector->dev->dev);
> - pm_runtime_put_autosuspend(connector->dev->dev);
> + if (!drm_kms_helper_is_poll_worker()) {
> + pm_runtime_mark_last_busy(connector->dev->dev);
> + pm_runtime_put_autosuspend(connector->dev->dev);
> + }
>
> return conn_status;
> }
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree
2018-02-26 16:13 ` Lukas Wunner
@ 2018-03-12 14:56 ` Greg KH
0 siblings, 0 replies; 3+ messages in thread
From: Greg KH @ 2018-03-12 14:56 UTC (permalink / raw)
To: Lukas Wunner; +Cc: airlied, bskeggs, lyude, stable
On Mon, Feb 26, 2018 at 05:13:51PM +0100, Lukas Wunner wrote:
> Hi Greg,
>
> On Mon, Feb 26, 2018 at 05:07:55PM +0100, gregkh@linuxfoundation.org wrote:
> > The patch below does not apply to the 4.14-stable tree.
>
> The patch applies just fine, but it has two prerequisites, as specified
> in the commit message:
>
> Cc: stable@vger.kernel.org # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
> Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker
>
> The radeon and amdgpu patches have the same prerequisites.
Doh, I missed that, sorry. Now fixed up.
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-03-12 14:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-26 16:07 FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree gregkh
2018-02-26 16:13 ` Lukas Wunner
2018-03-12 14:56 ` Greg KH
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.