Received: by 10.213.65.68 with SMTP id h4csp472112imn; Tue, 13 Mar 2018 10:06:45 -0700 (PDT) X-Google-Smtp-Source: AG47ELubcpNhcIUBlCibiRAJJrwjmGUCEq/r8iTgC6bOyEkq9EKckOjj3sWk2Wjkhq3XIxUTTcH7 X-Received: by 2002:a17:902:8341:: with SMTP id z1-v6mr1186356pln.386.1520960805616; Tue, 13 Mar 2018 10:06:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520960805; cv=none; d=google.com; s=arc-20160816; b=warY9yk8waZy/wd85dj9IEUW5tkb2UODEJXIGibh2y0Mjc9PwnSRPgAbLae/F6XPFI L8IW0teO1DdBEfPMkXoawf9P9iQSBI6BAeKQOSfAUT7IwKy5KkmL7nonUv7xIZ1CDvY/ Z7VDrX6muXsxkwtHGwIry4JPHA+O1gchAqBrgcKIq2ZNehTh5eGqOgCsAVp4DSANYb5z /6Pn/64DPSMRV7ZAbSEGDSN6qrRAfaurLOaOmGoCjzSBSwA5im6dtKUMsxthQ6LtF+Au 0UsLYUOsJBdA+GPiKqcsDBTXV045u/QuUyzirdpneHlwrqz3UFNFo0sCXkb8f5BYTKE9 9AOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=wH01SY+iYBQBB3BXffoXDJ8LR7Y6GNixB8zs0cNQIpM=; b=th9sgSMJpeEySuu2pvCicixMltnL48CKKWsSeb7XUyU/u827TM+kYfrenZWiHB+76x k8yQj9G8kdS8Fz8tjZ4a+LsUL5+WaXoeK256Gg6bupM9ubHh2gQXV8tKKfdXoK8bjBqQ OlP8v3aecY3m7rIld4o7b+0BgyyqzScu5pckCpvJhtOvhAoL9zhnsVtkjZl4F6iSjvWl DT/dtuysvrjOgKZ1MVHuOQkHvrBs0I1zR7RT9xMQ3v3jl+SSy5quMiG4b+FGeQ8DB4qW c5HyejzltHD4EQfOKSTefH2Epy67hwGyc18IHoj+QGkqfAlWFAaoLn7Ss3S+n4k7BdPO 1SIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w17-v6si340872plp.561.2018.03.13.10.06.30; Tue, 13 Mar 2018 10:06:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932791AbeCMP2j (ORCPT + 99 others); Tue, 13 Mar 2018 11:28:39 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:58022 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932750AbeCMP22 (ORCPT ); Tue, 13 Mar 2018 11:28:28 -0400 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 6EED2DFE; Tue, 13 Mar 2018 15:28:27 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alex Deucher , Mike Lothian , Lyude Paul , Lukas Wunner Subject: [PATCH 4.15 024/146] drm/amdgpu: Fix deadlock on runtime suspend Date: Tue, 13 Mar 2018 16:23:11 +0100 Message-Id: <20180313152322.323324350@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180313152320.439085687@linuxfoundation.org> References: <20180313152320.439085687@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Lukas Wunner commit aa0aad57909eb321746325951d66af88a83bc956 upstream. amdgpu'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 amdgpu's ->detect hooks, which waits for the ongoing suspend to finish, causing a deadlock. Fix by not acquiring a runtime PM ref if the ->detect hooks are 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. Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") Cc: stable@vger.kernel.org # v4.2+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct Cc: stable@vger.kernel.org # v4.2+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker Cc: Alex Deucher Tested-by: Mike Lothian Reviewed-by: Lyude Paul Signed-off-by: Lukas Wunner Link: https://patchwork.freedesktop.org/patch/msgid/4c9bf72aacae1eef062bd134cd112e0770a7f121.1518338789.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 58 ++++++++++++++++--------- 1 file changed, 38 insertions(+), 20 deletions(-) --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -737,9 +737,11 @@ amdgpu_connector_lvds_detect(struct drm_ enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (encoder) { struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); @@ -758,8 +760,12 @@ amdgpu_connector_lvds_detect(struct drm_ /* check acpi lid status ??? */ amdgpu_connector_update_scratch_regs(connector, ret); - 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 ret; } @@ -869,9 +875,11 @@ amdgpu_connector_vga_detect(struct drm_c enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } encoder = amdgpu_connector_best_single_encoder(connector); if (!encoder) @@ -925,8 +933,10 @@ amdgpu_connector_vga_detect(struct drm_c amdgpu_connector_update_scratch_regs(connector, ret); 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 ret; } @@ -989,9 +999,11 @@ amdgpu_connector_dvi_detect(struct drm_c enum drm_connector_status ret = connector_status_disconnected; bool dret = false, broken_edid = false; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1116,8 +1128,10 @@ out: amdgpu_connector_update_scratch_regs(connector, ret); exit: - 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 ret; } @@ -1360,9 +1374,11 @@ amdgpu_connector_dp_detect(struct drm_co struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1430,8 +1446,10 @@ amdgpu_connector_dp_detect(struct drm_co amdgpu_connector_update_scratch_regs(connector, ret); 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 ret; }