From patchwork Mon Jan 7 18:51:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 154949 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp4010967jaa; Mon, 7 Jan 2019 10:52:02 -0800 (PST) X-Google-Smtp-Source: ALg8bN5jFblrzTdJGpVNs8U7eJ9TzlTYX/HGU1vDalHfNYDpkLPuc0NPJkPAvXSeDFcifbRPdeal X-Received: by 2002:a17:902:4827:: with SMTP id s36mr60308468pld.168.1546887122674; Mon, 07 Jan 2019 10:52:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546887122; cv=none; d=google.com; s=arc-20160816; b=cK8sY0a13JI9JMwyEudvgglc4nFYJJG84YTqHJ7PMCeU+A56nfeWVJv0Ql8Sxn9NEv 1BvT6AntQ+7O6SeS/afpP/t2T9Z3dxPCr8j+mgQdG117EQmEHAZBX10OgdvN6weCDqk9 ATUWyxbYnr+Xb3/V1TpObfOxdgibFJ3fD9Q41mWXFMn4b/6VYa7DYq8QhNHagUSXv8g0 Q2YkHU+dsk5wnSvIeaoxGCZRJAqV2hr2fjiHMJmDmNmPQ3QF8tUH84NZQj2Ed0oIsTvj dz1T3DWrFMO01oqt5jQJiIoqGVJ1Vr7lvdfJtG6v4t0yapaV41dULLg8FyHK/vC+4qta GcJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=CCeX92ST2G7qOGuizv+FnkA6FJE6C9WD6gB5bmx7dj8=; b=UINnv9sQCmrQUe2evq6+DVAmxF+bUX70RF9ziDiduaUGEo+wqEJgqESG+0g2Ul4WMP MxOT+mO563QLS8mQiWug6aPIzsnaVBzx/kT4RStAFnSvZ9EAullrZX/OFNm+HUg9Nc2q GS3eMskiGnK7BJaR2g7Fszf8+IB/o7Jxi6aVZr8BOUWI3chB3bZ0C1j0s78LlVa72Va9 LFLqRtkczN94B8ezm1beiXoylce+wWux46bxOzgNH1zs12Y+J0ueOtlli35C0CGKwBRv mt6j4DsOxDLp3KcbPrW1W33wYRULYkPhIflbOuWRcPK2b7/pujKr1YWIp8N6OF4QGPgy 4Z9g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-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 e4si57973plk.260.2019.01.07.10.52.02; Mon, 07 Jan 2019 10:52:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-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-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727466AbfAGSwB (ORCPT + 11 others); Mon, 7 Jan 2019 13:52:01 -0500 Received: from foss.arm.com ([217.140.101.70]:37794 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726989AbfAGSwB (ORCPT ); Mon, 7 Jan 2019 13:52:01 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BB53380D; Mon, 7 Jan 2019 10:52:00 -0800 (PST) Received: from usa.arm.com (e107155-lin.cambridge.arm.com [10.1.196.42]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CD67A3F5A0; Mon, 7 Jan 2019 10:51:59 -0800 (PST) From: Sudeep Holla To: linux-pm@vger.kernel.org Cc: Sudeep Holla , "Rafael J. Wysocki" , Viresh Kumar Subject: [PATCH v2] cpufreq: check if policy is inactive early in __cpufreq_get Date: Mon, 7 Jan 2019 18:51:53 +0000 Message-Id: <20190107185153.23220-1-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190104114249.5355-1-sudeep.holla@arm.com> References: <20190104114249.5355-1-sudeep.holla@arm.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org cpuinfo_cur_freq gets current CPU frequency as detected by hardware while scaling_cur_freq last known CPU frequency. Some platforms may not allow checking the CPU frequency of an offline CPU or the associated resources may have been released via cpufreq_exit when the CPU gets offlined, in which case the policy would have been invalidated already. If we attempt to get current frequency from the hardware, it may result in hang or crash. For example on Juno, I see: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000188 [0000000000000188] pgd=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: CPU: 5 PID: 4202 Comm: cat Not tainted 4.20.0-08251-ga0f2c0318a15-dirty #87 Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform pstate: 40000005 (nZcv daif -PAN -UAO) pc : scmi_cpufreq_get_rate+0x34/0xb0 lr : scmi_cpufreq_get_rate+0x34/0xb0 Call trace: scmi_cpufreq_get_rate+0x34/0xb0 __cpufreq_get+0x34/0xc0 show_cpuinfo_cur_freq+0x24/0x78 show+0x40/0x60 sysfs_kf_seq_show+0xc0/0x148 kernfs_seq_show+0x44/0x50 seq_read+0xd4/0x480 kernfs_fop_read+0x15c/0x208 __vfs_read+0x60/0x188 vfs_read+0x94/0x150 ksys_read+0x6c/0xd8 __arm64_sys_read+0x24/0x30 el0_svc_common+0x78/0x100 el0_svc_handler+0x38/0x78 el0_svc+0x8/0xc ---[ end trace 3d1024e58f77f6b2 ]--- So fix the issue by checking if the policy is invalid early in __cpufreq_get before attempting to get the current frequency. Cc: "Rafael J. Wysocki" Cc: Viresh Kumar Signed-off-by: Sudeep Holla --- drivers/cpufreq/cpufreq.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) v1->v2: - Instead of calling cpufreq_get directly from show_cpuinfo_cur_freq fixed __cpufreq_get to handle invalid policy(moved handling from cpufreq_get into __cpufreq_get) -- 2.17.1 Acked-by: Viresh Kumar diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 6f23ebb395f1..e35a886e00bc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1530,17 +1530,16 @@ static unsigned int __cpufreq_get(struct cpufreq_policy *policy) { unsigned int ret_freq = 0; - if (!cpufreq_driver->get) + if (unlikely(policy_is_inactive(policy)) || !cpufreq_driver->get) return ret_freq; ret_freq = cpufreq_driver->get(policy->cpu); /* - * Updating inactive policies is invalid, so avoid doing that. Also - * if fast frequency switching is used with the given policy, the check + * If fast frequency switching is used with the given policy, the check * against policy->cur is pointless, so skip it in that case too. */ - if (unlikely(policy_is_inactive(policy)) || policy->fast_switch_enabled) + if (policy->fast_switch_enabled) return ret_freq; if (ret_freq && policy->cur && @@ -1569,10 +1568,7 @@ unsigned int cpufreq_get(unsigned int cpu) if (policy) { down_read(&policy->rwsem); - - if (!policy_is_inactive(policy)) - ret_freq = __cpufreq_get(policy); - + ret_freq = __cpufreq_get(policy); up_read(&policy->rwsem); cpufreq_cpu_put(policy);