Quels sont les événements du noyau PMU dans la liste perf_events?

11

À la recherche de ce que l' on peut surveiller perf_eventssous Linux, je ne trouve pas quoi Kernel PMU event? À savoir, avec perf version 3.13.11-ckt39les perf listspectacles des événements comme:

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

Globalement, il y a:

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

et j'aimerais comprendre ce qu'ils sont, d'où ils viennent. J'ai une sorte d'explication pour tout, mais l' Kernel PMU eventarticle.

Du tutoriel perf wiki et de la page de Brendan Gregg, je comprends que:

  • Tracepointssont les plus claires - ce sont des macros sur la source du noyau, qui constituent un point de sonde pour la surveillance, elles ont été introduites avec le ftraceprojet et sont maintenant utilisées par tout le monde
  • Software sont les compteurs de bas niveau du noyau et certaines structures de données internes (par conséquent, ils sont différents des points de trace)
  • Hardware eventsont des événements CPU très basiques, trouvés sur toutes les architectures et facilement accessibles par le noyau
  • Hardware cache eventsont des surnoms Raw hardware event descriptor- cela fonctionne comme suit

    comme je l'ai compris, Raw hardware event descriptorsont plus d'événements (micro?) spécifiques à l'architecture que Hardware event, les événements proviennent de Processor Monitoring Unit (PMU) ou d'autres fonctionnalités spécifiques d'un processeur donné, ils ne sont donc disponibles que sur certaines micro-architectures (disons " architecture "signifie" x86_64 "et tous les autres détails de l'implémentation sont" micro-architecture "); et ils sont accessibles pour l'instrumentation via ces étranges descripteurs

    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)
    

    - ces descripteurs, vers quels événements ils pointent et ainsi de suite, se trouvent dans les manuels du processeur ( événements PMU dans perf wiki );

    mais ensuite, quand les gens savent qu'il y a un événement utile sur un processeur donné, ils lui donnent un surnom et le connectent à linux Hardware cache eventpour faciliter l'accès

    - corrigez-moi si je me trompe (étrangement, tout Hardware cache eventest à propos something-loadsou something-misses- très semblable au cache du processeur réel ..)

  • maintenant le Hardware breakpoint

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

    est une fonctionnalité matérielle, qui est probablement commune à la plupart des architectures modernes, et fonctionne comme un point d'arrêt dans un débogueur? (c'est probablement googlable de toute façon)

  • enfin, Kernel PMU eventje n'arrive pas à faire une recherche sur google;

    il n'apparaît pas non plus dans la liste des événements de la page de perf de Brendan , alors c'est nouveau?

    Peut-être que ce sont juste des surnoms pour des événements matériels spécifiquement de PMU? (Pour faciliter l'accès, il a une section distincte dans la liste des événements en plus du surnom.) En fait, peut Hardware cache events- être que les surnoms aux événements matériels du cache du CPU et Kernel PMU eventles surnoms aux événements PMU? (Pourquoi ne pas l'appeler Hardware PMU eventalors? ..) Ce pourrait être juste un nouveau schéma de nommage - les surnoms des événements matériels ont été sectionnés?

    Et ces événements se réfèrent à des choses comme cpu/mem-stores/, plus puisque certains événements de version linux ont des descriptions dans /sys/devices/et:

    # 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/tracingest pour ftraceet tracepoints, les autres répertoires correspondent exactement à ce qui perf lists'affiche Kernel PMU event.

Quelqu'un pourrait-il m'indiquer une bonne explication / documentation de ce Kernel PMU eventsou des /sys/..events/systèmes? De plus, y a-t-il /sys/..events/un nouvel effort pour systématiser les événements matériels ou quelque chose de similaire? (Ensuite, le noyau PMU est comme "l'unité de surveillance des performances du noyau".)

PS

Pour donner un meilleur contexte, une exécution non privilégiée de perf list(les points de trace ne sont pas affichés, mais tous les 1374 sont là) avec des listes complètes de Kernel PMU events et Hardware cache events et d'autres ignorés:

$ 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
la source

Réponses:

11

Googler et ack-ing est terminé! J'ai une réponse.

Mais permettez-moi tout d'abord de clarifier un peu plus le but de la question: je veux distinguer clairement les processus indépendants du système et leurs compteurs de performance. Par exemple, un noyau d'un processeur, un périphérique non-core (appris récemment), un noyau ou une application utilisateur sur le processeur, un bus (= contrôleur de bus), un disque dur sont tous des processus indépendants, ils ne sont pas synchronisés par une horloge . Et de nos jours, tous ont probablement un compteur de surveillance de processus (PMC). J'aimerais comprendre de quels processus proviennent les compteurs. (Il est également utile pour la recherche sur Google: le "vendeur" d'une chose la met à zéro.)

En outre, le matériel utilisé pour la recherche: Ubuntu 14.04, linux 3.13.0-103-generic, processeur Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz( à partir /proc/cpuinfo, il dispose de 2 noyaux physiques et 4 virtuelles - la matière physique ici).

Terminologie, ce que la question implique

D'Intel:

  • le processeur est un coreappareil (c'est 1 appareil / processus) et un tas d' uncoreappareils , corec'est ce qui exécute le programme (horloge, ALU, registres, etc.), uncoresont des appareils mis sous tension, proches du processeur pour la vitesse et une faible latence (la vraie raison est "parce que le fabricant peut le faire"); si j'ai bien compris, c'est essentiellement le Northbridge, comme sur la carte mère du PC, plus les caches; et AMD appelle en fait ces appareils NorthBridge instead ofuncore`;

  • ubox qui apparaît dans mon sysfs

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

    - est un uncoreappareil qui gère Last Level Cache (LLC, le dernier avant de toucher la RAM); J'ai 2 cœurs, donc 2 LLC et 2 ubox;

  • L'unité de surveillance du processeur (PMU) est un appareil séparé qui surveille les opérations d'un processeur et les enregistre dans le compteur de surveillance du processeur (PMC) (compte les échecs de cache, les cycles du processeur, etc.); ils existent sur coreet les uncoreappareils; les corecelles sont accessibles avec rdpmc(lecture PMC) instruction; les uncore, puisque ces dispositifs dépendent du processeur réel à portée de main, sont accessibles via des registres spécifiques au modèle (MSR) via rdmsr(naturellement);

    apparemment, le flux de travail avec eux se fait via des paires de registres - 1 jeux de registres qui événements le compteur compte, 2 registre est la valeur dans le compteur; le compteur peut être configuré pour incrémenter après un tas d'événements, pas seulement 1; + il y a des interruptions / technologies remarquant des débordements dans ces compteurs;

  • on en trouvera plus dans le chapitre 18 du manuel "IA-32 Software Developer's Manual Vol 3B" "SURVEILLANCE DES PERFORMANCES";

    aussi, le format du MSR concrètement pour ces uncorePMC pour la version "Architectural Performance Monitoring Version 1" (il y a les versions 1-4 dans le manuel, je ne sais pas laquelle est mon processeur) est décrit dans "Figure 18-1. Disposition de IA32_PERFEVTSELx MSR "(page 18-3 dans la mienne), et la section" 18.2.1.2 Événements de performances architecturales prédéfinies "avec" Tableau 18-1. Codages UMask et Event Select pour les événements de performances architecturales prédéfinis ", qui montre la les événements qui apparaissent comme Hardware eventdans perf list.

Depuis le noyau Linux:

  • le noyau a un système (abstraction / couche) pour gérer les compteurs de performance d'origine différente, à la fois logiciel (noyau) et matériel, il est décrit dans linux-source-3.13.0/tools/perf/design.txt; un événement dans ce système est défini comme struct perf_event_attr(fichier linux-source-3.13.0/include/uapi/linux/perf_event.h), dont la partie principale est probablement un __u64 configchamp - il peut contenir à la fois une définition d'événement spécifique au processeur (le mot 64 bits au format décrit sur les figures d'Intel) ou un événement du noyau

    Le MSB du mot de configuration signifie si le reste contient [l'événement CPU ou noyau brut]

    l'événement du noyau défini avec 7 bits pour le type et 56 pour l'identifiant de l'événement, qui sont enum-s dans le code, qui dans mon cas sont:

    $ 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 */
    

    ( akest mon alias ack-grep, qui est le nom de acksur Debian; et ackest génial);

    dans le code source du noyau, on peut voir des opérations comme "enregistrer tous les PMU découverts sur le système" et les types de structure struct pmu, qui sont passés à quelque chose comme int perf_pmu_register(struct pmu *pmu, const char *name, int type)- ainsi, on pourrait simplement appeler ce système "PMU du noyau", qui serait une agrégation de toutes les UGP du système; mais ce nom pourrait être interprété comme un système de surveillance des opérations du noyau, ce qui serait trompeur;

    appelons ce sous-système perf_eventspour plus de clarté;

  • comme tout sous-système de noyau, ce sous-système peut être exporté vers sysfs(qui est conçu pour exporter des sous-systèmes de noyau pour que les gens les utilisent); et c'est ce que sont ces eventsrépertoires dans mon /sys/- le sous-système exporté (parties de?) perf_events;

  • en outre, l'utilitaire d'espace utilisateur perf(intégré à Linux) est toujours un programme distinct et possède ses propres abstractions; il représente un événement demandé pour la surveillance par l'utilisateur en tant que perf_evsel(fichiers linux-source-3.13.0/tools/perf/util/evsel.{h,c}) - cette structure a un champ struct perf_event_attr attr;, mais aussi un champ comme struct cpu_map *cpus;c'est ainsi que l' perfutilitaire attribue un événement à tous les CPU ou à certains CPU.

Réponse

  1. En effet, Hardware cache eventsont des "raccourcis" vers les événements des périphériques de cache ( uboxdes périphériques d'Intel uncore), qui sont spécifiques au processeur, et sont accessibles via le protocole Raw hardware event descriptor. Et Hardware eventsont plus stables au sein de l'architecture, qui, si je comprends bien, nomme les événements de l' coreappareil. Il n'y a pas d'autres "raccourcis" dans mon noyau 3.13vers d'autres uncoreévénements et compteurs. Tous les autres - Softwareet Tracepoints- sont des événements du noyau.

    Je me demande si le corede » Hardware eventde s sont accessibles via le même Raw hardware event descriptorprotocole. Ils pourraient ne pas - puisque le compteur / PMU est assis core, il est peut-être accessible différemment. Par exemple, avec cette rdpmuinstruction, au lieu de rdmsr, qui accède uncore. Mais ce n'est pas si important.

  2. Kernel PMU eventne sont que les événements, qui sont exportés dans sysfs. Je ne sais pas comment cela se fait (automatiquement par le noyau tous les PMC découverts sur le système, ou simplement quelque chose de codé en dur, et si j'ajoute un kprobe- est-il exporté? Etc.). Mais l'essentiel est qu'il s'agit des mêmes événements que Hardware eventtout autre événement du perf_eventsystème interne .

    Et je ne sais pas ce que ces

    $ ls /sys/devices/uncore_cbox_0/events
    clockticks
    

    sont.

Détails sur Kernel PMU event

La recherche dans le code conduit à:

$ 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]);

- ce qui se passe dans la fonction

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]); ... }
}

et se perf_pmu__scantrouve dans le même fichier:

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

- qui se trouve également dans le même fichier:

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

C'est ça.

Détails sur Hardware eventetHardware cache event

Apparemment, cela Hardware eventvient de ce qu'Intel appelle "Evénements de performances architecturales prédéfinies", 18.2.1.2 dans le Manuel du développeur du logiciel IA-32 Vol 3B. Et "18.1 APERÇU DE LA SURVEILLANCE DES PERFORMANCES" du manuel les décrit comme:

La deuxième classe de capacités de surveillance des performances est appelée surveillance des performances architecturales. Cette classe prend en charge les mêmes utilisations d'échantillonnage d'événements de comptage et d'interruption, avec un plus petit ensemble d'événements disponibles. Le comportement visible des événements de performances architecturales est cohérent dans toutes les implémentations de processeur. La disponibilité des capacités de surveillance des performances architecturales est énumérée à l'aide du CPUID.0AH. Ces événements sont traités dans la section 18.2.

- l'autre type est:

À partir des processeurs Intel Core Solo et Intel Core Duo, il existe deux classes de capacités de surveillance des performances. La première classe prend en charge les événements pour surveiller les performances en utilisant le comptage ou l'utilisation d'échantillonnage d'événements basé sur les interruptions. Ces événements sont non architecturaux et varient d'un modèle de processeur à l'autre ...

Et ces événements ne sont en effet que des liens vers des événements matériels "bruts" sous-jacents, accessibles via l' perfutilitaire as Raw hardware event descriptor.

Pour vérifier celui-ci regarde 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,
    ...
}

- et 0x412ese trouve exactement dans le "Tableau 18-1. Codages UMask et Event Select pour les événements de performances architecturales prédéfinis" pour "LLC Misses":

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

- Hest pour hex. Tous les 7 sont dans la structure, plus [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (Le nom est un peu différent, les adresses sont les mêmes.)

Ensuite, les Hardware cache events sont dans des structures comme (dans le même fichier):

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] =
{...}

- lequel devrait être pour le pont de sable?

L'un d'eux - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]est rempli SNB_DMND_WRITE|SNB_L3_ACCESS, d'où les def-s ci-dessus:

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

qui devrait être égal à 0x00010102, mais je ne sais pas comment le vérifier avec une table.

Et cela donne une idée de la façon dont il est utilisé dans 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));
$

Les memcpys sont terminés __init int intel_pmu_init(void) {... case:...}.

C'est attr->config1un peu bizarre. Mais il est là, dans perf_event_attr(même linux-source-3.13.0/include/uapi/linux/perf_event.hfichier):

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

Ils sont enregistrés dans le perf_eventssystème du noyau avec des appels à int perf_pmu_register(struct pmu *pmu, const char *name, int type)(définis dans linux-source-3.13.0/kernel/events/core.c:):

  • static int __init init_hw_perf_events(void)(fichier arch/x86/kernel/cpu/perf_event.c) avec appelperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

  • static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)(fichier arch/x86/kernel/cpu/perf_event_intel_uncore.c, il y en a aussi arch/x86/kernel/cpu/perf_event_amd_uncore.c) avec appelret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

Donc, finalement, tous les événements proviennent du matériel et tout va bien. Mais ici, on pourrait remarquer: pourquoi avons-nous LLC-loadsen perf listet non ubox1 LLC-loads, car ce sont des événements HW et ils viennent réellement d' uboxes?

C'est une chose de l' perfutilité et de sa perf_evselstructure: lorsque vous demandez un événement HW à perfvous, définissez l'événement à partir de quels processeurs vous le souhaitez (par défaut c'est tout), et il configure perf_evselavec l'événement et les processeurs demandés, puis lors de l'agrégation est additionne les compteurs de tous les processeurs perf_evsel(ou fait d'autres statistiques avec eux).

On peut le voir dans 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;
}

(Donc, pour l'utilitaire, perfun "compteur unique" n'est même pas un perf_event_attr, qui est une forme générale, s'adaptant aux événements SW et HW, c'est un événement de votre requête - les mêmes événements peuvent provenir de différents appareils et ils sont agrégés .)

Également un avis: struct perf_evselcontient seulement 1 struct perf_evevent_attr, mais il a également un champ struct perf_evsel *leader;- il est imbriqué. Il existe une fonctionnalité de "groupes d'événements (hiérarchiques)" dans perf_events, lorsque vous pouvez répartir un groupe de compteurs ensemble, afin qu'ils puissent être comparés entre eux et ainsi de suite. Je ne sais pas comment cela fonctionne avec des événements indépendants de kernel, core, ubox. Mais cette imbrication l' perf_evselest. Et, très probablement, c'est ainsi que perfgère une requête de plusieurs événements ensemble.

xealits
la source