Что делает native_write_msr в ядре? - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть сценарий python, который в начале иногда бывает медленным. Я запустил perf top на нем на днях, и все, что я мог видеть, было:

   PerfTop:       2 irqs/sec  kernel:100.0%  exact:  0.0% [4000Hz cycles],  (target_pid: 1234)
-------------------------------------------------------------------------------------------------

   100.00%  [kernel]       [k] native_write_msr

Поиск имени функции мне не сильно помог.

1 Ответ

2 голосов
/ 22 февраля 2020

native_write_msr - спецификация x86 / x86_64 c функции ядра, которая позволяет коду ядра выполнять MSR: https://elixir.bootlin.com/linux/v4.8/source/arch/x86/include/asm/msr.h#L118

static inline void native_write_msr(unsigned int msr,
                      unsigned low, unsigned high)
{
  asm volatile("1: wrmsr\n"
           "2:\n"
           : : "c" (msr), "a"(low), "d" (high) : "memory");
  if (msr_tracepoint_active(__tracepoint_write_msr))
      do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
}

Если вы хотите получить фактические индексы и значения MSR, которые вы можете попытаться активировать трассировкой msr с помощью https://www.kernel.org/doc/Documentation/trace/events-msr.txt или https://www.kernel.org/doc/html/v4.17/trace/events-msr.html инструкций.

native_write_msr является внутренней реализацией функций ядра wrmsr и wrmsl, которые имеют много возможных вызовов: https://elixir.bootlin.com/linux/v4.8/ident/wrmsr и https://elixir.bootlin.com/linux/v4.8/ident/wrmsrl и некоторые из них, как сказал Питер в комментарии, предназначены для счетчиков производительности программирования (из каталога arch/x86/events).

Для профилирования коротких сценариев не используйте инструмент perf top (он предназначен для длительных процессов и профилирования всей системы), но попробуйте perf record python3 ./your-script.py для записи профиля в perf.data файл и perf report или perf report > report.txt для декодирования perf.data файла. Это очень короткий скрипт, поэтому я изменил частоту дискретизации на более высокое значение, а также я не профилировал ядро ​​(:u суффикс)

echo 2 | sudo tee  /proc/sys/kernel/perf_event_paranoid
$ perf record -e cycles:u -F 20000 python3 -c 'print(1)' 
1
[ perf record: Woken up 1 times to write data ]

perf report покажет вам статистику, но пропустит некоторые символы показ только шестнадцатеричных адресов

$ perf report            # interactive TUI
$ perf report|head -n 20|tail
#
     9.75%  python3  python3.6          [.] _PyEval_EvalFrameDefault
     2.77%  python3  python3.6          [.] 0x000000000049b284
     1.95%  python3  libc-2.27.so       [.] __strlen_avx2
     1.86%  python3  python3.6          [.] PyObject_GetAttr
     1.80%  python3  python3.6          [.] PyDict_SetDefault
     1.61%  python3  python3.6          [.] PyUnicode_New
     1.55%  python3  libc-2.27.so       [.] _int_malloc
     1.52%  python3  python3.6          [.] _PyDict_LoadGlobal
     1.41%  python3  python3.6          [.] _PyObject_GenericSetAttrWithDict

perf script даст вам временную шкалу выполненного кода, перечисляя каждую выборку из perf record (при -F 20000 выборки берутся на частоте около 20 кГц).

...