Why does the MSR p-status on ryzen not change?

I am trying to detect the current p-state of my processor. I noticed that the p-state status of MSR (C001_0063) always returns 2 to my 1700x ryzen system, even if the kernel is clearly not in that state. I think it worked with the initial bios (v0403), which came with my motherboard, but which is no longer available for download 1 .

My processor is overclocked from 2 to 3.8 GHz. I used cpufreq-set to fix the speed and cpufreq-info to check:

 analyzing CPU 0: driver: acpi-cpufreq CPUs which run at the same hardware frequency: 0 CPUs which need to have their frequency coordinated by software: 0 maximum transition latency: 4294.55 ms. hardware limits: 2.20 GHz - 3.80 GHz available frequency steps: 3.80 GHz, 2.20 GHz available cpufreq governors: ondemand, conservative, performance, schedutil current policy: frequency should be within 3.80 GHz and 3.80 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency is 3.80 GHz (asserted by call to hardware). 

Below is a small test program that shows the value of the register for core # 0 along with the effective speed relative to state P0. Requires root privileges. For me, it constantly prints pstate: 2, speed: 99% under load.

 #include <stdio.h> #include <stdint.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char** argv) { uint64_t aperf_old = 0; uint64_t mperf_old = 0; int fd; fd = open("/dev/cpu/0/msr", O_RDONLY); uint64_t pstate_limits; pread(fd, &pstate_limits, sizeof(pstate_limits), 0xC0010061); printf("pstate ranges: %d to %d\n", (int)(pstate_limits & 0x07), (int)((pstate_limits >> 4) & 0x07)); for(;;) { uint64_t pstate; uint64_t pstate_req; uint64_t aperf; uint64_t mperf; pread(fd, &pstate_req, sizeof(pstate_req), 0xC0010062); pread(fd, &pstate, sizeof(pstate), 0xC0010063); pread(fd, &aperf, sizeof(aperf), 0x000000E8); pread(fd, &mperf, sizeof(mperf), 0x000000E7); printf("pstate: %d, requested: %d", (int)(pstate & 0x07), (int)(pstate_req & 0x07)); if (mperf_old != 0 && mperf_old != mperf) { printf(", speed: %d%%", (int)(100 * (aperf - aperf_old) / (mperf - mperf_old))); } putchar('\n'); mperf_old = mperf; aperf_old = aperf; sleep(1); } } 

A similar approach is used to work with my FX-8350. What am I doing wrong? Test results are also welcome.

System Information:

  • CPU: Ryzen 1700x, P0 and P1 - 3.8 GHz 3 P2 - 2.2 GHz
  • Motherboard: Asus Prime X370-A, bios 3401
  • Operating System: debian 7.1, kernel 4.9.0

Update: I changed the code to print the requested pstate, and this case changes as expected. The actual processor speed also changes, which is confirmed by various criteria.


1 For some unclear reason, the bios backup function is disabled, so I could not make a copy before upgrading.

2 I run the test by default when I get a chance.

3 I do not know why it is duplicated.

+10
linux cpu hardware amd-processor power-saving
source share
1 answer

This may not be related, however, I heard that some people have successfully replaced their Ryzen 7s with AMD due to p states causing system stability problems on Unix or Unix-like systems. Although the comments on this issue, especially from the ASrock forum , indicate a problem with drivers / firmware, I read elsewhere that AMD may take some responsibility for early batches of chips. However, from what I know about P and C states, some states are requested by the operating system or host virtualization environment. So what patch can be done from the inside out?

0
source share

All Articles