From patchwork Thu Oct 29 12:27:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 55757 Delivered-To: patch@linaro.org Received: by 10.112.61.134 with SMTP id p6csp529639lbr; Thu, 29 Oct 2015 05:27:39 -0700 (PDT) X-Received: by 10.50.43.234 with SMTP id z10mr3420452igl.53.1446121658864; Thu, 29 Oct 2015 05:27:38 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v2si26144637igh.21.2015.10.29.05.27.38; Thu, 29 Oct 2015 05:27:38 -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; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756230AbbJ2M1g (ORCPT + 28 others); Thu, 29 Oct 2015 08:27:36 -0400 Received: from mail-pa0-f52.google.com ([209.85.220.52]:36700 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751144AbbJ2M1e (ORCPT ); Thu, 29 Oct 2015 08:27:34 -0400 Received: by pacfv9 with SMTP id fv9so41601524pac.3 for ; Thu, 29 Oct 2015 05:27:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=YICNleFv3VwXSldTX64x+Yn0sWRwq6nySTzdiIONnWM=; b=KKN2cRQ+F9ZRUNmS0rzZmyEe86DuLkDneAwsCq6Dn2Y3ShovJBgsXnlklvlbYNJ+5a nD2ocWvuKfihoepOe1MleQgk42ZNbp0evVGmZTfT6OxgmaUndJ/iIusnZIgfYscKjRwe eRVODIs5W5C3tNheQPazqnL22NBVatyB3ywWPaRSMld1DrbaGZuhAjLtv6kheW2j6gF2 AZeZimYSgAhOJ1E8/t4OQXjC8scFE++PCAUo/Q1YhrDzVnwYY6DZZ1c5AjcnODFf0O5y 5EhAHtATOSiwtAGKTk2CIfAXmETXmx7IkJo2h+Qx62uflnNxyPY0Uqemxcs+ive+HeFX +aKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=YICNleFv3VwXSldTX64x+Yn0sWRwq6nySTzdiIONnWM=; b=JZTIeNDfqrXkk3sDtVOIFayZ2UCognKJ1nqFg22Y4GcwmSsvpgtYrWmAevLcKizqcH U3G6nQsYqdBGO+tyNwi4F1Igyr3O7Y8GKVAqIQB5yua7dncZaLrq22vasqVYIt8ZSap/ 8n1RjykdBgOt1CEoZwBDxFCrK/fWAs4gYPmZ9LFFiVNLGQ1H9ZtUPM0Kj6lGHdSoJxNU YHb1YWRh6lC4n+hzWR9gwHrkwcdG74ylaxgkurD7fnNFnICy/jcyBFFY4b7+oA9vlEow H507QITFl05v+1C0dSTJvnWFuP2CE9uWgFArJ/tjQTECgszgn2aB1pohXfka+ugzcTqz t5Wg== X-Gm-Message-State: ALoCoQn7XT7R9k3qTgMzwkSQVLmtsAkrTK1hD1bMMQEq17rhL6uhlNTovMekKyqcZJVddXjH20N6 X-Received: by 10.66.164.10 with SMTP id ym10mr1684086pab.26.1446121654136; Thu, 29 Oct 2015 05:27:34 -0700 (PDT) Received: from localhost ([122.172.111.169]) by smtp.gmail.com with ESMTPSA id qd2sm2168471pbb.68.2015.10.29.05.27.32 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 29 Oct 2015 05:27:33 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, Viresh Kumar , linux-kernel@vger.kernel.org (open list) Subject: [PATCH 1/6] cpufreq: ondemand: Update sampling rate only for concerned policies Date: Thu, 29 Oct 2015 17:57:20 +0530 Message-Id: X-Mailer: git-send-email 2.6.2.198.g614a2ac In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We are comparing policy->governor against cpufreq_gov_ondemand to make sure that we update sampling rate only for the concerned CPUs. But that isn't enough. In case of governor_per_policy, there can be multiple instances of ondemand governor and we will always end up updating all of them with current code. What we rather need to do, is to compare dbs_data with poilcy->governor_data, which will match only for the policies governed by dbs_data. This code is also racy as the governor might be getting stopped at that time and we may end up scheduling work for a policy, which we have just disabled. Fix that by protecting the entire function with &od_dbs_cdata.mutex, which will prevent against races with policy START/STOP/etc. After these locks are in place, we can safely get the policy via per-cpu dbs_info. Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq_ondemand.c | 40 ++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) -- 2.6.2.198.g614a2ac -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 03ac6ce54042..0800a937607b 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -247,25 +247,43 @@ static void update_sampling_rate(struct dbs_data *dbs_data, unsigned int new_rate) { struct od_dbs_tuners *od_tuners = dbs_data->tuners; + struct od_cpu_dbs_info_s *dbs_info; + struct cpu_dbs_info *cdbs; + struct cpufreq_policy *policy; + struct cpu_common_dbs_info *shared; + unsigned long next_sampling, appointed_at; int cpu; od_tuners->sampling_rate = new_rate = max(new_rate, dbs_data->min_sampling_rate); + /* + * Lock governor so that governor start/stop can't execute in parallel. + */ + mutex_lock(&od_dbs_cdata.mutex); + for_each_online_cpu(cpu) { - struct cpufreq_policy *policy; - struct od_cpu_dbs_info_s *dbs_info; - unsigned long next_sampling, appointed_at; + dbs_info = &per_cpu(od_cpu_dbs_info, cpu); + cdbs = &dbs_info->cdbs; + shared = cdbs->shared; - policy = cpufreq_cpu_get(cpu); - if (!policy) + /* + * A valid shared and shared->policy means governor hasn't + * stopped or exited yet. + */ + if (!shared || !shared->policy) continue; - if (policy->governor != &cpufreq_gov_ondemand) { - cpufreq_cpu_put(policy); + + policy = shared->policy; + + /* + * Update sampling rate for CPUs whose policy is governed by + * dbs_data. In case of governor_per_policy, only a single + * policy will be governed by dbs_data, otherwise there can be + * multiple policies that are governed by the same dbs_data. + */ + if (dbs_data != policy->governor_data) continue; - } - dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - cpufreq_cpu_put(policy); if (!delayed_work_pending(&dbs_info->cdbs.dwork)) continue; @@ -281,6 +299,8 @@ static void update_sampling_rate(struct dbs_data *dbs_data, } } + + mutex_unlock(&od_dbs_cdata.mutex); } static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,