summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2005-02-15 07:22:42 +0000
committernjl <njl@FreeBSD.org>2005-02-15 07:22:42 +0000
commitea80935c2aea86b616173763d1c4e3257fdb40f1 (patch)
treeb005af70181577d5d4e3565832e2dc98c5741c19
parent9f5b889b7b37c36d49786ca6e494aa05ad996edb (diff)
downloadFreeBSD-src-ea80935c2aea86b616173763d1c4e3257fdb40f1.zip
FreeBSD-src-ea80935c2aea86b616173763d1c4e3257fdb40f1.tar.gz
Bind to the driver's parent cpu before switching, for both absolute and
relative drivers. Remove some extraneous KASSERTs since NULL pointers will be found when they're used right afterwards.
-rw-r--r--sys/kern/kern_cpu.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
index 85b33d1..df88473 100644
--- a/sys/kern/kern_cpu.c
+++ b/sys/kern/kern_cpu.c
@@ -207,16 +207,6 @@ cf_set_method(device_t dev, const struct cf_level *level, int priority)
if (CPUFREQ_CMP(sc->curr_level.total_set.freq, level->total_set.freq))
return (0);
- /* If the setting is for a different CPU, switch to it. */
- cpu_id = PCPU_GET(cpuid);
- pc = cpu_get_pcpu(dev);
- KASSERT(pc, ("NULL pcpu for dev %p", dev));
- if (cpu_id != pc->pc_cpuid) {
- mtx_lock_spin(&sched_lock);
- sched_bind(curthread, pc->pc_cpuid);
- mtx_unlock_spin(&sched_lock);
- }
-
/* First, set the absolute frequency via its driver. */
set = &level->abs_set;
if (set->dev) {
@@ -224,7 +214,21 @@ cf_set_method(device_t dev, const struct cf_level *level, int priority)
error = ENXIO;
goto out;
}
+
+ /* Bind to the target CPU before switching, if necessary. */
+ cpu_id = PCPU_GET(cpuid);
+ pc = cpu_get_pcpu(set->dev);
+ if (cpu_id != pc->pc_cpuid) {
+ mtx_lock_spin(&sched_lock);
+ sched_bind(curthread, pc->pc_cpuid);
+ mtx_unlock_spin(&sched_lock);
+ }
error = CPUFREQ_DRV_SET(set->dev, set);
+ if (cpu_id != pc->pc_cpuid) {
+ mtx_lock_spin(&sched_lock);
+ sched_unbind(curthread);
+ mtx_unlock_spin(&sched_lock);
+ }
if (error) {
goto out;
}
@@ -237,7 +241,21 @@ cf_set_method(device_t dev, const struct cf_level *level, int priority)
error = ENXIO;
goto out;
}
+
+ /* Bind to the target CPU before switching, if necessary. */
+ cpu_id = PCPU_GET(cpuid);
+ pc = cpu_get_pcpu(set->dev);
+ if (cpu_id != pc->pc_cpuid) {
+ mtx_lock_spin(&sched_lock);
+ sched_bind(curthread, pc->pc_cpuid);
+ mtx_unlock_spin(&sched_lock);
+ }
error = CPUFREQ_DRV_SET(set->dev, set);
+ if (cpu_id != pc->pc_cpuid) {
+ mtx_lock_spin(&sched_lock);
+ sched_unbind(curthread);
+ mtx_unlock_spin(&sched_lock);
+ }
if (error) {
/* XXX Back out any successful setting? */
goto out;
@@ -266,12 +284,6 @@ cf_set_method(device_t dev, const struct cf_level *level, int priority)
error = 0;
out:
- /* If we switched to another CPU, switch back before exiting. */
- if (cpu_id != pc->pc_cpuid) {
- mtx_lock_spin(&sched_lock);
- sched_unbind(curthread);
- mtx_unlock_spin(&sched_lock);
- }
if (error)
device_printf(set->dev, "set freq failed, err %d\n", error);
return (error);
@@ -732,7 +744,6 @@ cpufreq_register(device_t dev)
* must offer the same levels and be switched at the same time.
*/
cpu_dev = device_get_parent(dev);
- KASSERT(cpu_dev != NULL, ("no parent for %p", dev));
if (device_find_child(cpu_dev, "cpufreq", -1))
return (0);
@@ -761,7 +772,6 @@ cpufreq_unregister(device_t dev)
if (error)
return (error);
cf_dev = devclass_get_device(cpufreq_dc, 0);
- KASSERT(cf_dev != NULL, ("unregister with no cpufreq dev"));
cfcount = 0;
for (i = 0; i < devcount; i++) {
if (!device_is_attached(devs[i]))
OpenPOWER on IntegriCloud