summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_cpu.c
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 /sys/kern/kern_cpu.c
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.
Diffstat (limited to 'sys/kern/kern_cpu.c')
-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