Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp980449ybz; Fri, 1 May 2020 12:05:17 -0700 (PDT) X-Google-Smtp-Source: APiQypLxOCA9OWdlC2OdG+ZZhfKJsKjwcr6EDAI5/CJMwfl3L+BWM9/IztMtLv1FubBowom6dPUS X-Received: by 2002:a17:906:c82b:: with SMTP id dd11mr4398266ejb.216.1588359917533; Fri, 01 May 2020 12:05:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588359917; cv=none; d=google.com; s=arc-20160816; b=qWK3ATaD9pyt/OEdJNvSrqoVtavJpH2N08sUTJE3V/XnkkbTb3fFPaKhy3d7OT3kyv ktgQHHfU01f/MXCR8ky2PyihuOS00D9BC1vLpZ41ZliJgnBO2BMNCWlz8vGOg8Tyd9Lc nHY3pfMVoV2na/c1InzGZffehW1mcNUHC4fRZvP40cF8kWRuOqp7m8J9NqFJt7wKKRJj eZZnCoq4c0rCdaKdBJ/qeTT4ac+86KSRgoExyWjA3SKLoL/ZbRo/C9GT16uXutncNl2Z AgXFTWZAd8mJjGK0MGYka/HzsTyfJ1/OWhkmL/29imSxAukr6/ajfUOS7dMNq8unKgTm /ycg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dmarc-filter:dkim-signature; bh=GY5sqtDiJc80ZiMq+8+zAVXgb8kIjKkuNxyYZsSwO/g=; b=fXSqM4D9Qnxfwj/Tt1x/qnR3XIs2j0vaIGLHRiU0TzYJbpW2RTauEC8MRQ0SkFdI4J vK0nsq01XiCzftp3FZCE76Z9ZQ934vaGj++UlRme24JUdQj1pIJ4NFN6Fx3f1KYeXrly lYVCdTxgXGywd2eJtaKO8E49Bv9tzm4c6svmn5Pbr8iVH/OsNrq50Nm2EBxmG2L9opTS +en0Rqs6pOMvSNrjJH8qEK6kF/guZESTwFfP3mXisZuGgLDT5apnSQiUniRmNY/jd1yd aDHUupumaxJgyIgugVj3XvKJ4maF5zzjVJQQrh/vFtlriI+Mihz6+uXmyvWWIBUIKf3w xunQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=EwM4uxQq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 4si2346978ejy.347.2020.05.01.12.04.54; Fri, 01 May 2020 12:05:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=EwM4uxQq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730325AbgEATD3 (ORCPT + 99 others); Fri, 1 May 2020 15:03:29 -0400 Received: from mail27.static.mailgun.info ([104.130.122.27]:64352 "EHLO mail27.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729930AbgEATD3 (ORCPT ); Fri, 1 May 2020 15:03:29 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1588359808; h=Message-Id: Date: Subject: Cc: To: From: Sender; bh=GY5sqtDiJc80ZiMq+8+zAVXgb8kIjKkuNxyYZsSwO/g=; b=EwM4uxQqBfut02pCY7bBkzMPqrYZx0YA1K3ifEyva5N7dUu6CxJi51/GbS4yC7RJfxMcMvgs 3B0Gh/cmRdMu2a98qyucxRyXjBNb7uwFVmaMphoWxjiguFFoKAuAJyIwSvzpzwypybR1sOVb lixIsM3XVgQRyUuApluhQfh+oeI= X-Mailgun-Sending-Ip: 104.130.122.27 X-Mailgun-Sid: WyI0MWYwYSIsICJsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnIiwgImJlOWU0YSJd Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5eac7280.7f8bef7cc420-smtp-out-n05; Fri, 01 May 2020 19:03:28 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 33AD1C4478F; Fri, 1 May 2020 19:03:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id 2352CC433CB; Fri, 1 May 2020 19:03:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 2352CC433CB Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Eric Anholt , stable@vger.kernel.org, Akhil P Oommen , AngeloGioacchino Del Regno , Ben Dooks , Daniel Vetter , David Airlie , Greg Kroah-Hartman , Jeffrey Hugo , "Michael J. Ruhl" , Rob Clark , Sean Paul , Sharat Masetty , Thomas Gleixner , dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] drm/msm: Check for powered down HW in the devfreq callbacks Date: Fri, 1 May 2020 13:03:20 -0600 Message-Id: <20200501190320.17681-1-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Writing to the devfreq sysfs nodes while the GPU is powered down can result in a system crash (on a5xx) or a nasty GMU error (on a6xx): $ /sys/class/devfreq/5000000.gpu# echo 500000000 > min_freq [ 104.841625] platform 506a000.gmu: [drm:a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set GPU_DCVS: 0x0 Despite the fact that we carefully try to suspend the devfreq device when the hardware is powered down there are lots of holes in the governors that don't check for the suspend state and blindly call into the devfreq callbacks that end up triggering hardware reads in the GPU driver. Call pm_runtime_get_if_in_use() in the gpu_busy() and gpu_set_freq() callbacks to skip the hardware access if it isn't active. v2: Use pm_runtime_get_if_in_use() per Eric Anholt Cc: stable@vger.kernel.org Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 ++++++ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 724024a2243a..4d7f269edfcc 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1404,6 +1404,10 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) { u64 busy_cycles, busy_time; + /* Only read the gpu busy if the hardware is already active */ + if (pm_runtime_get_if_in_use(&gpu->pdev->dev) <= 0) + return 0; + busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); @@ -1412,6 +1416,8 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) gpu->devfreq.busy_cycles = busy_cycles; + pm_runtime_put(&gpu->pdev->dev); + if (WARN_ON(busy_time > ~0LU)) return ~0LU; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index c4e71abbdd53..8ace989b11db 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -108,6 +108,13 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index) struct msm_gpu *gpu = &adreno_gpu->base; int ret; + /* + * This can get called from devfreq while the hardware is idle. Don't + * bring up the power if it isn't already active + */ + if (pm_runtime_get_if_in_use(gmu->dev) <= 0) + return; + gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0); gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING, @@ -134,6 +141,7 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index) * for now leave it at max so that the performance is nominal. */ icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216)); + pm_runtime_put(gmu->dev); } void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 68af24150de5..bf43eb2fb078 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -810,6 +810,11 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); u64 busy_cycles, busy_time; + + /* Only read the gpu busy if the hardware is already active */ + if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) <= 0) + return 0; + busy_cycles = gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H); @@ -819,6 +824,8 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) gpu->devfreq.busy_cycles = busy_cycles; + pm_runtime_put(a6xx_gpu->gmu.dev); + if (WARN_ON(busy_time > ~0LU)) return ~0LU; -- 2.17.1