From owner-svn-src-stable@freebsd.org Wed Dec 6 21:40:26 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 38D99E8CC5B; Wed, 6 Dec 2017 21:40:26 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 124016342F; Wed, 6 Dec 2017 21:40:25 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vB6LePn8028137; Wed, 6 Dec 2017 21:40:25 GMT (envelope-from jkim@FreeBSD.org) Received: (from jkim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vB6LePC1028136; Wed, 6 Dec 2017 21:40:25 GMT (envelope-from jkim@FreeBSD.org) Message-Id: <201712062140.vB6LePC1028136@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jkim set sender to jkim@FreeBSD.org using -f From: Jung-uk Kim Date: Wed, 6 Dec 2017 21:40:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r326638 - stable/10/sys/x86/cpufreq X-SVN-Group: stable-10 X-SVN-Commit-Author: jkim X-SVN-Commit-Paths: stable/10/sys/x86/cpufreq X-SVN-Commit-Revision: 326638 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Dec 2017 21:40:26 -0000 Author: jkim Date: Wed Dec 6 21:40:24 2017 New Revision: 326638 URL: https://svnweb.freebsd.org/changeset/base/326638 Log: MFC: r267961, r309361, r322710, r323286, r326378, r326383, r326407 Sync. hwpstate with head. r267961 (hselasky, partial): Remove a redundant TUNABLE statement. r309361 (danfe): - Mention mismatching numbers in MSR vs. ACPI _PSS count warning. - Rephrase unsupported AMD CPUs message and wrap as an overly long line. - Improve readability when reporting resulted P-state transition (debug). r322710, r323286 (cem): - Add support for family 17h pstate info from MSRs. - Yield CPU awaiting frequency change. r326378, r326383, r326407: - Fix some style(9) nits. - Add a tunable "debug.hwpstate_verify" to check P-state after changing it and turn it off by default. Modified: stable/10/sys/x86/cpufreq/hwpstate.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/x86/cpufreq/hwpstate.c ============================================================================== --- stable/10/sys/x86/cpufreq/hwpstate.c Wed Dec 6 21:39:01 2017 (r326637) +++ stable/10/sys/x86/cpufreq/hwpstate.c Wed Dec 6 21:40:24 2017 (r326638) @@ -83,11 +83,15 @@ __FBSDID("$FreeBSD$"); #define AMD_10H_11H_CUR_DID(msr) (((msr) >> 6) & 0x07) #define AMD_10H_11H_CUR_FID(msr) ((msr) & 0x3F) +#define AMD_17H_CUR_VID(msr) (((msr) >> 14) & 0xFF) +#define AMD_17H_CUR_DID(msr) (((msr) >> 8) & 0x3F) +#define AMD_17H_CUR_FID(msr) ((msr) & 0xFF) + #define HWPSTATE_DEBUG(dev, msg...) \ - do{ \ - if(hwpstate_verbose) \ + do { \ + if (hwpstate_verbose) \ device_printf(dev, msg); \ - }while(0) + } while (0) struct hwpstate_setting { int freq; /* CPU clock in Mhz or 100ths of a percent. */ @@ -117,11 +121,14 @@ static int hwpstate_get_info_from_acpi_perf(device_t d static int hwpstate_get_info_from_msr(device_t dev); static int hwpstate_goto_pstate(device_t dev, int pstate_id); -static int hwpstate_verbose = 0; -SYSCTL_INT(_debug, OID_AUTO, hwpstate_verbose, CTLFLAG_RW | CTLFLAG_TUN, - &hwpstate_verbose, 0, "Debug hwpstate"); -TUNABLE_INT("debug.hwpstate_verbose", &hwpstate_verbose); +static int hwpstate_verbose; +SYSCTL_INT(_debug, OID_AUTO, hwpstate_verbose, CTLFLAG_RWTUN, + &hwpstate_verbose, 0, "Debug hwpstate"); +static int hwpstate_verify; +SYSCTL_INT(_debug, OID_AUTO, hwpstate_verify, CTLFLAG_RWTUN, + &hwpstate_verify, 0, "Verify P-state after setting"); + static device_method_t hwpstate_methods[] = { /* Device interface */ DEVMETHOD(device_identify, hwpstate_identify), @@ -155,61 +162,69 @@ DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, hwpstate * Go to Px-state on all cpus considering the limit. */ static int -hwpstate_goto_pstate(device_t dev, int pstate) +hwpstate_goto_pstate(device_t dev, int id) { - int i; + sbintime_t sbt; uint64_t msr; - int j; - int limit; - int id = pstate; - int error; - + int cpu, i, j, limit; + /* get the current pstate limit */ msr = rdmsr(MSR_AMD_10H_11H_LIMIT); limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr); - if(limit > id) + if (limit > id) id = limit; + cpu = curcpu; + HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu); + /* Go To Px-state */ + wrmsr(MSR_AMD_10H_11H_CONTROL, id); + /* * We are going to the same Px-state on all cpus. * Probably should take _PSD into account. */ - error = 0; CPU_FOREACH(i) { + if (i == cpu) + continue; + /* Bind to each cpu. */ thread_lock(curthread); sched_bind(curthread, i); thread_unlock(curthread); - HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", - id, PCPU_GET(cpuid)); + HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, i); /* Go To Px-state */ wrmsr(MSR_AMD_10H_11H_CONTROL, id); } - CPU_FOREACH(i) { - /* Bind to each cpu. */ - thread_lock(curthread); - sched_bind(curthread, i); - thread_unlock(curthread); - /* wait loop (100*100 usec is enough ?) */ - for(j = 0; j < 100; j++){ - /* get the result. not assure msr=id */ - msr = rdmsr(MSR_AMD_10H_11H_STATUS); - if(msr == id){ - break; + + /* + * Verify whether each core is in the requested P-state. + */ + if (hwpstate_verify) { + CPU_FOREACH(i) { + thread_lock(curthread); + sched_bind(curthread, i); + thread_unlock(curthread); + /* wait loop (100*100 usec is enough ?) */ + for (j = 0; j < 100; j++) { + /* get the result. not assure msr=id */ + msr = rdmsr(MSR_AMD_10H_11H_STATUS); + if (msr == id) + break; + sbt = SBT_1MS / 10; + tsleep_sbt(dev, PZERO, "pstate_goto", sbt, + sbt >> tc_precexp, 0); } - DELAY(100); + HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n", + (int)msr, i); + if (msr != id) { + HWPSTATE_DEBUG(dev, + "error: loop is not enough.\n"); + return (ENXIO); + } } - HWPSTATE_DEBUG(dev, "result P%d-state on cpu%d\n", - (int)msr, PCPU_GET(cpuid)); - if (msr != id) { - HWPSTATE_DEBUG(dev, "error: loop is not enough.\n"); - error = ENXIO; - } } - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); - return (error); + + return (0); } static int @@ -243,7 +258,7 @@ hwpstate_get(device_t dev, struct cf_setting *cf) if (cf == NULL) return (EINVAL); msr = rdmsr(MSR_AMD_10H_11H_STATUS); - if(msr >= sc->cfnum) + if (msr >= sc->cfnum) return (EINVAL); set = sc->hwpstate_settings[msr]; @@ -368,7 +383,8 @@ hwpstate_probe(device_t dev) */ msr = rdmsr(MSR_AMD_10H_11H_LIMIT); if (sc->cfnum != 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr)) { - HWPSTATE_DEBUG(dev, "msr and acpi _PSS count mismatch.\n"); + HWPSTATE_DEBUG(dev, "MSR (%jd) and ACPI _PSS (%d)" + " count mismatch\n", (intmax_t)msr, sc->cfnum); error = TRUE; } } @@ -417,7 +433,7 @@ hwpstate_get_info_from_msr(device_t dev) fid = AMD_10H_11H_CUR_FID(msr); /* Convert fid/did to frequency. */ - switch(family) { + switch (family) { case 0x11: hwpstate_set[i].freq = (100 * (fid + 0x08)) >> did; break; @@ -427,8 +443,18 @@ hwpstate_get_info_from_msr(device_t dev) case 0x16: hwpstate_set[i].freq = (100 * (fid + 0x10)) >> did; break; + case 0x17: + did = AMD_17H_CUR_DID(msr); + if (did == 0) { + HWPSTATE_DEBUG(dev, "unexpected did: 0\n"); + did = 1; + } + fid = AMD_17H_CUR_FID(msr); + hwpstate_set[i].freq = (200 * fid) / did; + break; default: - HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family 0x%02x CPU's are not implemented yet. sorry.\n", family); + HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family" + " 0x%02x CPUs are not supported yet\n", family); return (ENXIO); } hwpstate_set[i].pstate_id = i;