diff options
| author | Bill Holler <Bill.Holler@Sun.COM> | 2009-09-02 15:36:26 -0700 |
|---|---|---|
| committer | Bill Holler <Bill.Holler@Sun.COM> | 2009-09-02 15:36:26 -0700 |
| commit | 56b56c0dc63eac41299ada6dcb890406f9063b1c (patch) | |
| tree | 6255ebe02c44bc3516d3d03c54e55f86e397fc76 /usr/src | |
| parent | 4fd5d0674a83e10428a10ee35d37170e08cda101 (diff) | |
| download | illumos-joyent-56b56c0dc63eac41299ada6dcb890406f9063b1c.tar.gz | |
6872740 deeper c-state residency greatly hampered by legacy code on some platforms
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/uts/i86pc/os/cpupm/cpu_acpi.c | 1 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/os/cpupm/cpu_idle.c | 85 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/sys/cpu_acpi.h | 2 |
3 files changed, 21 insertions, 67 deletions
diff --git a/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c b/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c index 4a9a9e9dd7..381973d7cc 100644 --- a/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c +++ b/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c @@ -734,7 +734,6 @@ cpu_acpi_cache_cst(cpu_acpi_handle_t handle) CPU_ACPI_CSTATES_COUNT(handle) = (uint32_t)cnt; alloc_size = CPU_ACPI_CSTATES_SIZE(cnt); CPU_ACPI_CSTATES(handle) = kmem_zalloc(alloc_size, KM_SLEEP); - CPU_ACPI_BM_INFO(handle) = 0; cstate = (cpu_acpi_cstate_t *)CPU_ACPI_CSTATES(handle); p = cstate; diff --git a/usr/src/uts/i86pc/os/cpupm/cpu_idle.c b/usr/src/uts/i86pc/os/cpupm/cpu_idle.c index 81a0904b01..524f0c8c6f 100644 --- a/usr/src/uts/i86pc/os/cpupm/cpu_idle.c +++ b/usr/src/uts/i86pc/os/cpupm/cpu_idle.c @@ -543,22 +543,6 @@ acpi_cpu_cstate(cpu_acpi_cstate_t *cstate) } /* - * indicate when bus masters are active - */ -static uint32_t -cpu_acpi_bm_sts(void) -{ - uint32_t bm_sts = 0; - - cpu_acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_sts); - - if (bm_sts) - cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); - - return (bm_sts); -} - -/* * Idle the present CPU, deep c-state is supported */ void @@ -593,32 +577,8 @@ cpu_acpi_idle(void) cs_indx = cpupm_next_cstate(cs_data, cstates, cpu_max_cstates, start); - /* - * OSPM uses the BM_STS bit to determine the power state to enter - * when considering a transition to or from the C2/C3 power state. - * if C3 is determined, bus master activity demotes the power state - * to C2. - */ - if ((cstates[cs_indx].cs_type >= CPU_ACPI_C3) && cpu_acpi_bm_sts()) - --cs_indx; cs_type = cstates[cs_indx].cs_type; - /* - * BM_RLD determines if the Cx power state was exited as a result of - * bus master requests. Set this bit when using a C3 power state, and - * clear it when using a C1 or C2 power state. - */ - if ((CPU_ACPI_BM_INFO(handle) & BM_RLD) && (cs_type < CPU_ACPI_C3)) { - cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); - CPU_ACPI_BM_INFO(handle) &= ~BM_RLD; - } - - if ((!(CPU_ACPI_BM_INFO(handle) & BM_RLD)) && - (cs_type >= CPU_ACPI_C3)) { - cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); - CPU_ACPI_BM_INFO(handle) |= BM_RLD; - } - switch (cs_type) { default: /* FALLTHROUGH */ @@ -632,24 +592,16 @@ cpu_acpi_idle(void) case CPU_ACPI_C3: /* - * recommended in ACPI spec, providing hardware mechanisms - * to prevent master from writing to memory (UP-only) - */ - if ((ncpus_online == 1) && - (CPU_ACPI_BM_INFO(handle) & BM_CTL)) { - cpu_acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); - CPU_ACPI_BM_INFO(handle) |= BM_ARB_DIS; - /* - * Today all Intel's processor support C3 share cache. + * All supported Intel processors maintain cache coherency + * during C3. Currently when entering C3 processors flush + * core caches to higher level shared cache. The shared cache + * maintains state and supports probes during C3. + * Consequently there is no need to handle cache coherency + * and Bus Master activity here with the cache flush, BM_RLD + * bit, BM_STS bit, nor PM2_CNT.ARB_DIS mechanisms described + * in section 8.1.4 of the ACPI Specification 4.0. */ - } else if (x86_vendor != X86_VENDOR_Intel) { - __acpi_wbinvd(); - } acpi_cpu_cstate(&cstates[cs_indx]); - if (CPU_ACPI_BM_INFO(handle) & BM_ARB_DIS) { - cpu_acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); - CPU_ACPI_BM_INFO(handle) &= ~BM_ARB_DIS; - } break; } @@ -699,7 +651,6 @@ cpu_idle_init(cpu_t *cp) cpu_acpi_cstate_t *cstate; char name[KSTAT_STRLEN]; int cpu_max_cstates, i; - ACPI_TABLE_FADT *gbl_FADT; int ret; /* @@ -715,13 +666,6 @@ cpu_idle_init(cpu_t *cp) return (-1); } - /* - * Check the bus master arbitration control ability. - */ - acpica_get_global_FADT(&gbl_FADT); - if (gbl_FADT->Pm2ControlBlock && gbl_FADT->Pm2ControlLength) - CPU_ACPI_BM_INFO(handle) |= BM_CTL; - cstate = (cpu_acpi_cstate_t *)CPU_ACPI_CSTATES(handle); cpu_max_cstates = cpu_acpi_get_max_cstates(handle); @@ -754,6 +698,8 @@ cpu_idle_init(cpu_t *cp) cpupm_alloc_ms_cstate(cp); if (cpu_deep_cstates_supported()) { + uint32_t value; + mutex_enter(&cpu_idle_callb_mutex); if (cpu_deep_idle_callb_id == (callb_id_t)0) cpu_deep_idle_callb_id = callb_add(&cpu_deep_idle_callb, @@ -762,6 +708,17 @@ cpu_idle_init(cpu_t *cp) cpu_idle_cpr_callb_id = callb_add(&cpu_idle_cpr_callb, (void *)NULL, CB_CL_CPR_PM, "cpu_idle_cpr"); mutex_exit(&cpu_idle_callb_mutex); + + + /* + * All supported CPUs (Nehalem and later) will remain in C3 + * during Bus Master activity. + * All CPUs set ACPI_BITREG_BUS_MASTER_RLD to 0 here if it + * is not already 0 before enabling Deeper C-states. + */ + cpu_acpi_get_register(ACPI_BITREG_BUS_MASTER_RLD, &value); + if (value & 1) + cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); } return (0); diff --git a/usr/src/uts/i86pc/sys/cpu_acpi.h b/usr/src/uts/i86pc/sys/cpu_acpi.h index 6a5de8edf6..c558b9d9a8 100644 --- a/usr/src/uts/i86pc/sys/cpu_acpi.h +++ b/usr/src/uts/i86pc/sys/cpu_acpi.h @@ -71,7 +71,6 @@ extern "C" { * C-state realted macros */ #define CPU_ACPI_CSD(sp) sp->cs_csd -#define CPU_ACPI_BM_INFO(sp) sp->bm_info #define CPU_ACPI_CSTATES(sp) sp->cs_cstates.ss_states #define CPU_ACPI_CSTATES_COUNT(sp) sp->cs_cstates.ss_count @@ -205,7 +204,6 @@ typedef struct cpu_acpi_state { cpu_acpi_tpc_t cs_tpc; cpu_acpi_cstates_t cs_cstates; cpu_acpi_csd_t cs_csd; - uint_t bm_info; } cpu_acpi_state_t; typedef cpu_acpi_state_t *cpu_acpi_handle_t; |
