Что такое события ядра Kernel PMU в списке perf_events?

11

В поисках того, что можно отслеживать perf_eventsв Linux, я не могу найти то Kernel PMU event, что есть? А именно, с perf version 3.13.11-ckt39теми perf listшоу событий , как:

branch-instructions OR cpu/branch-instructions/    [Kernel PMU event]

Всего есть:

Tracepoint event
Software event
Hardware event
Hardware cache event
Raw hardware event descriptor
Hardware breakpoint
Kernel PMU event

и я хотел бы понять, что они, откуда они берутся. У меня есть какое-то объяснение для всех, кроме Kernel PMU eventпункта.

Из урока perf wiki и страницы Брендана Грегга я понял, что:

  • Tracepointsсамые ясные - это макросы в исходном коде ядра, которые представляют собой пробную точку для мониторинга, они были представлены в ftraceпроекте и теперь используются всеми
  • Software счетчики уровня ядра и некоторые внутренние структуры данных (следовательно, они отличаются от точек трассировки)
  • Hardware eventнекоторые базовые события ЦП, встречающиеся на всех архитектурах и легко доступные для ядра
  • Hardware cache eventэто псевдонимы Raw hardware event descriptor- это работает следующим образом

    как я понял, Raw hardware event descriptorэто больше (микро?) специфичных для архитектуры событий, чем Hardware eventсобытия, поступающие от Processor Monitoring Unit (PMU) или других специфических функций данного процессора, поэтому они доступны только на некоторых микроархитектурах (скажем, « архитектура "означает" x86_64 ", а все остальные детали реализации -" микроархитектура "); и они доступны для инструментовки через эти странные дескрипторы

    rNNN                                               [Raw hardware event descriptor]
    cpu/t1=v1[,t2=v2,t3 ...]/modifier                  [Raw hardware event descriptor]
     (see 'man perf-list' on how to encode it)
    

    - эти дескрипторы, на какие события они указывают и так далее, можно найти в руководствах процессора ( события PMU в perf wiki );

    но затем, когда люди знают, что на данном процессоре есть какое-то полезное событие, они дают ему псевдоним и подключают его к Linux, Hardware cache eventчтобы облегчить доступ

    - поправьте меня, если я ошибаюсь (как ни странно, все Hardware cache eventо something-loadsили something-misses- очень похоже на кеш фактического процессора ..)

  • сейчас Hardware breakpoint

    mem:<addr>[:access]                                [Hardware breakpoint]
    

    аппаратная функция, которая, вероятно, является общей для большинства современных архитектур и работает как точка останова в отладчике? (вероятно, в любом случае это Google)

  • наконец, Kernel PMU eventмне не удается гуглить;

    он также не отображается в списке событий на странице Брендана , так что это новое?

    Может быть, это просто прозвища к аппаратным событиям конкретно из PMU? (Для простоты доступа в дополнение к псевдониму он получил отдельный раздел в списке событий.) На самом деле, возможно Hardware cache events, псевдонимы для аппаратных событий из кэша ЦП и Kernel PMU eventпсевдонимы для событий PMU? (Почему бы не назвать его Hardware PMU eventтогда? ..) Это может быть просто новая схема именования - псевдонимы аппаратных событий были разделены?

    И эти события относятся к таким вещам, как cpu/mem-stores/плюс, так как некоторые события версий Linux получили описания в /sys/devices/и:

    # find /sys/ -type d -name events
    /sys/devices/cpu/events
    /sys/devices/uncore_cbox_0/events
    /sys/devices/uncore_cbox_1/events
    /sys/kernel/debug/tracing/events
    

    - debug/tracingдля ftraceи трассировки, другие каталоги точно соответствуют тому, что perf listпоказано как Kernel PMU event.

Может ли кто-нибудь указать мне хорошее объяснение / документацию о том, что Kernel PMU eventsили /sys/..events/системы? Кроме того, это /sys/..events/какие-то новые попытки систематизировать аппаратные события или что-то подобное? (Тогда Kernel PMU похож на «Модуль мониторинга производительности ядра».)

PS

Для лучшего контекста используется непривилегированный прогон perf list(точки трассировки не показаны, но есть все 1374 из них) с полным списком Kernel PMU events и Hardware cache events, а другие пропущены:

$ perf list 

List of pre-defined events (to be used in -e):
 cpu-cycles OR cycles                               [Hardware event]
 instructions                                       [Hardware event]
 ...
 cpu-clock                                          [Software event]
 task-clock                                         [Software event]
 ...
 L1-dcache-load-misses                              [Hardware cache event]
 L1-dcache-store-misses                             [Hardware cache event]
 L1-dcache-prefetch-misses                          [Hardware cache event]
 L1-icache-load-misses                              [Hardware cache event]
 LLC-loads                                          [Hardware cache event]
 LLC-stores                                         [Hardware cache event]
 LLC-prefetches                                     [Hardware cache event]
 dTLB-load-misses                                   [Hardware cache event]
 dTLB-store-misses                                  [Hardware cache event]
 iTLB-loads                                         [Hardware cache event]
 iTLB-load-misses                                   [Hardware cache event]
 branch-loads                                       [Hardware cache event]
 branch-load-misses                                 [Hardware cache event]

 branch-instructions OR cpu/branch-instructions/    [Kernel PMU event]
 branch-misses OR cpu/branch-misses/                [Kernel PMU event]
 bus-cycles OR cpu/bus-cycles/                      [Kernel PMU event]
 cache-misses OR cpu/cache-misses/                  [Kernel PMU event]
 cache-references OR cpu/cache-references/          [Kernel PMU event]
 cpu-cycles OR cpu/cpu-cycles/                      [Kernel PMU event]
 instructions OR cpu/instructions/                  [Kernel PMU event]
 mem-loads OR cpu/mem-loads/                        [Kernel PMU event]
 mem-stores OR cpu/mem-stores/                      [Kernel PMU event]
 ref-cycles OR cpu/ref-cycles/                      [Kernel PMU event]
 stalled-cycles-frontend OR cpu/stalled-cycles-frontend/ [Kernel PMU event]
 uncore_cbox_0/clockticks/                          [Kernel PMU event]
 uncore_cbox_1/clockticks/                          [Kernel PMU event]

 rNNN                                               [Raw hardware event descriptor]
 cpu/t1=v1[,t2=v2,t3 ...]/modifier                  [Raw hardware event descriptor]
  (see 'man perf-list' on how to encode it)

 mem:<addr>[:access]                                [Hardware breakpoint]

 [ Tracepoints not available: Permission denied ]
xealits
источник

Ответы:

11

Поиск в Google и ackокончание! У меня есть какой-то ответ.

Но сначала позвольте мне прояснить цель вопроса немного подробнее: я хочу четко различать независимые процессы в системе и их счетчики производительности. Например, ядро ​​процессора, неосновное устройство (о котором недавно узнали), ядро ​​или пользовательское приложение на процессоре, шина (= контроллер шины), жесткий диск - все это независимые процессы, они не синхронизируются по часам , И в настоящее время, вероятно, все они имеют некоторый счетчик мониторинга процесса (PMC). Я хотел бы понять, из каких процессов происходят счетчики. (Это также полезно при поиске в Google: «продавец» вещи обнуляет это лучше.)

Кроме того , передача используется для поиска: Ubuntu 14.04, linux 3.13.0-103-generic, процессор Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz/proc/cpuinfo, он имеет 2 физических ядра и 4 виртуальных - физическая материя здесь).

Терминология, вещи, о которых идет речь

От Intel:

  • Процессор - это coreустройство (это 1 устройство / процесс) и группа uncoreустройств , coreкоторые запускают программу (часы, ALU, регистры и т. д.), uncoreустройства, установленные на кристалле, близкие к процессору по скорости и низкой задержке (настоящая причина «потому что производитель может это сделать»); как я понял, это в основном северный мост, как на материнской плате ПК, плюс кеши; и AMD фактически называет эти устройства NorthBridge instead ofuncore`;

  • ubox который появляется в моем sysfs

    $ find /sys/devices/ -type d -name events 
    /sys/devices/cpu/events
    /sys/devices/uncore_cbox_0/events
    /sys/devices/uncore_cbox_1/events
    

    - это uncoreустройство, которое управляет кэшем последнего уровня (LLC, последний перед загрузкой оперативной памяти); У меня 2 ядра, таким образом 2 LLC и 2 ubox;

  • Блок мониторинга процессора (PMU) - это отдельное устройство, которое отслеживает операции процессора и записывает их в счетчик мониторинга процессора (PMC) (подсчитывает потери в кэш-памяти, циклы процессора и т. Д.); они существуют coreи на uncoreустройствах; в coreних доступны с rdpmc(чтение PMC) инструкции; uncore, так как эти устройства зависит от фактического процессора под рукой, доступны через моделезависимые регистры (MSR) через rdmsr(естественно);

    по-видимому, рабочий процесс с ними осуществляется через пары регистров - 1 регистр устанавливает, какие события счетчик считает, 2 регистр - значение в счетчике; счетчик может быть настроен на увеличение после нескольких событий, а не только 1; + в этих счетчиках есть некоторые перехваты / технические заметки переполнения;

  • больше можно найти в главе 18 «Руководства разработчика программного обеспечения IA-32», том 3 «Мониторинг производительности»;

    также, формат MSR конкретно для этих uncorePMC для версии «Мониторинг производительности архитектуры, версия 1» (в руководстве есть версии 1-4, я не знаю, какая из них является моим процессором) описан в «Рис. 18-1. «MSR IA32_PERFEVTSELx» (на странице 18-3 у меня) и раздел «18.2.1.2 Предопределенные события производительности архитектуры» с «Таблицей 18-1. Кодировки UMask и выбора событий для предварительно определенных событий производительности архитектуры», в которой показаны события, которые появляются как Hardware eventв perf list.

Из ядра Linux:

  • в ядре есть система (абстракция / слой) для управления счетчиками производительности различного происхождения, как программными (ядро), так и аппаратными, в которых это описано linux-source-3.13.0/tools/perf/design.txt; событие в этой системе определяется как struct perf_event_attr(файл linux-source-3.13.0/include/uapi/linux/perf_event.h), основной частью которого, вероятно, является __u64 configполе - оно может содержать как определение события, связанного с процессором (64-битное слово в формате, описанном на рисунках Intel), так и событие ядра

    MSB слова конфигурации указывает, содержит ли остальное [событие необработанного ЦП или ядра]

    событие ядра, определенное с 7 битами для типа и 56 для идентификатора события, которые enum-s в коде, которые в моем случае:

    $ ak PERF_TYPE linux-source-3.13.0/include/
    ...
    linux-source-3.13.0/include/uapi/linux/perf_event.h
    29: PERF_TYPE_HARDWARE      = 0,
    30: PERF_TYPE_SOFTWARE      = 1,
    31: PERF_TYPE_TRACEPOINT    = 2,
    32: PERF_TYPE_HW_CACHE      = 3,
    33: PERF_TYPE_RAW           = 4,
    34: PERF_TYPE_BREAKPOINT    = 5,
    36: PERF_TYPE_MAX,         /* non-ABI */
    

    ( akмой псевдоним для ack-grep, который является именем для ackDebian; и ackэто здорово);

    в исходном коде ядра можно увидеть такие операции, как «зарегистрировать все PMU, обнаруженные в системе» и типы структур struct pmu, которые передаются в нечто подобное int perf_pmu_register(struct pmu *pmu, const char *name, int type)- таким образом, можно просто назвать эту систему «PMU ядра», который будет агрегировать всех PMU в системе; но это имя можно интерпретировать как систему мониторинга операций ядра, что может вводить в заблуждение;

    давайте назовем эту подсистему perf_eventsдля ясности;

  • как любая подсистема ядра, эта подсистема может быть экспортирована sysfs(что сделано для экспорта подсистем ядра для использования людьми); и что это за eventsкаталоги в моей /sys/- экспортированной (части?) perf_eventsподсистеме;

  • также утилита пользовательского пространства perf(встроенная в linux) все еще является отдельной программой и имеет свои собственные абстракции; он представляет событие, запрошенное для мониторинга пользователем как perf_evsel(файлы linux-source-3.13.0/tools/perf/util/evsel.{h,c}) - эта структура имеет поле struct perf_event_attr attr;, но также поле, подобное struct cpu_map *cpus;тому, как perfутилита назначает событие всем или отдельным ЦП.

Ответ

  1. Действительно, Hardware cache eventэто «ярлыки» для событий устройств кэширования (устройств uboxIntel uncore), которые зависят от процессора и могут быть доступны через протокол Raw hardware event descriptor. И Hardware eventболее стабильны в архитектуре, которая, как я понимаю, называет события с coreустройства. В моем ядре нет других «ярлыков» 3.13для некоторых других uncoreсобытий и счетчиков. Все остальное - Softwareи Tracepoints- это события ядра.

    Интересно , если core«S Hardware events доступны через тот же Raw hardware event descriptorпротокол. Они не могут - так как счетчик / PMU сидит core, возможно, к нему обращаются по-другому. Например, с той rdpmuинструкцией, а не с тем rdmsr, к которой осуществляется доступ uncore. Но это не так важно.

  2. Kernel PMU eventэто просто события, которые экспортируются в sysfs. Я не знаю, как это сделать (автоматически ядром все обнаруженные PMC в системе, или просто что-то жестко запрограммированное, и если я добавлю kprobe- экспортируется ли это? И т. Д.). Но главное в том, что это те же события, что Hardware eventи во всех других perf_eventсистемах.

    И я не знаю, что это за

    $ ls /sys/devices/uncore_cbox_0/events
    clockticks
    

    находятся.

Подробности на Kernel PMU event

Поиск по коду приводит к:

$ ak "Kernel PMU" linux-source-3.13.0/tools/perf/
linux-source-3.13.0/tools/perf/util/pmu.c                                                            
629:                printf("  %-50s [Kernel PMU event]\n", aliases[j]);

- что происходит в функции

void print_pmu_events(const char *event_glob, bool name_only) {
   ...
        while ((pmu = perf_pmu__scan(pmu)) != NULL)
                list_for_each_entry(alias, &pmu->aliases, list) {...}
   ... 
   /* b.t.w. list_for_each_entry is an iterator
    * apparently, it takes a block of {code} and runs over some lost
    * Ruby built in kernel!
    */
    // then there is a loop over these aliases and
    loop{ ... printf("  %-50s [Kernel PMU event]\n", aliases[j]); ... }
}

и perf_pmu__scanнаходится в том же файле:

struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) {
    ...
                pmu_read_sysfs(); // that's what it calls
}

- который также находится в том же файле:

/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void) {...}

Вот и все.

Подробности на Hardware eventиHardware cache event

По-видимому, они Hardware eventвзяты из того, что Intel называет «Предопределенные события производительности архитектуры», 18.2.1.2 в Руководстве разработчика программного обеспечения IA-32, том 3B. И «18.1 ОБЗОР МОНИТОРИНГА ЭФФЕКТИВНОСТИ» руководства описывает их как:

Второй класс возможностей мониторинга производительности называется мониторингом производительности архитектуры. Этот класс поддерживает то же использование подсчета и выборки событий на основе прерываний с меньшим набором доступных событий. Видимое поведение событий производительности архитектуры является единым для всех реализаций процессора. Доступность возможностей мониторинга производительности архитектуры перечисляется с помощью CPUID.0AH. Эти события обсуждаются в разделе 18.2.

- другой тип:

Начиная с процессоров Intel Core Solo и Intel Core Duo, существует два класса возможностей мониторинга производительности. Первый класс поддерживает события для мониторинга производительности, используя подсчет или использование выборок событий на основе прерываний. Эти события не являются архитектурными и варьируются от одной модели процессора к другой ...

И эти события действительно просто ссылки на базовые «сырые» аппаратные события, к которым можно получить доступ через perfутилиту as Raw hardware event descriptor.

Чтобы проверить это, посмотрите на linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c:

/*
 * Intel PerfMon, used on Core and later.
 */
static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
{
    [PERF_COUNT_HW_CPU_CYCLES]              = 0x003c,
    [PERF_COUNT_HW_INSTRUCTIONS]            = 0x00c0,
    [PERF_COUNT_HW_CACHE_REFERENCES]        = 0x4f2e,
    [PERF_COUNT_HW_CACHE_MISSES]            = 0x412e,
    ...
}

- и точно 0x412eнаходится в «Таблице 18-1. UMask и кодировки выбора событий для предварительно определенных событий производительности архитектуры» для «LLC Misses»:

Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
                        4 | LLC Misses | 41H   | 2EH

- Hдля гекса. Все 7 находятся в структуре, плюс [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (Именование немного отличается, адреса совпадают.)

Тогда Hardware cache events в структурах вроде (в том же файле):

static __initconst const u64 snb_hw_cache_extra_regs
                            [PERF_COUNT_HW_CACHE_MAX]
                            [PERF_COUNT_HW_CACHE_OP_MAX]
                            [PERF_COUNT_HW_CACHE_RESULT_MAX] =
{...}

- какой должен быть песчаный мост?

Один из них - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]заполнен SNB_DMND_WRITE|SNB_L3_ACCESS, где из определения выше:

#define SNB_L3_ACCESS           SNB_RESP_ANY
#define SNB_RESP_ANY            (1ULL << 16)                                                                            
#define SNB_DMND_WRITE          (SNB_DMND_RFO|SNB_LLC_RFO)
#define SNB_DMND_RFO            (1ULL << 1)
#define SNB_LLC_RFO             (1ULL << 8)

что должно быть равно 0x00010102, но я не знаю, как проверить это с какой-то таблицей.

И это дает представление о том, как это используется в perf_events:

$ ak hw_cache_extra_regs linux-source-3.13.0/arch/x86/kernel/cpu/
linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.c
50:u64 __read_mostly hw_cache_extra_regs
292:    attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];

linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.h
521:extern u64 __read_mostly hw_cache_extra_regs

linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c
272:static __initconst const u64 snb_hw_cache_extra_regs
567:static __initconst const u64 nehalem_hw_cache_extra_regs
915:static __initconst const u64 slm_hw_cache_extra_regs
2364:       memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2365:              sizeof(hw_cache_extra_regs));
2407:       memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
2408:              sizeof(hw_cache_extra_regs));
2424:       memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2425:              sizeof(hw_cache_extra_regs));
2452:       memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2453:              sizeof(hw_cache_extra_regs));
2483:       memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2484:              sizeof(hw_cache_extra_regs));
2516:       memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
$

С memcpyсделано в __init int intel_pmu_init(void) {... case:...}.

Только attr->config1немного странно. Но это там, в perf_event_attr(тот же linux-source-3.13.0/include/uapi/linux/perf_event.hфайл):

...
    union {
            __u64           bp_addr;
            __u64           config1; /* extension of config */                                                      
    };
    union {
            __u64           bp_len;
            __u64           config2; /* extension of config1 */
    };
...

Они зарегистрированы в perf_eventsсистеме ядра с вызовами int perf_pmu_register(struct pmu *pmu, const char *name, int type)(определены в linux-source-3.13.0/kernel/events/core.c:):

  • static int __init init_hw_perf_events(void)(файл arch/x86/kernel/cpu/perf_event.c) с вызовомperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

  • static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)(файл arch/x86/kernel/cpu/perf_event_intel_uncore.cтоже есть arch/x86/kernel/cpu/perf_event_amd_uncore.c) с вызовомret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

Итак, наконец, все события происходят от оборудования, и все в порядке. Но здесь можно было заметить: почему у нас LLC-loadsв perf listи нет ubox1 LLC-loads, так как они являются HW события , и они actualy приходят из uboxэс?

Это дело perfутилиты и ее perf_evselструктуры: когда вы запрашиваете событие HW у perfвас, вы определяете событие, от которого вы хотите его обработчики (по умолчанию все), и оно устанавливает perf_evselс запрошенным событием и процессорами, тогда при агрегировании суммирует счетчики от всех процессоров в perf_evsel(или делает некоторую другую статистику с ними).

Это можно увидеть в tools/perf/builtin-stat.c:

/*
 * Read out the results of a single counter:
 * aggregate counts across CPUs in system-wide mode
 */
static int read_counter_aggr(struct perf_evsel *counter)
{
    struct perf_stat *ps = counter->priv;
    u64 *count = counter->counts->aggr.values;
    int i;

    if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
                           thread_map__nr(evsel_list->threads), scale) < 0)
            return -1;

    for (i = 0; i < 3; i++)
            update_stats(&ps->res_stats[i], count[i]);

    if (verbose) {
            fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
                    perf_evsel__name(counter), count[0], count[1], count[2]);
    }

    /*
     * Save the full runtime - to allow normalization during printout:
     */
    update_shadow_stats(counter, count);

    return 0;
}

(Таким образом, для утилиты perf«единый счетчик» - это даже не единица perf_event_attr, которая является общей формой, соответствующей событиям SW и HW, это событие вашего запроса - одни и те же события могут поступать с разных устройств, и они агрегируются. .)

Также уведомление: struct perf_evselсодержит только 1 struct perf_evevent_attr, но у него также есть поле struct perf_evsel *leader;- оно вложено. Существует функция «(иерархических) групп событий» perf_events, когда вы можете отправлять несколько счетчиков вместе, чтобы их можно было сравнивать друг с другом и так далее. Не знаю , как он работает с независимыми событиями из kernel, core, ubox. Но это вложение perf_evselэто. И, скорее всего, именно так perfуправляет запросом нескольких событий вместе.

xealits
источник