summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormh27603 <none@none>2007-08-16 16:52:20 -0700
committermh27603 <none@none>2007-08-16 16:52:20 -0700
commit68afbec1fabe0d352bb5ab4ed82c44b58ec651fb (patch)
tree32317f52d74b2c7615c7cb023fc46bc7c5d40998
parent8d483882aa3390058094b043f3d62187b5d1de03 (diff)
downloadillumos-gate-68afbec1fabe0d352bb5ab4ed82c44b58ec651fb.tar.gz
6587576 cpu_info kstat is returning garbage in supported_frequencies_Hz
-rw-r--r--usr/src/uts/common/io/cpudrv.c9
-rw-r--r--usr/src/uts/common/os/cpu.c54
-rw-r--r--usr/src/uts/common/sys/cpudrv.h1
-rw-r--r--usr/src/uts/common/sys/cpuvar.h4
-rw-r--r--usr/src/uts/i86pc/os/mp_startup.c5
-rw-r--r--usr/src/uts/sun4u/os/mach_mp_startup.c5
-rw-r--r--usr/src/uts/sun4v/os/mach_mp_startup.c5
7 files changed, 72 insertions, 11 deletions
diff --git a/usr/src/uts/common/io/cpudrv.c b/usr/src/uts/common/io/cpudrv.c
index 31a522e93b..0fa758e282 100644
--- a/usr/src/uts/common/io/cpudrv.c
+++ b/usr/src/uts/common/io/cpudrv.c
@@ -311,6 +311,7 @@ cpudrv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
mutex_enter(&cpudsp->lock);
cpudsp->cpudrv_pm.cur_spd = NULL;
cpudsp->cpudrv_pm.targ_spd = cpudsp->cpudrv_pm.head_spd;
+ cpudsp->cpudrv_pm.pm_started = B_FALSE;
/*
* We don't call pm_raise_power() directly from attach because
* driver attach for a slave CPU node can happen before the
@@ -590,7 +591,8 @@ set_supp_freqs(cpu_t *cp, cpudrv_pm_t *cpupm)
sfptr = supp_freqs + strlen(supp_freqs);
}
}
- cp->cpu_supp_freqs = supp_freqs;
+ cpu_set_supp_freqs(cp, supp_freqs);
+ kmem_free(supp_freqs, (UINT64_MAX_STRING * cpupm->num_spd));
kmem_free(speeds, cpupm->num_spd * sizeof (uint64_t));
}
@@ -1012,8 +1014,11 @@ cpudrv_pm_monitor(void *arg)
"cpu_t", ddi_get_instance(dip));
goto do_return;
}
- if (cp->cpu_supp_freqs == NULL)
+
+ if (!cpupm->pm_started) {
+ cpupm->pm_started = B_TRUE;
set_supp_freqs(cp, cpupm);
+ }
cpudrv_get_cpu_mstate(cp, msnsecs);
GET_CPU_MSTATE_CNT(CMS_IDLE, idle_cnt);
diff --git a/usr/src/uts/common/os/cpu.c b/usr/src/uts/common/os/cpu.c
index 6a36b662e0..1eaeb22d02 100644
--- a/usr/src/uts/common/os/cpu.c
+++ b/usr/src/uts/common/os/cpu.c
@@ -2163,15 +2163,8 @@ cpu_info_kstat_update(kstat_t *ksp, int rw)
cpu_info_template.ci_core_id.value.l = pg_plat_get_core_id(cp);
cpu_info_template.ci_curr_clock_Hz.value.ui64 =
cp->cpu_curr_clock;
- if (cp->cpu_supp_freqs == NULL) {
- char clkstr[sizeof ("18446744073709551615") + 1]; /* ui64 MAX */
- (void) snprintf(clkstr, sizeof (clkstr), "%"PRIu64,
- cpu_info_template.ci_curr_clock_Hz.value.ui64);
- kstat_named_setstr(&cpu_info_template.ci_supp_freq_Hz, clkstr);
- } else {
- kstat_named_setstr(&cpu_info_template.ci_supp_freq_Hz,
- cp->cpu_supp_freqs);
- }
+ kstat_named_setstr(&cpu_info_template.ci_supp_freq_Hz,
+ cp->cpu_supp_freqs);
#if defined(__sparcv9)
cpu_info_template.ci_device_ID.value.ui64 =
cpunodes[cp->cpu_id].device_id;
@@ -2784,6 +2777,49 @@ cpu_destroy_bound_threads(cpu_t *cp)
}
/*
+ * Update the cpu_supp_freqs of this cpu. This information is returned
+ * as part of cpu_info kstats.
+ */
+void
+cpu_set_supp_freqs(cpu_t *cp, const char *freqs)
+{
+ char clkstr[sizeof ("18446744073709551615") + 1]; /* ui64 MAX */
+ const char *lfreqs = clkstr;
+
+ /*
+ * A NULL pointer means we only support one speed.
+ */
+ if (freqs == NULL)
+ (void) snprintf(clkstr, sizeof (clkstr), "%"PRIu64,
+ cp->cpu_curr_clock);
+ else
+ lfreqs = freqs;
+
+ /*
+ * Make sure the frequency doesn't change while a snapshot is
+ * going on.
+ */
+ mutex_enter(cp->cpu_info_kstat->ks_lock);
+
+ /*
+ * Free any previously allocated string.
+ */
+ if (cp->cpu_supp_freqs != NULL)
+ kmem_free(cp->cpu_supp_freqs, strlen(cp->cpu_supp_freqs) + 1);
+
+ /*
+ * Allocate the new string and set the pointer.
+ */
+ cp->cpu_supp_freqs = kmem_alloc(strlen(lfreqs) + 1, KM_SLEEP);
+ (void) strcpy(cp->cpu_supp_freqs, lfreqs);
+
+ /*
+ * kstat is free to take a snapshot once again.
+ */
+ mutex_exit(cp->cpu_info_kstat->ks_lock);
+}
+
+/*
* processor_info(2) and p_online(2) status support functions
* The constants returned by the cpu_get_state() and cpu_get_state_str() are
* for use in communicating processor state information to userland. Kernel
diff --git a/usr/src/uts/common/sys/cpudrv.h b/usr/src/uts/common/sys/cpudrv.h
index 2d60254a14..2a7e4843c3 100644
--- a/usr/src/uts/common/sys/cpudrv.h
+++ b/usr/src/uts/common/sys/cpudrv.h
@@ -90,6 +90,7 @@ typedef struct cpudrv_pm {
#if defined(__x86)
kthread_t *pm_throttle_thread; /* throttling thread */
#endif
+ boolean_t pm_started; /* PM really started */
} cpudrv_pm_t;
/*
diff --git a/usr/src/uts/common/sys/cpuvar.h b/usr/src/uts/common/sys/cpuvar.h
index ae73f769cf..21cbd94afd 100644
--- a/usr/src/uts/common/sys/cpuvar.h
+++ b/usr/src/uts/common/sys/cpuvar.h
@@ -643,6 +643,10 @@ void cpu_set_state(cpu_t *); /* record/timestamp current state */
int cpu_get_state(cpu_t *); /* get current cpu state */
const char *cpu_get_state_str(cpu_t *); /* get current cpu state as string */
+
+void cpu_set_supp_freqs(cpu_t *, const char *); /* set the CPU supported */
+ /* frequencies */
+
int cpu_configure(int);
int cpu_unconfigure(int);
void cpu_destroy_bound_threads(cpu_t *cp);
diff --git a/usr/src/uts/i86pc/os/mp_startup.c b/usr/src/uts/i86pc/os/mp_startup.c
index 1c0d3104d3..17a3b9700a 100644
--- a/usr/src/uts/i86pc/os/mp_startup.c
+++ b/usr/src/uts/i86pc/os/mp_startup.c
@@ -120,6 +120,11 @@ init_cpu_info(struct cpu *cp)
*/
cp->cpu_curr_clock = cpu_freq_hz;
+ /*
+ * Supported frequencies.
+ */
+ cpu_set_supp_freqs(cp, NULL);
+
(void) strcpy(pi->pi_processor_type, "i386");
if (fpu_exists)
(void) strcpy(pi->pi_fputypes, "i387 compatible");
diff --git a/usr/src/uts/sun4u/os/mach_mp_startup.c b/usr/src/uts/sun4u/os/mach_mp_startup.c
index afb023c7c5..b2a0762dc8 100644
--- a/usr/src/uts/sun4u/os/mach_mp_startup.c
+++ b/usr/src/uts/sun4u/os/mach_mp_startup.c
@@ -59,6 +59,11 @@ init_cpu_info(struct cpu *cp)
*/
cp->cpu_curr_clock = cpunode->clock_freq;
+ /*
+ * Supported frequencies.
+ */
+ cpu_set_supp_freqs(cp, NULL);
+
(void) strcpy(pi->pi_processor_type, "sparcv9");
(void) strcpy(pi->pi_fputypes, "sparcv9");
diff --git a/usr/src/uts/sun4v/os/mach_mp_startup.c b/usr/src/uts/sun4v/os/mach_mp_startup.c
index 18d4090684..4426624cf9 100644
--- a/usr/src/uts/sun4v/os/mach_mp_startup.c
+++ b/usr/src/uts/sun4v/os/mach_mp_startup.c
@@ -65,6 +65,11 @@ init_cpu_info(struct cpu *cp)
*/
cp->cpu_curr_clock = cpunode->clock_freq;
+ /*
+ * Supported frequencies.
+ */
+ cpu_set_supp_freqs(cp, NULL);
+
(void) strcpy(pi->pi_processor_type, "sparcv9");
(void) strcpy(pi->pi_fputypes, "sparcv9");