Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932788AbcCJWS4 (ORCPT ); Thu, 10 Mar 2016 17:18:56 -0500 Received: from v094114.home.net.pl ([79.96.170.134]:64259 "HELO v094114.home.net.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S932436AbcCJWSx (ORCPT ); Thu, 10 Mar 2016 17:18:53 -0500 From: "Rafael J. Wysocki" To: Richard Cochran Cc: linux-kernel@vger.kernel.org, rt@linutronix.de, "Rafael J. Wysocki" , Viresh Kumar , Linux PM list Subject: Re: [PATCH] cpufreq: Make cpufreq_quick_get() safe to call. Date: Thu, 10 Mar 2016 23:20:47 +0100 Message-ID: <3267506.5YnhcYthBi@vostro.rjw.lan> User-Agent: KMail/4.11.5 (Linux/4.5.0-rc1+; KDE/4.11.5; x86_64; ; ) In-Reply-To: <1457622636-10028-1-git-send-email-rcochran@linutronix.de> References: <1457622636-10028-1-git-send-email-rcochran@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="utf-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1910 Lines: 60 On Thursday, March 10, 2016 04:10:36 PM Richard Cochran wrote: > The function, cpufreq_quick_get, accesses the global 'cpufreq_driver' and > its fields without taking the associated lock, cpufreq_driver_lock. > > Without the locking, nothing guarantees that 'cpufreq_driver' remains > consistent during the call. This patch fixes the issue by taking the lock > before accessing the data structure. > > Cc: Dirk Brandewie > Cc: Rafael J. Wysocki > Cc: Viresh Kumar > Signed-off-by: Richard Cochran Can you please CC PM-related patches to linux-pm@vger.kernel.org? They are much easier to handle for me then. > --- > drivers/cpufreq/cpufreq.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c > index e979ec7..ce02b2b 100644 > --- a/drivers/cpufreq/cpufreq.c > +++ b/drivers/cpufreq/cpufreq.c > @@ -1457,9 +1457,17 @@ unsigned int cpufreq_quick_get(unsigned int cpu) > { > struct cpufreq_policy *policy; > unsigned int ret_freq = 0; > + unsigned long flags; > + > + read_lock_irqsave(&cpufreq_driver_lock, flags); > > if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) > - return cpufreq_driver->get(cpu); > + ret_freq = cpufreq_driver->get(cpu); > + > + read_unlock_irqrestore(&cpufreq_driver_lock, flags); > + > + if (ret_freq) > + return ret_freq; > > policy = cpufreq_cpu_get(cpu); > if (policy) { > I would prefer something like this: read_lock_irqsave(&cpufreq_driver_lock, flags); if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) { unsigned int ret_freq = cpufreq_driver->get(cpu); read_unlock_irqrestore(&cpufreq_driver_lock, flags); return ret_freq; } read_unlock_irqrestore(&cpufreq_driver_lock, flags); Thanks, Rafael