Почему MSR статуса p-состояния на ryzen не меняется?

Я пытаюсь определить текущее p-состояние моего процессора. Я заметил, что MSR состояния p-состояния (C001_0063) всегда возвращает 2 в моей системе ryzen 1700x, даже если ядро ​​явно не в этом состоянии. Я думаю, что раньше он работал с исходной BIOS (v0403), с которой шла моя материнская плата, но она больше не доступна для загрузки 1.

Мой процессор разогнан на 2 до 3,8 ГГц. Я использовал cpufreq-set, чтобы зафиксировать скорость, и cpufreq-info, чтобы проверить:

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).

Ниже приводится небольшая тестовая программа, которая показывает значение регистра для ядра № 0, а также эффективную скорость относительно состояния P0. Требуются привилегии root. По мне, под нагрузкой постоянно печатает pstate: 2, speed: 99%.

#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);
    }
}

Похожий подход работал с моим FX-8350. Что я делаю неправильно? Результаты тестов тоже приветствуются.

Системная информация:

  • ЦП: Ryzen 1700x, P0 и P1 - 3,8 ГГц 3, P2 - 2,2 ГГц
  • Материнская плата: Asus Prime X370-A, bios 3401
  • Операционная система: debian 7.1, ядро ​​4.9.0

Обновление: я изменил код для печати запрошенного pstate, и этот регистр изменяется, как ожидалось. Фактическая скорость процессора тоже меняется, что подтверждается различными тестами.


1 По какой-то непонятной причине функция резервного копирования BIOS отключена, поэтому я не смог сделать копию перед обновлением.

2 Я проведу тест по умолчанию, когда у меня будет возможность.

3 Понятия не имею, почему это дублируется.


person Jester    schedule 20.12.2017    source источник


Ответы (1)


Возможно, это не связано, однако я слышал, что некоторые люди успешно заменили свои Ryzen 7 на AMD из-за состояний p, вызывающих проблемы со стабильностью системы в Unix или Unix-подобных системах. Хотя из комментариев по этому поводу, особенно из Форум ASrock указывает на проблему с драйвером / прошивкой, я читал в другом месте, что AMD может взять на себя некоторую ответственность за первые партии чипов. Тем не менее, из того, что я знаю о состояниях P и C, некоторые состояния запрашиваются операционной системой или средой вертулизации хоста. Значит патч можно было сделать изнутри?

person piman007    schedule 17.10.2019