Re: FAILED: patch "[PATCH] drm/nouveau: Fix deadlock on runtime suspend" failed to apply to 4.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg,

On Mon, Feb 26, 2018 at 05:07:55PM +0100, gregkh@xxxxxxxxxxxxxxxxxxx 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@xxxxxxxxxxxxxxx # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
Cc: stable@xxxxxxxxxxxxxxx # 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@xxxxxxxxxxxxxxx>.
> 
> thanks,
> 
> greg k-h
> 
> ------------------ original commit in Linus's tree ------------------
> 
> From d61a5c1063515e855bedb1b81e20e50b0ac3541e Mon Sep 17 00:00:00 2001
> From: Lukas Wunner <lukas@xxxxxxxxx>
> 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@xxxxxxxxxxxxxxx # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct
> Cc: stable@xxxxxxxxxxxxxxx # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker
> Cc: Ben Skeggs <bskeggs@xxxxxxxxxx>
> Cc: Dave Airlie <airlied@xxxxxxxxxx>
> Reviewed-by: Lyude Paul <lyude@xxxxxxxxxx>
> Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx>
> Link: https://patchwork.freedesktop.org/patch/msgid/b7d2cbb609a80f59ccabfdf479b9d5907c603ea1.1518338789.git.lukas@xxxxxxxxx
> 
> 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;
>  }
> 



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]