From: Saravana Kannan <skannan@codeaurora.org>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Rafael Wysocki <rjw@rjwysocki.net>,
linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org,
sboyd@codeaurora.org, prarit@redhat.com
Subject: Re: [PATCH V2 11/20] cpufreq: Manage governor usage history with 'policy->last_governor'
Date: Wed, 01 Apr 2015 21:34:11 -0700 [thread overview]
Message-ID: <551CC6C3.2000102@codeaurora.org> (raw)
In-Reply-To: <073c66088540954706ba5ffc0e4c2efa4759d197.1424345053.git.viresh.kumar@linaro.org>
On 02/19/2015 03:32 AM, Viresh Kumar wrote:
> 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.
This governor restore code actually has bug -- at least in 3.12 (I
think) but probably has a bug in this kernel too. So, this patch
actually also fixes a bug.
The bug has to do with restoring the wrong governor (as in, not the
governor that was last picked by userspace) for a particular hot plug
sequence.
Assume one cluster has CPUs 2, 3.
Assume default governor is performance.
CPU2 is first brought online.
Governor is changed to ondemand.
CPU2 is taken offline.
CPU3 is brought online.
Governor gets set to performance.
So, governor for the cluster is now not what was last picked by userspace.
>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> 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 20d5f4590c4b..b7cd1bf97044 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -115,9 +115,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;
>
> @@ -1028,7 +1025,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);
> @@ -1422,14 +1419,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");
> @@ -2142,7 +2140,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;
> @@ -2150,12 +2149,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);
You are writing to a variable that's protected. This should be a write lock.
> + 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 */
>
Nack due to lock.
-Saravana
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2015-04-02 4:34 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-19 11:32 [PATCH V2 00/20] cpufreq: Don't loose cpufreq history on CPU hotplug Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 01/20] cpufreq: Add doc style comment about cpufreq_cpu_{get|put}() Viresh Kumar
2015-03-20 0:34 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 02/20] cpufreq: Merge __cpufreq_add_dev() and cpufreq_add_dev() Viresh Kumar
2015-03-20 0:34 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 03/20] cpufreq: Throw warning when we try to get policy for an invalid CPU Viresh Kumar
2015-03-20 0:34 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 04/20] cpufreq: Keep a single path for adding managed CPUs Viresh Kumar
2015-03-20 0:37 ` Saravana Kannan
2015-03-20 3:16 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 05/20] cpufreq: Clear policy->cpus even for the last CPU Viresh Kumar
2015-03-20 0:43 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 06/20] cpufreq: Create for_each_{in}active_policy() Viresh Kumar
2015-03-20 1:01 ` Saravana Kannan
2015-03-20 4:41 ` Viresh Kumar
2015-03-20 19:18 ` Saravana Kannan
2015-05-07 22:11 ` Rafael J. Wysocki
2015-05-08 2:33 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 07/20] cpufreq: Call schedule_work() for the last active policy Viresh Kumar
2015-04-02 3:40 ` Saravana Kannan
2015-04-02 5:02 ` Viresh Kumar
2015-05-07 22:13 ` Rafael J. Wysocki
2015-05-08 2:36 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 08/20] cpufreq: Don't clear cpufreq_cpu_data and policy list for inactive policies Viresh Kumar
2015-04-02 4:14 ` Saravana Kannan
2015-04-02 5:11 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 09/20] cpufreq: Get rid of cpufreq_cpu_data_fallback Viresh Kumar
2015-04-02 4:20 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 10/20] cpufreq: Don't traverse list of all policies for adding policy for a cpu Viresh Kumar
2015-04-02 4:24 ` Saravana Kannan
2015-02-19 11:32 ` [PATCH V2 11/20] cpufreq: Manage governor usage history with 'policy->last_governor' Viresh Kumar
2015-04-02 4:34 ` Saravana Kannan [this message]
2015-04-02 5:26 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 12/20] cpufreq: Mark policy->governor = NULL for inactive policies Viresh Kumar
2015-04-02 4:38 ` Saravana Kannan
2015-04-02 6:09 ` Viresh Kumar
2015-04-04 1:20 ` Saravana Kannan
2015-04-04 3:07 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 13/20] cpufreq: Don't allow updating inactive-policies from sysfs Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 14/20] cpufreq: Track cpu managing sysfs kobjects separately Viresh Kumar
2015-04-02 4:40 ` Saravana Kannan
2015-04-02 5:41 ` Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 15/20] cpufreq: Stop migrating sysfs files on hotplug Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 16/20] cpufreq: Remove cpufreq_update_policy() Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 17/20] cpufreq: Initialize policy->kobj while allocating policy Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 18/20] cpufreq: Call cpufreq_policy_put_kobj() from cpufreq_policy_free() Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 19/20] cpufreq: Restart governor as soon as possible Viresh Kumar
2015-02-19 11:32 ` [PATCH V2 20/20] cpufreq: Add support for physical hoplug of CPUs Viresh Kumar
2015-02-27 5:26 ` [PATCH V2 00/20] cpufreq: Don't loose cpufreq history on CPU hotplug Viresh Kumar
2015-02-28 2:36 ` Saravana Kannan
2015-03-16 9:45 ` Viresh Kumar
2015-03-17 22:13 ` Saravana Kannan
2015-03-26 11:59 ` Viresh Kumar
2015-03-26 20:28 ` Rafael J. Wysocki
2015-03-26 20:41 ` Saravana Kannan
2015-03-27 5:15 ` Viresh Kumar
2015-03-20 0:33 ` Saravana Kannan
2015-05-07 22:18 ` Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=551CC6C3.2000102@codeaurora.org \
--to=skannan@codeaurora.org \
--cc=linaro-kernel@lists.linaro.org \
--cc=linux-pm@vger.kernel.org \
--cc=prarit@redhat.com \
--cc=rjw@rjwysocki.net \
--cc=sboyd@codeaurora.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).