diff options
author | mh27603 <none@none> | 2007-08-16 16:52:20 -0700 |
---|---|---|
committer | mh27603 <none@none> | 2007-08-16 16:52:20 -0700 |
commit | 68afbec1fabe0d352bb5ab4ed82c44b58ec651fb (patch) | |
tree | 32317f52d74b2c7615c7cb023fc46bc7c5d40998 | |
parent | 8d483882aa3390058094b043f3d62187b5d1de03 (diff) | |
download | illumos-gate-68afbec1fabe0d352bb5ab4ed82c44b58ec651fb.tar.gz |
6587576 cpu_info kstat is returning garbage in supported_frequencies_Hz
-rw-r--r-- | usr/src/uts/common/io/cpudrv.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/os/cpu.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/sys/cpudrv.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/cpuvar.h | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mp_startup.c | 5 | ||||
-rw-r--r-- | usr/src/uts/sun4u/os/mach_mp_startup.c | 5 | ||||
-rw-r--r-- | usr/src/uts/sun4v/os/mach_mp_startup.c | 5 |
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"); |