Які події ядра 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 та сторінки Брендана Грегга я отримую це:

  • Tracepointsє найяснішими - це макроси на джерелі ядра, які роблять точку зондування для моніторингу, вони були представлені з ftraceпроектом і зараз їх використовують усі
  • Software є лічильниками низького рівня ядра та деякими внутрішніми структурами даних (отже, вони відрізняються від точок сліду)
  • Hardware eventце деякі дуже базові події процесора, які можна знайти у всіх архітектурах і доступними ядром
  • Hardware cache eventце прізвиська Raw hardware event descriptor- працює так

    як я зрозумів, Raw hardware event descriptorце більше (мікро?) архітектурних подій, ніж Hardware eventподії походять від модуля контролю процесора (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 в перф. wiki );

    але тоді, коли люди знають, що на даному процесорі є якась корисна подія, вони дають йому прізвисько і підключають його до Linux, як Hardware cache eventдля зручності доступу

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

  • тепер, the Hardware breakpoint

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

    це апаратне забезпечення, яке, мабуть, є загальним для більшості сучасних архітектур, і працює як точка перелому у налагоджувачі? (напевно, це все-таки може бути googlable)

  • нарешті, Kernel PMU eventмені не вдається перейти в Google;

    він також не відображається в переліку подій на парфюмерній сторінці Брендана , тож він новий?

    Можливо, це лише прізвиська до апаратних подій, зокрема від PMU? (Для зручності доступу він отримав окремий розділ у списку подій, крім псевдоніма.) Насправді, можливо, Hardware cache eventsце прізвиська до апаратних подій з кешу CPU і 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 ]

Відповіді:


11

Гугл і ack-інг закінчено! У мене є відповідь.

Але спочатку дозвольте мені ще трохи уточнити мету питання: я хочу чітко розмежувати незалежні процеси в системі та їх лічильники ефективності. Наприклад, ядро ​​процесора, некомерційний пристрій (про це дізналися недавно), ядро ​​або користувацька програма на процесорі, шина (= контролер шини), жорсткий диск - це все незалежні процеси, вони не синхронізуються годинником . І сьогодні, ймовірно, всі вони мають лічильник моніторингу процесів (PMC). Я хотів би зрозуміти, з яких процесів надходять лічильники. (Це також корисно в гуглінгу: "постачальник" речі нуліть це краще.)

Крім того , передача використовується для пошуку: 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це пристрої, які ставлять на штамп, близькі до процесора за швидкістю та низькою затримкою (справжня причина є "тому що виробник може це зробити"); як я зрозумів, це в основному Northbridge, як на материнській платі ПК, плюс кеші; 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 ТОВ і 2 ubox;

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

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

  • більше ви можете знайти в Інструкції Intel «IA-32 Software Developer Guide» Vol 3B »глави 18« МОНИТОРИНГ РОБОТИ »;

    також формат MSR конкретно для цих uncoreПМК для версії "Архітектурний моніторинг продуктивності версії 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 слова config означає, що решта містить [raw CPU або подія ядра]

    подія ядра, визначена з 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це приголомшливо);

    у вихідному коді ядра можна побачити такі операції, як "реєструвати всі ПМУ struct pmu, які є в системі," та типи структури , які передаються на щось подібне int perf_pmu_register(struct pmu *pmu, const char *name, int type)- таким чином, можна було б просто назвати цю систему "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. Я не знаю, як це робиться (автоматично ядром усі виявлені ПМС в системі, або просто щось жорстко закодоване, і якщо я додам 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, Vol 3B. І "Огляд огляду моніторингу виконання 18.1" описує їх як:

Другий клас можливостей моніторингу продуктивності називають архітектурним моніторингом ефективності. Цей клас підтримує ті ж самі підрахунки подій для відбору проб на основі переривань, з меншим набором доступних подій. Видима поведінка подій архітектурної продуктивності узгоджується у всіх процесорах. Наявність можливостей контролю архітектури продуктивності перераховується за допомогою CPUID.0AH. Ці події обговорюються у розділі 18.2.

- інший тип:

Починаючи з процесорів Intel Core Solo та Intel Core Duo, є два класи можливостей моніторингу продуктивності. Перший клас підтримує події для моніторингу продуктивності з використанням підрахунку або використання вибірок на основі переривань. Ці події є не архітектурними і відрізняються від однієї моделі процесора до іншої ...

І ці події справді є лише посиланнями на основні "сирі" апаратні події, до яких можна отримати доступ за допомогою perfутиліти як 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це для hex. Усі 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));
$

В memcpys зроблені в __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керується запитом кількох подій разом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.