From: Nathan Zimmer <nzimmer@sgi.com>
To: viresh.kumar@linaro.org, rjw@sisk.pl
Cc: cpufreq@vger.kernel.org, linux-pm@vger.kernel.org,
linux-kernel@vger.kernel.org, Nathan Zimmer <nzimmer@sgi.com>
Subject: [PATCH v4 1/2] cpufreq: Convert the cpufreq_driver_lock to a rwlock
Date: Fri, 22 Feb 2013 10:24:34 -0600 [thread overview]
Message-ID: <1361550275-5716-2-git-send-email-nzimmer@sgi.com> (raw)
In-Reply-To: <1361550275-5716-1-git-send-email-nzimmer@sgi.com>
This eliminates the contention I am seeing in __cpufreq_cpu_get.
It also nicely stages the lock to be replaced by the rcu.
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
---
drivers/cpufreq/cpufreq.c | 52 +++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b02824d..c5996fe 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -45,7 +45,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
/* This one keeps track of the previously set governor of a removed CPU */
static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
#endif
-static DEFINE_SPINLOCK(cpufreq_driver_lock);
+static DEFINE_RWLOCK(cpufreq_driver_lock);
/*
* cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
@@ -137,7 +137,7 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
goto err_out;
/* get the cpufreq driver */
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ read_lock_irqsave(&cpufreq_driver_lock, flags);
if (!cpufreq_driver)
goto err_out_unlock;
@@ -155,13 +155,13 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
if (!sysfs && !kobject_get(&data->kobj))
goto err_out_put_module;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
return data;
err_out_put_module:
module_put(cpufreq_driver->owner);
err_out_unlock:
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
err_out:
return NULL;
}
@@ -266,9 +266,9 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
pr_debug("notification %u of frequency transition to %u kHz\n",
state, freqs->new);
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ read_lock_irqsave(&cpufreq_driver_lock, flags);
policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
switch (state) {
@@ -765,12 +765,12 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
goto err_out_kobj_put;
}
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus) {
per_cpu(cpufreq_cpu_data, j) = policy;
per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
}
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
ret = cpufreq_add_dev_symlink(cpu, policy);
if (ret)
@@ -813,12 +813,12 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
lock_policy_rwsem_write(sibling);
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
cpumask_set_cpu(cpu, policy->cpus);
per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
per_cpu(cpufreq_cpu_data, cpu) = policy;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
unlock_policy_rwsem_write(sibling);
@@ -871,15 +871,15 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
#ifdef CONFIG_HOTPLUG_CPU
/* Check if this cpu was hot-unplugged earlier and has siblings */
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ read_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_online_cpu(sibling) {
struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
return cpufreq_add_policy_cpu(cpu, sibling, dev);
}
}
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
#endif
#endif
@@ -952,10 +952,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
return 0;
err_out_unregister:
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus)
per_cpu(cpufreq_cpu_data, j) = NULL;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
@@ -1008,12 +1008,12 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
data = per_cpu(cpufreq_cpu_data, cpu);
per_cpu(cpufreq_cpu_data, cpu) = NULL;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
if (!data) {
pr_debug("%s: No cpu_data found\n", __func__);
@@ -1047,9 +1047,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
WARN_ON(lock_policy_rwsem_write(cpu));
cpumask_set_cpu(cpu, data->cpus);
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
per_cpu(cpufreq_cpu_data, cpu) = data;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
unlock_policy_rwsem_write(cpu);
@@ -1848,13 +1848,13 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
if (driver_data->setpolicy)
driver_data->flags |= CPUFREQ_CONST_LOOPS;
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
if (cpufreq_driver) {
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
return -EBUSY;
}
cpufreq_driver = driver_data;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
ret = subsys_interface_register(&cpufreq_interface);
if (ret)
@@ -1886,9 +1886,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
err_if_unreg:
subsys_interface_unregister(&cpufreq_interface);
err_null_driver:
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver = NULL;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
return ret;
}
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
@@ -1914,9 +1914,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
subsys_interface_unregister(&cpufreq_interface);
unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
- spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver = NULL;
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
return 0;
}
--
1.8.1.2
next prev parent reply other threads:[~2013-02-22 16:24 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-04 22:45 [PATCH 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Nathan Zimmer
2013-02-04 22:45 ` [PATCH 1/2] cpufreq: Convert the cpufreq_driver_lock to a rwlock Nathan Zimmer
2013-02-05 8:11 ` Viresh Kumar
2013-02-04 22:45 ` [PATCH 2/2] cpufreq: Convert the cpufreq_driver_lock to use the rcu Nathan Zimmer
2013-02-05 1:07 ` [PATCH 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Rafael J. Wysocki
2013-02-05 8:28 ` Viresh Kumar
2013-02-05 10:03 ` Rafael J. Wysocki
2013-02-05 9:58 ` Viresh Kumar
2013-02-05 10:13 ` Rafael J. Wysocki
2013-02-05 14:58 ` Nathan Zimmer
2013-02-05 22:00 ` Rafael J. Wysocki
2013-02-06 2:04 ` [PATCH v2 linux-next " Nathan Zimmer
2013-02-06 2:04 ` [PATCH v2 linux-next 1/2] cpufreq: Convert the cpufreq_driver_lock to a rwlock Nathan Zimmer
2013-02-06 2:47 ` Viresh Kumar
2013-02-06 2:04 ` [PATCH v2 linux-next 2/2] cpufreq: Convert the cpufreq_driver_lock to use the rcu Nathan Zimmer
2013-02-06 2:52 ` Viresh Kumar
2013-02-06 8:51 ` Viresh Kumar
2013-02-06 13:00 ` Rafael J. Wysocki
2013-02-07 23:29 ` Rafael J. Wysocki
2013-02-11 17:13 ` Nathan Zimmer
2013-02-11 19:36 ` Rafael J. Wysocki
2013-02-12 4:03 ` Nathan Zimmer
2013-02-12 15:59 ` Paul E. McKenney
2013-02-13 13:20 ` Rafael J. Wysocki
2013-02-20 23:56 ` [PATCH v3 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Nathan Zimmer
2013-02-20 23:56 ` [PATCH v3 1/2] cpufreq: Convert the cpufreq_driver_lock to a rwlock Nathan Zimmer
2013-02-20 23:56 ` [PATCH v3 2/2] cpufreq: Convert the cpufreq_driver_lock to use the rcu Nathan Zimmer
2013-02-21 5:50 ` Viresh Kumar
2013-02-21 17:49 ` Nathan Zimmer
2013-02-22 16:24 ` [PATCH v4 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Nathan Zimmer
2013-02-22 16:24 ` Nathan Zimmer [this message]
2013-02-23 3:57 ` [PATCH v4 1/2] cpufreq: Convert the cpufreq_driver_lock to a rwlock Viresh Kumar
2013-02-22 16:24 ` [PATCH v4 2/2] cpufreq: Convert the cpufreq_driver_lock to use the rcu Nathan Zimmer
2013-02-23 3:39 ` Viresh Kumar
2013-02-25 20:07 ` Nathan Zimmer
2013-03-11 23:23 ` [PATCH v4 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Rafael J. Wysocki
2013-03-13 20:50 ` Nathan Zimmer
2013-04-01 15:33 ` [PATCH v5] cpufreq: split the cpufreq_driver_lock and use the rcu (was cpufreq: cpufreq_driver_lock is hot on large systems) Nathan Zimmer
2013-04-01 16:28 ` Viresh Kumar
2013-04-01 17:17 ` Nathan Zimmer
2013-04-01 20:11 ` [PATCH v6 0/2] cpufreq: cpufreq_driver_lock is hot on large systems Nathan Zimmer
2013-04-01 20:11 ` [PATCH v6 1/2] cpufreq: split the cpufreq_driver_lock and use the rcu Nathan Zimmer
2013-04-02 5:05 ` Viresh Kumar
2013-04-02 14:55 ` Nathan Zimmer
2013-04-02 14:59 ` Viresh Kumar
2013-04-02 15:40 ` Nathan Zimmer
2013-04-02 15:52 ` Viresh Kumar
2013-04-02 22:57 ` Rafael J. Wysocki
2013-04-03 5:25 ` Viresh Kumar
2013-04-01 20:11 ` [PATCH v6 2/2] cpufreq: covert the cpufreq_data_lock to a spinlock Nathan Zimmer
2013-04-01 20:41 ` Rafael J. Wysocki
2013-04-02 0:56 ` Nathan Zimmer
2013-04-02 5:04 ` Viresh Kumar
2013-04-02 12:48 ` Rafael J. Wysocki
2013-04-02 14:58 ` Nathan Zimmer
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=1361550275-5716-2-git-send-email-nzimmer@sgi.com \
--to=nzimmer@sgi.com \
--cc=cpufreq@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rjw@sisk.pl \
--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).