From patchwork Mon May 18 05:13:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 48672 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4C7DC21411 for ; Mon, 18 May 2015 05:14:25 +0000 (UTC) Received: by wixv7 with SMTP id v7sf18251622wix.0 for ; Sun, 17 May 2015 22:14:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=7wPuuFYjwvG8WdFQQmwfUFLhR5/eCVJ0Q2UX1CN0HI8=; b=dse3HPDdEM5uXFJvNboqCe3xS92TJgFlnp7S1mmPQgXud6UdVISBsHoQilszCWO6/x /Lky5YDK5WrxRZdf3vngt3vry0nR7eJnr1OcfDgthlMoJfnVt8QVMs8gQ3LKF/Ljcuyf hGjbfh0mUGhpgyoJ0sEhF3p0n1ZSSstwn2eGvBAY56qxW9nffeirvDzM+N2MIeMKRYO3 5Kc/KmYCRmI8SeEv6potnxP7DwoHPzDRxfNOX9XAm60TsHL1Dy0OpAmBmFH52sDGXpCp nBxnWgd1+37WGZt9D4KW9wdGS1w2tJPjtXGJw8dcMa+SYp9c69H4SXKUZOEqc5ZVnsQX SQPA== X-Gm-Message-State: ALoCoQm8Kmp7wsmrjQDoNwVB6GTqA9YkqS8tqsFZ+en4apzegOs9KPUauRqRtx3FNWymGCrYXPqz X-Received: by 10.180.11.101 with SMTP id p5mr8596651wib.3.1431926064631; Sun, 17 May 2015 22:14:24 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.10.208 with SMTP id k16ls727115lab.42.gmail; Sun, 17 May 2015 22:14:24 -0700 (PDT) X-Received: by 10.153.6.36 with SMTP id cr4mr16310160lad.56.1431926064468; Sun, 17 May 2015 22:14:24 -0700 (PDT) Received: from mail-la0-f51.google.com (mail-la0-f51.google.com. [209.85.215.51]) by mx.google.com with ESMTPS id le4si5939081lac.158.2015.05.17.22.14.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 17 May 2015 22:14:24 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) client-ip=209.85.215.51; Received: by laat2 with SMTP id t2so201805050laa.1 for ; Sun, 17 May 2015 22:14:24 -0700 (PDT) X-Received: by 10.152.21.136 with SMTP id v8mr8224307lae.19.1431926064013; Sun, 17 May 2015 22:14:24 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp3711490lbb; Sun, 17 May 2015 22:14:22 -0700 (PDT) X-Received: by 10.66.232.104 with SMTP id tn8mr40473883pac.73.1431926061983; Sun, 17 May 2015 22:14:21 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id iu9si2678127pbc.77.2015.05.17.22.14.14; Sun, 17 May 2015 22:14:21 -0700 (PDT) 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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750895AbbERFOK (ORCPT + 11 others); Mon, 18 May 2015 01:14:10 -0400 Received: from mail-pd0-f170.google.com ([209.85.192.170]:34823 "EHLO mail-pd0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751223AbbERFOJ (ORCPT ); Mon, 18 May 2015 01:14:09 -0400 Received: by pdea3 with SMTP id a3so132290506pde.2 for ; Sun, 17 May 2015 22:14:09 -0700 (PDT) X-Received: by 10.68.69.40 with SMTP id b8mr23119808pbu.40.1431926049191; Sun, 17 May 2015 22:14:09 -0700 (PDT) Received: from localhost ([122.167.226.34]) by mx.google.com with ESMTPSA id to6sm8597887pbc.19.2015.05.17.22.14.07 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 17 May 2015 22:14:08 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, sboyd@codeaurora.org, prarit@redhat.com, skannan@codeaurora.org, Srivatsa Bhat , Viresh Kumar Subject: [PATCH V5 05/14] cpufreq: Manage governor usage history with 'policy->last_governor' Date: Mon, 18 May 2015 10:43:28 +0530 Message-Id: X-Mailer: git-send-email 2.4.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , History of which governor was used last is common to all CPUs within a policy and maintaining it per-cpu isn't the best approach for sure. Apart from wasting memory, this also increases the complexity of managing this data structure as it has to be updated for all CPUs. To make that somewhat simpler, lets store this information in a new field 'last_governor' in struct cpufreq_policy and update it on removal of last cpu of a policy. As a side-effect it also solves an old problem, consider a system with two clusters 0 & 1. And there is one policy per cluster. Cluster 0: CPU0 and 1. Cluster 1: CPU2 and 3. - CPU2 is first brought online, and governor is set to performance (default as cpufreq_cpu_governor wasn't set). - Governor is changed to ondemand. - CPU2 is taken offline and cpufreq_cpu_governor is updated for CPU2. - CPU3 is brought online. - Because cpufreq_cpu_governor wasn't set for CPU3, the default governor performance is picked for CPU3. This patch fixes the bug as we now have a single variable to update for policy. Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 30 +++++++++++++++--------------- include/linux/cpufreq.h | 1 + 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e6a63d6ba6f1..16275ba6428e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -104,9 +104,6 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); static DEFINE_RWLOCK(cpufreq_driver_lock); DEFINE_MUTEX(cpufreq_governor_lock); -/* This one keeps track of the previously set governor of a removed CPU */ -static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); - /* Flag to suspend/resume CPUFreq governors */ static bool cpufreq_suspended; @@ -1017,7 +1014,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) memcpy(&new_policy, policy, sizeof(*policy)); /* Update governor of new_policy to the governor used before hotplug */ - gov = find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); + gov = find_governor(policy->last_governor); if (gov) pr_debug("Restoring governor %s for cpu %d\n", policy->governor->name, policy->cpu); @@ -1411,14 +1408,15 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, pr_err("%s: Failed to stop governor\n", __func__); return ret; } - - strncpy(per_cpu(cpufreq_cpu_governor, cpu), - policy->governor->name, CPUFREQ_NAME_LEN); } - down_read(&policy->rwsem); + down_write(&policy->rwsem); cpus = cpumask_weight(policy->cpus); - up_read(&policy->rwsem); + + if (has_target() && cpus == 1) + strncpy(policy->last_governor, policy->governor->name, + CPUFREQ_NAME_LEN); + up_write(&policy->rwsem); if (cpu != policy->cpu) { sysfs_remove_link(&dev->kobj, "cpufreq"); @@ -2135,7 +2133,8 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor) { - int cpu; + struct cpufreq_policy *policy; + unsigned long flags; if (!governor) return; @@ -2143,12 +2142,13 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor) if (cpufreq_disabled()) return; - for_each_present_cpu(cpu) { - if (cpu_online(cpu)) - continue; - if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) - strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); + /* clear last_governor for all inactive policies */ + read_lock_irqsave(&cpufreq_driver_lock, flags); + for_each_inactive_policy(policy) { + if (!strcmp(policy->last_governor, governor->name)) + strcpy(policy->last_governor, "\0"); } + read_unlock_irqrestore(&cpufreq_driver_lock, flags); mutex_lock(&cpufreq_governor_mutex); list_del(&governor->governor_list); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 2ee4888c1f47..48e37c07eb84 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -80,6 +80,7 @@ struct cpufreq_policy { struct cpufreq_governor *governor; /* see below */ void *governor_data; bool governor_enabled; /* governor start/stop flag */ + char last_governor[CPUFREQ_NAME_LEN]; /* last governor used */ struct work_struct update; /* if update_policy() needs to be * called, but you're in IRQ context */