From patchwork Fri May 8 06:23:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 48150 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f69.google.com (mail-wg0-f69.google.com [74.125.82.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 98BB02121F for ; Fri, 8 May 2015 06:24:59 +0000 (UTC) Received: by wgtl5 with SMTP id l5sf18922008wgt.1 for ; Thu, 07 May 2015 23:24:58 -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=SFSlW8NNO+PrTNSuM7x4s+geyiw00rWtI3HemOUaKps=; b=Kg9GKQALduiyG28g9y5c91P20PG5Wx8JYn/vB1NWQu0K8EFaKEJxoqk/xEUoa6U7KZ ItHF9UbjzyaD+UoRMaVjmsNW/sQoi74TwJfENu2MZG2BcUtpR9vfFIrOokNsHty7aXaL vTup435DqGnPu0kPTOD+4dl8NQMC19svHUcbKQUme43KKVMqbNQBgNhIEF7bNdD3iKAW A6m5yoIf5YcshRrGjYIIbViZ2rbfQikj52Dw5ZQ8UB3ka5632iu6FfRmoCDN48yQ/vG2 eONoMdI8nUv7No/W8RYxCLJsbdc4aGS3BhPvKsbFOYsensfeJIiH9utN0o2WqnE3mrJa adMQ== X-Gm-Message-State: ALoCoQnavMB+ac9KbElD8NQY00+4KxZfj+YCp719ZoCSRrsLbcuINzgwVPM3Gc20Q8ONVmWEIbIr X-Received: by 10.112.28.111 with SMTP id a15mr1203733lbh.21.1431066298893; Thu, 07 May 2015 23:24:58 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.153.7.167 with SMTP id dd7ls261022lad.28.gmail; Thu, 07 May 2015 23:24:58 -0700 (PDT) X-Received: by 10.112.157.164 with SMTP id wn4mr1713959lbb.100.1431066298747; Thu, 07 May 2015 23:24:58 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id h1si2659428lam.172.2015.05.07.23.24.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 May 2015 23:24:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by lbbqq2 with SMTP id qq2so46449620lbb.3 for ; Thu, 07 May 2015 23:24:58 -0700 (PDT) X-Received: by 10.152.4.137 with SMTP id k9mr1654102lak.29.1431066298642; Thu, 07 May 2015 23:24:58 -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 hn6csp269251lbb; Thu, 7 May 2015 23:24:57 -0700 (PDT) X-Received: by 10.66.196.163 with SMTP id in3mr4022509pac.70.1431066296401; Thu, 07 May 2015 23:24:56 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t17si5783046pdi.227.2015.05.07.23.24.55; Thu, 07 May 2015 23:24:56 -0700 (PDT) Received-SPF: none (google.com: linux-pm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751309AbbEHGYy (ORCPT + 11 others); Fri, 8 May 2015 02:24:54 -0400 Received: from mail-pd0-f178.google.com ([209.85.192.178]:34306 "EHLO mail-pd0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751326AbbEHGYx (ORCPT ); Fri, 8 May 2015 02:24:53 -0400 Received: by pdbqa5 with SMTP id qa5so66450060pdb.1 for ; Thu, 07 May 2015 23:24:53 -0700 (PDT) X-Received: by 10.70.134.133 with SMTP id pk5mr3884185pdb.133.1431066272739; Thu, 07 May 2015 23:24:32 -0700 (PDT) Received: from localhost ([122.172.243.237]) by mx.google.com with ESMTPSA id dc5sm3979687pbc.53.2015.05.07.23.24.31 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 07 May 2015 23:24:32 -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 V3 05/14] cpufreq: Manage governor usage history with 'policy->last_governor' Date: Fri, 8 May 2015 11:53:48 +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.217.174 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 a3eb76969969..5e87679ec6d1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -116,9 +116,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; @@ -1029,7 +1026,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); @@ -1423,14 +1420,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"); @@ -2147,7 +2145,8 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor) { - int cpu; + struct cpufreq_policy *policy, *tpolicy; + unsigned long flags; if (!governor) return; @@ -2155,12 +2154,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, tpolicy) { + 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 */