def mwait_callback(use_mwait, name="", hint=0): for cpu in bits.cpus(): bits.set_mwait(cpu, use_mwait, hint, int_break_event) with ttypager.page(): if use_mwait: print("MWAIT enabled: {}".format(name)) else: print("MWAIT disabled")
def test_hardware_pstates(ratio_to_control_value): old_mwait = {} try: MSR_PLATFORM_INFO = 0xce IA32_PERF_CTL = 0x199 min_ratio = testmsr.MSR("maximum efficiency ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=47, lowbit=40)[0] max_ratio = testmsr.MSR("max non-turbo ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=15, lowbit=8)[0] # Get the Turbo Mode Availability flag turbo_mode_available = bits.cpuid(bits.bsp_apicid(),0).eax >= 6 and (bits.cpuid(bits.bsp_apicid(),6).eax & 0x2) last_ratio = max_ratio if turbo_mode_available: last_ratio += 1 duration = last_ratio - min_ratio + 1 if turbo_mode_available: duration += 2 print "Test duration is ~{} seconds...".format(duration) # Force use of MWAIT C3 hint = 0x20 cpus = bits.cpus() for apicid in cpus: old_mwait[apicid] = bits.get_mwait(apicid) bits.set_mwait(apicid, True, hint) bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 for ratio in range(min_ratio, last_ratio + 1): control_value = ratio_to_control_value(ratio, min_ratio, max_ratio) for apicid in cpus: bits.wrmsr(apicid, IA32_PERF_CTL, control_value) if ratio == max_ratio + 1: # Needs to busywait, not sleep start = time.time() while (time.time() - start < 2): pass aperf = bits.cpu_frequency()[1] aperf = testutil.adjust_to_nearest(aperf, bclk/2) aperf = int(aperf / 1000000) expected = int(ratio * bclk / 1000000) if ratio == max_ratio + 1: testsuite.test("Turbo measured frequency {} >= expected {} MHz".format(aperf, expected), aperf >= expected) else: testsuite.test("Ratio {} measured frequency {} MHz == expected {} MHz".format(ratio, aperf, expected), aperf == expected) finally: for apicid, old_mwait_values in old_mwait.iteritems(): bits.set_mwait(apicid, *old_mwait_values)
def use_hint(hint=None): """Context manager to temporarily set the mwait hint of all CPUs""" global default_hint if hint is None: hint = default_hint old_mwait = {} try: for apicid in bits.cpus(): old_mwait[apicid] = bits.get_mwait(apicid) bits.set_mwait(apicid, True, hint) yield finally: for apicid, old_mwait_values in old_mwait.iteritems(): bits.set_mwait(apicid, *old_mwait_values)
def test(residency_tests, residency_counter_msr, residency_counters): cpus = bits.cpus() for states, hint in residency_tests: for apicid in cpus: bits.set_mwait(apicid, True, hint) delta = residency(residency_counters, residency_counter_msr) detail = False for state in states: for apic_id, r in sorted(delta.iteritems()): state_residency = getattr(r, state) testsuite.test("MWAIT hint {:#x}, socket {} {} residency {:4.0%} (expected >= 85%)".format(hint, bits.socket_index(apic_id), state.upper(), state_residency), state_residency >= 0.85) detail = detail or testsuite.show_detail() if detail: print testsuite.format_detail("Full residency for MWAIT hint {:#x}:".format(hint)) print testsuite.format_detail(" SKT APIC" + "".join("{:>6s}".format(field.upper()) for field in residency_counters._fields)) for apic_id, r in sorted(delta.iteritems()): skt_index = bits.socket_index(apic_id) print testsuite.format_detail("{:4d} {:#04x} ".format(skt_index, apic_id) + " ".join("{:4.0%}".format(field) for field in r))
def cmd_set_mwait(args): if args.mwait == 'enable': if args.hint is None: set_mwait_argparser.print_usage() print '"enable" requires an MWAIT hint value' return use_mwait = True if args.mwait == 'disable': if args.hint is not None or args.no_int_break_event: set_mwait_argparser.print_usage() print '"disable" takes no arguments' return use_mwait = False args.hint = 0 for apicid in each_apicid(args.cpu): bits.set_mwait(apicid, use_mwait, args.hint, not args.no_int_break_event)
def test_pstates(): """Execute and verify frequency for each Pstate in the _PSS""" old_mwait = {} try: IA32_PERF_CTL = 0x199 # Force use of MWAIT C3 hint = 0x20 cpus = bits.cpus() for apicid in cpus: old_mwait[apicid] = bits.get_mwait(apicid) bits.set_mwait(apicid, True, hint) cpupath_procid = acpi.find_procid() cpupath_uid = acpi.find_uid() procid_apicid, uid_x2apicid = acpi.parse_apic() def cpupath_apicid(cpupath): if procid_apicid is not None: procid = cpupath_procid.get(cpupath, None) if procid is not None: apicid = procid_apicid.get(procid, None) if apicid is not None: return apicid if uid_x2apicid is not None: uid = cpupath_uid.get(cpupath, None) if uid is not None: apicid = uid_x2apicid.get(uid, None) if apicid is not None: return apicid return bits.cpus()[0] bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 uniques = acpi.parse_cpu_method("_PSS") for pss, cpupaths in uniques.iteritems(): if not testsuite.test("_PSS must exist", pss is not None): testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) testsuite.print_detail('No _PSS exists') continue print "Test duration is ~{} seconds...".format(len(pss.pstates) + 2) for n, pstate in enumerate(pss.pstates): for cpupath in cpupaths: apicid = cpupath_apicid(cpupath) if apicid is None: print 'Failed to find apicid for cpupath {}'.format(cpupath) continue bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control) # Detecting Turbo frequency requires at least 2 pstates # since turbo frequency = max non-turbo frequency + 1 turbo = False if len(pss.pstates) >= 2: turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1)) if turbo: # Needs to busywait, not sleep start = time.time() while (time.time() - start < 2): pass # Abort the test if no cpu frequency is not available if bits.cpu_frequency() is None: continue aperf = bits.cpu_frequency()[1] aperf = testutil.adjust_to_nearest(aperf, bclk/2) aperf = int(aperf / 1000000) if turbo: testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency) else: testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency) finally: for apicid, old_mwait_values in old_mwait.iteritems(): bits.set_mwait(apicid, *old_mwait_values)