perf_event_open(2) System Calls Manual perf_event_open(2) NOM perf_event_open - Définir la surveillance des performances BIBLIOTHÈQUE Bibliothèque C standard (libc, -lc) SYNOPSIS #include <linux/perf_event.h> /* Définition des constantes PERF_* */ #include <linux/hw_breakpoint.h> /* Définition des constantes HW_* */ #include <sys/syscall.h> /* Définition des constantes SYS_* */ #include <unistd.h> int syscall(SYS_perf_event_open, struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags); Remarque : la glibc ne fournit pas d'enveloppe pour perf_event_open(), imposant l'utilisation de syscall(2). DESCRIPTION À partir d'une liste de paramètres, perf_event_open() renvoie un des- cripteur de fichier, pour une utilisation dans les appels système sui- vants (read(2), mmap(2), prctl(2), fcntl(2), etc.). Un appel de perf_event_open() crée un descripteur de fichier qui permet de mesurer les renseignements de performance. Tous les descripteurs de fichier correspondent chacun à un événement mesuré ; ils peuvent être regroupés pour mesurer plusieurs événements simultanément. Les événements peuvent être activés et désactivés de deux façons : à l'aide de ioctl(2) ou de prctl(2). Quand un événement est désactivé, il ne décompte ni ne génère de dépassement, mais continue vraiment d'exis- ter et maintient sa valeur de décompte. Les événements sont de deux types : comptage et échantillonnage. Un événement de comptage sert à comptabiliser le nombre total d'événements qui se produisent. En général, les résultats d'un événement de comptage sont recueillis avec un appel read(2). Un événement d'échantillonnage écrit périodiquement les mesures dans un tampon qui peut ensuite être accédé à l'aide de mmap(2). Arguments Les arguments pid et cpu permettent d’indiquer le processus et le pro- cesseur à surveiller : pid == 0 et cpu == -1 Cela mesure le processus ou thread appelant sur tous les proces- seurs. pid == 0 et cpu >= 0 Cela ne mesure le processus ou thread appelant que s’il est en cours d’exécution sur le processeur indiqué. pid > 0 et cpu == -1 Cela mesure le processus ou thread indiqué sur tous les proces- seurs. pid > 0 et cpu >= 0 Cela ne mesure le processus ou thread indiqué que s’il est en cours d’exécution sur le processeur indiqué. pid == -1 et cpu >= 0 Cela mesure tous les processus et threads du processeur indiqué. Cela nécessite la capacité CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN ou une valeur /proc/sys/kernel/perf_event_paranoid strictement inférieure à 1. pid == -1 et cpu == -1 Ce réglage est incorrect et renverra une erreur. Quand pid est supérieur à zéro, le droit d'effectuer cet appel système est géré par CAP_PERFMON (depuis Linux 5.9) et une vérification PTRACE_MODE_READ_REALCREDS du mode d'accès ptrace sur les anciennes versions du noyau ; voir ptrace(2). L'argument group_fd permet aux groupes d'événements d'être créés. Un groupe d'événements a un événement qui est le leader de groupe. Le lea- der est d'abord créé avec group_fd = -1. Les autres membres du groupe sont créés par les appels perf_event_open() suivants, avec group_fd dé- fini au descripteur de fichier du leader de groupe (un événement unique créé avec group_fd = -1 est considéré comme formant un groupe d'un seul membre). Un événement de groupe est programmé dans le processeur comme un bloc : il ne sera mis dans le processeur que si tous les événements du groupe peuvent être mis dans le processeur. Cela veut dire que les valeurs des événements de tous les membres peuvent être comparées — ajoutées, divisées (pour obtenir des rapports), etc. — ensemble de manière significative, puisqu'elles ont compté les événements pendant les mêmes instructions exécutées. L'argument flags est constitué d’un OU binaire entre une ou plusieurs des valeurs suivantes. PERF_FLAG_FD_CLOEXEC (depuis Linux 3.14) Cet attribut active l’attribut « close-on-exec » pour le des- cripteur de fichier de l’événement créé, de telle sorte que le descripteur de fichier est automatiquement fermé par execve(2). L’attribution de « close-on-exec » au moment de la création, plutôt qu’ensuite avec fcntl(2), évite de potentielles situa- tions de compétition où le thread appelant invoque perf_event_open() et fcntl() en même temps qu’un autre thread appelle fork(2) puis execve(2). PERF_FLAG_FD_NO_GROUP Cet attribut dit à l'événement d'ignorer le paramètre group_fd, sauf pour initialiser la redirection de la sortie en utilisant l'attribut PERF_FLAG_FD_OUTPUT. PERF_FLAG_FD_OUTPUT (cassé depuis Linux 2.6.35) Cet attribut redirige la sortie échantillonnée de l'événement vers le tampon mmap de l'événement indiqué par group_fd. PERF_FLAG_PID_CGROUP (depuis Linux 2.6.39) Cet attribut active la surveillance par conteneur sur tout le système. Un conteneur est une abstraction qui isole un ensemble de ressources à contrôler plus finement (processeurs, mé- moire, etc.). Dans ce mode, l'événement n'est mesuré que si le thread exécuté sur le processeur surveillé appartient au conte- neur désigné (cgroup). Le cgroup est identifié en passant un fi- chier au descripteur de fichier ouvert sur son répertoire dans le système de fichiers cgroupfs. Par exemple, si le cgroup à surveiller est appelé test, alors un descripteur de fichier ou- vert sur /dev/cgroup/test (en supposant que cgroupfs est monté sur /dev/cgroup) doit être passé au paramètre pid. La sur- veillance de cgroup n'est disponible que pour les événements sur tout le système et pourrait donc nécessiter des droits supplé- mentaires. La structure perf_event_attr fournit des renseignements de configura- tion détaillés pour les événements en cours de création. struct perf_event_attr { __u32 type; /* Type d'événement */ __u32 size; /* Taille de la structure d'attributs */ __u64 config; /* Configuration spécifique au type */ union { __u64 sample_period; /* Période d'échantillonnage */ __u64 sample_freq; /* Fréquence d'échantillonnage */ }; __u64 sample_type; /* Indique les valeurs incluses dans l’échantillon */ __u64 read_format; /* Indique les valeurs renvoyées en lecture */ __u64 disabled : 1, /* désactivé par défaut */ inherit : 1, /* les enfants en héritent */ pinned : 1, /* doit toujours être en PMU */ exclusive : 1, /* ne regrouper qu'en PMU */ exclude_user : 1, /* ne pas compter l'utilisateur */ exclude_kernel : 1, /* ne pas compter le noyau */ exclude_hv : 1, /* ne pas compter l'hyperviseur */ exclude_idle : 1, /* ne pas compter quand inactif */ mmap : 1, /* inclure les données mmap */ comm : 1, /* inclure les données comm */ freq : 1, /* utiliser la fréquence, pas la période */ inherit_stat : 1, /* décomptes par tâche */ enable_on_exec : 1, /* prochain exec activé */ task : 1, /* tracer la création d’enfant et la fin */ watermark : 1, /* wakeup_watermark */ precise_ip : 2, /* contrainte de dérapage */ mmap_data : 1, /* données mmap non exécutées */ sample_id_all : 1, /* tous les événements sample_type */ exclude_host : 1, /* ne pas compter dans l'hôte */ exclude_guest : 1, /* ne pas compter dans l'invité */ exclude_callchain_kernel : 1, /* exclure les appels en chaîne du noyau */ exclude_callchain_user : 1, /* exclure les appels en chaîne d’utilisateur */ mmap2 : 1, /* inclure mmap avec les données d'inœud */ comm_exec : 1, /* événements flag comm devant être exécutés */ use_clockid : 1, /* utiliser clockid pour les champs de temps */ context_switch : 1, /* données de changement de contexte */ write_backward : 1, /* Écrire le tampon circulaire de la fin vers le début */ namespaces : 1, /* inclure les données des espaces de noms */ ksymbol : 1, /* inclure les événements ksymbol */ bpf_event : 1, /* inclure les événements BPF */ aux_output : 1, /* générer les enregistrements AUX au lieu des événements */ cgroup : 1, /* inclure les événements cgroup */ text_poke : 1, /* inclure les événements de poke de texte */ build_id : 1, /* utiliser build id dans les événements mmap2 */ inherit_thread : 1, /* seuls les enfants en héritent */ /* si cloné avec CLONE_THREAD */ remove_on_exec : 1, /* l'événement est supprimé des tâches à l'exécution */ sigtrap : 1, /* envoyer un SIGTRAP synchrone lors d'un événement */ __reserved_1 : 26; union { __u32 wakeup_events; /* réveil tous les n événements */ __u32 wakeup_watermark; /* octets avant le réveil */ }; __u32 bp_type; /* type de point d'arrêt */ union { __u64 bp_addr; /* adresse de point d'arrêt */ __u64 kprobe_func; /* pour perf_kprobe */ __u64 uprobe_path; /* pour perf_uprobe */ __u64 config1; /* extension de config */ }; union { __u64 bp_len; /* taille de point d'arrêt */ __u64 kprobe_addr; /* avec kprobe_func == NULL */ __u64 probe_offset; /* pour perf_[k,u]probe */ __u64 config2; /* extension de config1 */ }; __u64 branch_sample_type; /* enum perf_branch_sample_type */ __u64 sample_regs_user; /* registres utilisateur à renvoyer dans les échantillons */ __u32 sample_stack_user; /* taille de pile à renvoyer dans les échantillons */ __s32 clockid; /* horloge à utiliser pour les champs de temps */ __u64 sample_regs_intr; /* registres à renvoyer dans les échantillons */ __u32 aux_watermark; /* octets supp. avant le réveil */ __u16 sample_max_stack; /* nombre maximal de trames dans la chaîne d'appel */ __u32 __reserved_2; /* aligner sur u64 */ __u32 aux_sample_size; /* taille maximale d'échantillon aux */ __u32 __reserved_3; /* aligner sur u64 */ __u64 sig_data; /* données utilisateur pour sigtrap */ }; Les champs de la structure perf_event_attr sont décrits en détail ci-dessous. type Ce champ indique le type d'événement dans son ensemble. Il a une des valeurs suivantes : PERF_TYPE_HARDWARE Cela indique un des événements matériels « généralisés » fournis par le noyau. Consultez la définition du champ config pour plus de précisions. PERF_TYPE_SOFTWARE Cela indique un des événements logiciels fournis par le noyau (même si aucune prise en charge matérielle n'est disponible). PERF_TYPE_TRACEPOINT Cela indique un point de trace fourni par l'infrastruc- ture de point de trace du noyau. PERF_TYPE_HW_CACHE Cela indique un événement de cache matériel. Cela a un encodage particulier décrit dans la définition du champ config. PERF_TYPE_RAW Cela indique un événement « brut » spécifique à l'implé- mentation dans le champ config. PERF_TYPE_BREAKPOINT (depuis Linux 2.6.33) Cela indique un point d'arrêt matériel tel que fourni par le processeur. Les points d'arrêt peuvent être des accès en lecture ou écriture sur une adresse ainsi que l'exécu- tion d'une adresse d'instruction. PMU dynamique Depuis Linux 2.6.38, perf_event_open() permet de gérer plusieurs PMU. Pour activer cela, une valeur exportée par le noyau peut être utilisée dans le champ type pour indi- quer la PMU à utiliser. La valeur à utiliser est trou- vable dans le système de fichiers sysfs : un sous-réper- toire existe par instance PMU sous /sys/bus/event_source/devices. Le fichier type dans chaque sous-répertoire contient un entier qui peut être utilisé dans le champ type. Par exemple, /sys/bus/event_source/devices/cpu/type contient la valeur de PMU du processeur principal, c'est-à-dire 4 en géné- ral. kprobe et uprobe (depuis Linux 4.17) Ces deux PMU dynamiques créent un kprobe/uprobe et le rattachent à un descripteur de fichier généré par perf_event_open. kprobe/uprobe sera détruit lors de la destruction du descripteur de fichier. Voir les champs kprobe_func, uprobe_path, kprobe_addr et probe_offset pour plus de détails. size La taille de la structure perf_event_attr pour compatibilités ascendante et descendante. Définissez-la en utilisant si- zeof(struct perf_event_attr) pour permettre au noyau de voir la taille de struct au moment de la compilation. Le PERF_ATTR_SIZE_VER0 relatif est défini à 64 ; c'était la taille de la première struct publiée. PERF_ATTR_SIZE_VER1 est 72, correspondant à l'addition des points d'arrêts dans Li- nux 2.6.33. PERF_ATTR_SIZE_VER2 est 80, correspondant à l'addi- tion d'échantillonnage de branchement dans Linux 3.4. PERF_ATR_SIZE_VER3 est 96, correspondant à l'addition de sample_regs_user et sample_stack_user dans Linux 3.7. PERF_ATTR_SIZE_VER4 vaut 104, correspondant à l'ajout de sample_regs_intr dans Linux 3.19. PERF_ATTR_SIZE_VER5 vaut 112, correspondant à l'ajout de aux_watermark dans Linux 4.1. config Cela indique l'événement voulu, en conjonction avec le champ type. Les champs config1 et config2 sont aussi pris en compte dans les cas où 64 bits ne suffisent pas pour spécifier complè- tement l'événement. L'encodage de ces champs dépend de l'événe- ment. Le champ config peut être défini de différentes façons, en fonc- tion de la valeur du champ type précédemment décrit. Suivent les divers réglages possibles pour config, distingués par type. Si type est PERF_TYPE_HARDWARE, un des événements processeur ma- tériel généralisé est mesuré. Ils ne sont pas tous disponibles sur toutes les plateformes. Définissez config à une des valeurs suivantes : PERF_COUNT_HW_CPU_CYCLES Nombre total de cycles. Méfiez-vous de ce qui arrive lors de la variation de fréquence du processeur. PERF_COUNT_HW_INSTRUCTIONS Instructions retirées. Prenez garde, elles peuvent être affectées par plusieurs problèmes, en particu- lier les décomptes d'interruptions matérielles. PERF_COUNT_HW_CACHE_REFERENCES Accès au cache. En général, cela indique les accès au cache de dernier niveau, mais cela peut dépendre du processeur. Cela pourrait inclure des messages de prélecture et de cohérence ; cela dépend toujours de la conception du processeur. PERF_COUNT_HW_CACHE_MISSES Absences dans le cache. Cela indique généralement les absences dans le cache de dernier niveau, c'est destiné à être utilisé en conjonction avec l'événe- ment PERF_COUNT_HW_CACHE_REFERENCES pour calculer le taux d’absence du cache. PERF_COUNT_HW_BRANCH_INSTRUCTIONS Instructions de branchements retirés. Avant Li- nux 2.6.34, cela utilisait l’événement incorrect sur les processeurs AMD. PERF_COUNT_HW_BRANCH_MISSES Instructions de branchements mal prédits. PERF_COUNT_HW_BUS_CYCLES Cycles de bus, ce qui peut être différent du dé- compte total de cycles. PERF_COUNT_HW_STALLED_CYCLES_FRONTEND (depuis Linux 3.0) Cycles bloqués pendant un problème. PERF_COUNT_HW_STALLED_CYCLES_BACKEND (depuis Linux 3.0) Cycles bloqués pendant un retrait. PERF_COUNT_HW_REF_CPU_CYCLES (depuis Linux 3.3) Nombre total de cycles ; non affecté par la varia- tion de fréquence du processeur. Si type est PERF_TYPE_SOFTWARE, les événements logiciels fournis par le noyau sont mesurés. Définissez config à une des valeurs suivantes : PERF_COUNT_SW_CPU_CLOCK Cela rend compte de l'horloge du processeur, un tem- porisateur par processeur à haute résolution. PERF_COUNT_SW_TASK_CLOCK Cela rend compte de l'horloge spécifique à la tâche en cours d'exécution. PERF_COUNT_SW_PAGE_FAULTS Cela rend compte du nombre d'erreurs de pagination. PERF_COUNT_SW_CONTEXT_SWITCHES Cela compte les changements de contexte. Jusqu'à Li- nux 2.6.34, ils étaient tous signalés comme des évé- nements en espace utilisateur, ils sont maintenant signalés comme ayant lieu dans le noyau. PERF_COUNT_SW_CPU_MIGRATIONS Cela rend compte du nombre de fois où le processus a migré vers un nouveau processeur. PERF_COUNT_SW_PAGE_FAULTS_MIN Cela compte le nombre d'erreurs mineures de pagina- tion. Elles n'ont pas nécessité d'entrées ou sorties du disque pour les traiter. PERF_COUNT_SW_PAGE_FAULTS_MAJ Cela compte le nombre d'erreurs majeures de pagina- tion. Elles ont nécessité des entrées ou sorties de disque pour les traiter. PERF_COUNT_SW_ALIGNMENT_FAULTS (depuis Linux 2.6.33) Cela compte le nombre de défauts d'alignement. Ils ont lieu lors d'accès non alignés en mémoire ; le noyau peut les traiter mais cela réduit les perfor- mances. Cela n'arrive que sur certaines architec- tures (jamais sur x86). PERF_COUNT_SW_EMULATION_FAULTS (depuis Linux 2.6.33) Cela compte le nombre de défauts d'émulation. Le noyau intercepte parfois des instructions non implé- mentées et les émule pour l'espace utilisateur. Cela peut avoir des conséquences négatives sur les per- formances. PERF_COUNT_SW_DUMMY (depuis Linux 3.12) C’est un événement fictif qui ne compte rien. Les types d’enregistrement d’échantillonnage informatif comme mmap ou comm doivent être associés à un événe- ment actif. Cet événement factice permet de récupé- rer ce genre d’enregistrements sans nécessiter d’événement de comptage. PERF_COUNT_SW_BPF_OUTPUT (depuis Linux 4.4) Cela est utilisé pour générer des données d'échan- tillonnage brutes à partir de BPF. Les programmes BPF peuvent écrire sur cet événement en utilisant l'assistant bpf_perf_event_output. PERF_COUNT_SW_CGROUP_SWITCHES (since Linux 5.13) Cela compte les changements de contexte d'une tâche dans un cgroup différent. En d'autres termes, si la tâche suivante est dans le même cgroup, il ne comp- tera le changement. Si type est PERF_TYPE_TRACEPOINT, alors les points de trace du noyau sont mesurés. La valeur à utiliser dans config peut être obtenue depuis tracing/events/*/*/id de debugfs si ftrace est activé dans le noyau. Si type est PERF_TYPE_HW_CACHE, alors un événement de cache du processeur matériel est mesuré. Utilisez l'équation suivante pour calculer la valeur config appropriée. config = (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) | (perf_hw_cache_op_result_id << 16); où perf_hw_cache_id peut être : PERF_COUNT_HW_CACHE_L1D pour mesurer le cache de données de niveau 1 ; PERF_COUNT_HW_CACHE_L1I pour mesurer le cache d'instructions de ni- veau 1 ; PERF_COUNT_HW_CACHE_LL pour mesurer le cache de dernier niveau ; PERF_COUNT_HW_CACHE_DTLB pour mesurer les données TLB ; PERF_COUNT_HW_CACHE_ITLB pour mesurer les instructions TLB ; PERF_COUNT_HW_CACHE_BPU pour mesurer l'unité de prédiction de branche- ment ; PERF_COUNT_HW_CACHE_NODE (depuis Linux 3.1) pour mesurer les accès à la mémoire locale. et perf_hw_cache_op_id est parmi : PERF_COUNT_HW_CACHE_OP_READ pour les accès en lecture ; PERF_COUNT_HW_CACHE_OP_WRITE pour les accès en écriture ; PERF_COUNT_HW_CACHE_OP_PREFETCH pour les accès de prélecture et perf_hw_cache_op_result_id peut être : PERF_COUNT_HW_CACHE_RESULT_ACCESS pour mesurer les accès ; PERF_COUNT_HW_CACHE_RESULT_MISS pour mesurer les échecs. Si type est PERF_TYPE_RAW, alors une valeur config « brute » personnalisée est nécessaire. La plupart des processeurs gèrent les événements qui ne sont pas couverts par les événements « gé- néralisés ». Ceux-ci sont définis par l'implémentation ; consul- tez le manuel du processeur (par exemple la documentation Intel Volume 3B ou le guide du développeur de BIOS et noyau AMD). La bibliothèque libpfm4 peut être utilisée pour traduire le nom, dans les manuels architecturaux, en valeur hexadécimale brute que perf_event_open() attend dans ce champ. Si type est PERF_TYPE_BREAKPOINT, alors laissez config défini à zéro. Ses paramètres sont définis ailleurs. Si type est kprobe ou uprobe, définir retprobe (bit 0 de config, voir /sys/bus/event_source/devices/[k,u]probe/format/retprobe) pour kretprobe/uretprobe. Voir les champs kprobe_func, uprobe_path, kprobe_addr et probe_offset pour plus de détails. kprobe_func, uprobe_path, kprobe_addr et probe_offset Ces champs décrivent les kprobe/uprobe pour les PMU dynamiques kprobe et uprobe. Pour kprobe utilisez kprobe_func et probe_off- set ou alors utilisez kprobe_addr et laissez le champ kprobe_func à NULL. Pour uprobe, utilisez uprobe_path et probe_offset. sample_period, sample_freq Un compteur d'« échantillonnage » génère une notification de dé- passement tous les N événements, où N est donné par sample_per- iod. Un compteur d'échantillonnage a sample_period > 0. Quand un dépassement arrive, les données demandées sont enregistrées dans le tampon mmap. Le champ sample_type contrôle les données qui sont enregistrées à chaque dépassement. sample_freq permet d'utiliser la fréquence au lieu de la pé- riode. Dans ce cas, l'attribut freq doit être défini. Le noyau ajustera la période d'échantillonnage pour essayer d'atteindre le taux voulu. Le taux d'ajustement est un tic d'horloge. sample_type Les divers bits de ce champ indiquent les valeurs à inclure dans l'échantillon. Elles seront enregistrées dans un tampon circu- laire, disponible en espace utilisateur avec mmap(2). L'ordre de sauvegarde des valeurs dans l'échantillon est documenté dans la sous-section Disposition MMAP ci-dessous ; ce n'est pas l'ordre enum perf_event_sample_format. PERF_SAMPLE_IP Enregistrement de pointeur d'instruction. PERF_SAMPLE_TID Enregistrement des identifiants de processus et de thread. PERF_SAMPLE_TIME Enregistrement d'un horodatage. PERF_SAMPLE_ADDR Enregistrement d'une adresse, si applicable. PERF_SAMPLE_READ Enregistrement des valeurs de décompte de tous les événe- ments d'un groupe, pas seulement du leader de groupe. PERF_SAMPLE_CALLCHAIN Enregistrement de l'appel en chaîne (backtrace de pile). PERF_SAMPLE_ID Enregistrement d'un identifiant unique pour le leader de groupe d'événements ouvert. PERF_SAMPLE_CPU Enregistrement de numéro de processeur. PERF_SAMPLE_PERIOD Enregistrement de la période d'échantillonnage actuelle. PERF_SAMPLE_STREAM_ID Enregistrement d'un identifiant unique pour l'événement ouvert. Contrairement à PERF_SAMPLE_ID, le véritable identifiant est renvoyé, pas celui du leader de groupe. Cet identifiant est le même que celui renvoyé par PERF_FORMAT_ID. PERF_SAMPLE_RAW Enregistrement de données supplémentaires, si applicable. Normalement renvoyées par les événements de point de trace. PERF_SAMPLE_BRANCH_STACK (depuis Linux 3.4) Cela fournit un enregistrement des derniers branchements tels que fournis par le matériel d’échantillonnage de branchement processeur (comme le LBR – Last Branch Re- cord – d’Intel). Les matériels ne prennent pas tous en charge cette fonctionnalité. Consultez le champ branch_sample_type pour la façon de filtrer les branchements signalés. PERF_SAMPLE_REGS_USER (depuis Linux 3.7) Enregistrement de l’état actuel du registre processeur au niveau utilisateur (les valeurs dans le processus avant d’appeler le noyau). PERF_SAMPLE_STACK_USER (depuis Linux 3.7) Enregistrement de la pile au niveau utilisateur, permet- tant le défilement de la pile. PERF_SAMPLE_WEIGHT (depuis Linux 3.10) Enregistrement d’une valeur de poids fournie par le maté- riel qui exprime le coût de l’événement d’échantillon- nage. Cela permet au matériel de mettre en valeur les événements coûteux dans un profil. PERF_SAMPLE_DATA_SRC (depuis Linux 3.10) Enregistrement des sources de données : d’où viennent, dans la hiérarchie de mémoire, les données associées à l’instruction d’échantillonnage. Ce n’est disponible que si le matériel sous-jacent prend en charge cette fonc- tionnalité. PERF_SAMPLE_IDENTIFIER (depuis Linux 3.12) Placement de la valeur SAMPLE_ID à un endroit fixe de l’enregistrement, soit au début (pour les événements d’échantillonnage), soit à la fin (si ce n’est pas un événement d’échantillonnage). C’était nécessaire parce qu’un flux d’échantillonnage pourrait avoir des enregistrements provenant de diffé- rentes sources d’événements avec des réglages de sample_type différents. L’analyse correcte du flux d’évé- nements n’était pas possible parce que le format de l’en- registrement était nécessaire pour trouver SAMPLE_ID, mais le format ne pouvait pas être trouvé sans savoir à quel événement l’échantillonnage appartenait (provoquant une dépendance circulaire). Ce nouveau réglage PERF_SAMPLE_IDENTIFIER rend le flux d’événements toujours analysable en plaçant SAMPLE_ID à une position fixe, même si cela a pour conséquence de du- pliquer les valeurs SAMPLE_ID dans les enregistrements. PERF_SAMPLE_TRANSACTION (depuis Linux 3.13) Enregistrement des raisons pour les événements d’abandon de mémoire transactionnelle (venant par exemple de la prise en charge de mémoire transactionnelle TSX Intel). Le réglage precise_ip doit être positif et un événement d’abandon de mémoire transactionnelle doit être mesuré sinon aucune valeur ne sera enregistrée. Remarquez égale- ment que certaines mesures perf_event, comme le comptage de cycles d’échantillonnage, peuvent provoquer des aban- dons supplémentaires (en provoquant une interruption lors d’une transaction). PERF_SAMPLE_REGS_INTR (depuis Linux 3.19) Enregistrement d'un sous-ensemble de l'état actuel du re- gistre du processeur comme indiqué par sample_regs_intr. Contrairement à PERF_SAMPLE_REGS_USER, les valeurs du re- gistre renverront l'état du registre du noyau si le dé- passement s'est produit alors que le code du noyau est en cours d'exécution. Si le processeur gère l'échantillon- nage matériel de l'état du registre (à savoir PEBS sur Intel x86) et si precise_ip est supérieur à zéro, les va- leurs du registre renvoyées sont celles récupérées par le matériel au moment du retrait de l'instruction échan- tillonnée. PERF_SAMPLE_PHYS_ADDR (depuis Linux 4.13) Enregistrement de l'adresse physique des données comme avec PERF_SAMPLE_ADDR. PERF_SAMPLE_CGROUP (depuis Linux 5.7) Enregistrement de l'identifiant cgroup (perf_event) du processus. Cela correspond au champ id de l'événement PERF_RECORD_CGROUP. PERF_SAMPLE_DATA_PAGE_SIZE (depuis Linux 5.11) Enregistrement de la taille de la page de données comme avec PERF_SAMPLE_ADDR. PERF_SAMPLE_CODE_PAGE_SIZE (depuis Linux 5.11) Enregistrement de la taille de la page de l'ip comme avec PERF_SAMPLE_ADDR. PERF_SAMPLE_WEIGHT_STRUCT (depuis Linux 5.12) Enregistrement d’une valeur de poids fournie par le maté- riel comme PERF_SAMPLE_WEIGHT, mais il peut représenter plusieurs valeur dans un struct. Il partage le même es- pace que PERF_SAMPLE_WEIGHT, aussi les utilisateurs peuvent appliquer l'un ou l'autre, mais pas les deux à la fois. Il a le format suivant et la signification de chaque champ dépend de l'implémentation matérielle. union perf_sample_weight { u64 full; /* PERF_SAMPLE_WEIGHT */ struct { /* PERF_SAMPLE_WEIGHT_STRUCT */ u32 var1_dw; u16 var2_w; u16 var3_w; }; }; read_format Ce champ indique le format des données renvoyées par read(2) sur un descripteur de fichier perf_event_open(). PERF_FORMAT_TOTAL_TIME_ENABLED Ajout du champ time_enabled de 64 bits. Cela peut servir à calculer les totaux estimés si la PMU est surutilisée et qu'il y a multiplexage. PERF_FORMAT_TOTAL_TIME_RUNNING Ajout du champ time_running de 64 bits. Cela peut servir pour calculer les totaux estimés si la PMU est surutili- sée et qu'il y a multiplexage. PERF_FORMAT_ID Ajout d'une valeur unique de 64 bits qui correspond au groupe d’événements. PERF_FORMAT_GROUP Permettre à toutes les valeurs de décompte d'un groupe d'événements d'être lues en une seule lecture. PERF_FORMAT_LOST (depuis Linux 6.0) Ajout d'une valeur 64 bits qui est le nombre d'échan- tillons perdus pour cet événement. Ce ne devrait signifi- catif uniquement quand sample_period ou sample_freq est défini. disabled Le bit disabled indique si le compteur commence désactivé ou ac- tivé. Si désactivé, l'événement peut être activé plus tard par ioctl(2), prctl(2) ou enable_on_exec. Lors de la création d’un groupe d’événements, le leader de groupe est généralement initialisé avec disabled défini à 1 et tous les événements enfants sont initialisés avec disabled dé- fini à 0. Bien que disabled soit 0, les événements enfants ne démarrent pas avant que le leader de groupe ne soit activé. inherit Le bit inherit indique que le compteur devrait compter les évé- nements des tâches enfant comme les tâches indiquées. Cela ne s'applique qu'aux nouveaux enfants, pas à ceux existants au mo- ment où le compteur est créé (ni aux nouveaux enfants des en- fants existants). L'héritage ne fonctionne pas pour certaines combinaisons de read_format, comme PERF_FORMAT_GROUP. pinned Le bit pinned indique que le compteur devrait toujours être sur le processeur si c'est possible. Cela ne s'applique qu'aux comp- teurs matériels et seulement aux leaders de groupe. Si un comp- teur épinglé ne peut pas être mis dans le processeur (par exemple s'il n'y a pas assez de compteurs matériels ou en cas de confit avec n'importe quel autre événement), alors le compteur arrive en état d'« erreur », où les lectures renvoient une fin de fichier (c'est-à-dire que read(2) renvoie 0) jusqu'à ce que le compteur soit ensuite activé ou désactivé. exclusive Le bit exclusive indique que si ce groupe du compteur est sur le processeur, il devrait être le seul groupe utilisant les comp- teurs du processeur. Cela pourrait permettre à l'avenir de sur- veiller des programmes pour gérer les fonctionnalités PMU qui doivent fonctionner seules, sans perturber d'autres compteurs matériels. Remarquez que de nombreuses situations non attendues pourraient empêcher de démarrer les événements avec le bit exclusive dé- fini. Cela concerne tous les utilisateurs exécutant des mesures au niveau du système ainsi que toutes les utilisations par le noyau des compteurs de performance (y compris l’interface NMI Watchdog Timer habituellemen activée). exclude_user Si ce bit est défini, le décompte exclut les événements qui ar- rivent dans l'espace utilisateur. exclude_kernel Si ce bit est défini, le décompte exclut les événements qui ar- rivent dans l'espace du noyau. exclude_hv Si ce bit est défini, le décompte exclut les événements qui ar- rivent dans l'hyperviseur. C'est surtout pour les PMU avec prise en charge intégrée de leur traitement (comme POWER). Une prise en charge supplémentaire est nécessaire pour traiter les mesures d'hyperviseur sur la plupart des machines. exclude_idle S'il est défini, ne pas décompter quand le processeur exécute la tâche inactive. Si vous pouvez actuellement activer cela pour n'importe quel type d'événement, il est ignoré pour tous, sauf ceux de type logiciel. mmap Le bit mmap active la génération des échantillons PERF_RE- CORD_MMAP pour tous les appels mmap(2) qui ont PROT_EXEC défini. Cela permet aux outils de remarquer le nouveau code exécutable en train d’être associé dans un programme (les bibliothèques partagées dynamiques par exemple) de telle sorte que les adresses peuvent être réassociées au code d’origine. comm Le bit comm active le suivi du nom de commande de processus tel que modifié par les appels système execve(2) et prctl(PR_SET_NAME) ainsi que l'écriture dans /proc/self/comm. Si l'attribut comm_exec est positionné avec succès (ce qui est pos- sible depuis Linux 3.16), l'attribut général PERF_RE- CORD_MISC_COMM_EXEC peut être utilisé pour différencier le cas execve(2) des autres. freq Si ce bit est activé, alors sample_frequency est utilisé au lieu de sample_period lors du réglage de l'intervalle d'échantillon- nage. inherit_stat Ce bit active la sauvegarde des décomptes d'événements lors du changement de contexte pour les tâches héritées. Cela n'a de sens que si le champ inherit est défini. enable_on_exec Si ce bit est défini, un compteur est automatiquement activé après un appel d'execve(2). task Si ce bit est défini, alors les notifications de création d’en- fant et de fin sont inclues au tampon circulaire. watermark Si défini, une notification de débordement arrive lors du pas- sage de la frontière wakeup_watermark. Sinon, les notifications arrivent après les échantillons wakeup_events. precise_ip (depuis Linux 2.6.35) Cela contrôle la quantité de dérapage. Le dérapage est le nombre d'instructions qui s'exécutent entre l'arrivée d'un événement d'intérêt et la possibilité du noyau de s'arrêter pour enregis- trer l'événement. Les plus petits dérapages sont meilleurs et permettent d'associer plus précisément les événements correspon- dant aux instructions, mais le matériel est souvent limité par leur taille. Les valeurs possibles du champ sont les suivantes : 0 SAMPLE_IP peut avoir un dérapage arbitraire ; 1 SAMPLE_IP doit avoir un dérapage constant ; 2 SAMPLE_IP a demandé un dérapage nul ; 3 SAMPLE_IP doit avoir un dérapage nul. Consultez aussi la description de PERF_RECORD_MISC_EXACT_IP. mmap_data (depuis Linux 2.6.36) L’opposé du champ mmap. Cela active la génération des échan- tillons PERF_RECORD_MMAP pour les appels mmap(2) qui n’ont pas PROT_EXEC défini (par exemple les données et la mémoire partagée SysV). sample_id_all (depuis Linux 2.6.38) Si défini, alors TID, TIME, ID, STREAM_ID et CPU peuvent de plus être inclus dans les non PERF_RECORD_SAMPLE si le sample_type correspondant est sélectionné. Si PERF_SAMPLE_IDENTIFIER est indiqué, alors une valeur d’iden- tifiant supplémentaire est incluse en dernière valeur pour faci- liter l’analyse du flux d’enregistrement. Cela peut avoir pour conséquence de voir apparaître la valeur id deux fois. La disposition est décrite par cette pseudostructure : struct sample_id { { u32 pid, tid; } /* si PERF_SAMPLE_TID est défini */ { u64 time; } /* si PERF_SAMPLE_TIME est défini */ { u64 id; } /* si PERF_SAMPLE_ID est défini */ { u64 stream_id;} /* si PERF_SAMPLE_STREAM_ID est défini */ { u32 cpu, res; } /* si PERF_SAMPLE_CPU est défini */ { u64 id; } /* si PERF_SAMPLE_IDENTIFIER est défini */ }; exclude_host (depuis Linux 3.2) Quand on prend des mesures comprenant les processus exécutant des instances de VM (à savoir si on exécute ioctl(2) KVM_RUN), ne mesurer que les événements dans l'instance de l'invité. Cela n'a de sens qu'à l'extérieur de l'invité ; ce paramètre ne modi- fie pas les compteurs à l'intérieur d'un invité. Actuellement, cette fonctionnalité n'existe que sur x86. exclude_guest (depuis Linux 3.2) Quand on prend des mesures comprenant les processus exécutant des instances de VM (à savoir si on exécute ioctl(2) KVM_RUN), ne pas mesurer les événements dans l'instance de l'invité. Cela n'a de sens qu'à l'extérieur de l'invité ; ce paramètre ne modi- fie pas les compteurs à l'intérieur d'un invité. Actuellement, cette fonctionnalité n'existe que sur x86. exclude_callchain_kernel (depuis Linux 3.7) Ne pas inclure les appels en chaîne du noyau. exclude_callchain_user (depuis Linux 3.7) Ne pas inclure les appels en chaîne d'utilisateur. mmap2 (depuis Linux 3.16) Générer un enregistrement mmap exécutable étendu contenant assez d'informations supplémentaires pour n'identifier que les projec- tions partagées. L'attribut mmap doit aussi être défini pour que cela fonctionne. comm_exec (depuis Linux 3.16) Il s'agit d'un attribut de pure détection de fonctionnalité, il ne modifie pas le comportement du noyau. Si cet attribut peut être positionné avec succès, quand comm est activé, l'attribut PERF_RECORD_MISC_COMM_EXEC sera positionné dans le champ misc de l'entête de l'enregistrement comm si l'événement de renommage signalé a été causé par un appel à execve(2). Cela permet aux outils de distinguer les types de renommage du processus. use_clockid (depuis Linux 4.1) Cela permet de sélectionner l'horloge interne du noyau Linux à utiliser lors de la génération des horodatages à l'aide du champ clockid. Cela peut faciliter la corrélation des durées d'échan- tillonnage des perf avec les horodatages générés par d'autres outils. context_switch (depuis Linux 4.3) Cela active la génération d'enregistrements PERF_RECORD_SWITCH lors d'un changement de contexte. Cela active aussi la généra- tion d'enregistrements PERF_RECORD_SWITCH_CPU_WIDE lors d'un échantillonnage en mode processeur complet. Cette fonctionnalité s'ajoute aux points de trace existants et aux événements logi- ciels de mesure des changements de contexte. L'avantage de cette méthode est qu'elle fournira toutes les informations même avec des réglages perf_event_paranoid stricts. write_backward (depuis Linux 4.6) Cela fait écrire le tampon circulaire de la fin vers le début. Cela permet de gérer la lecture à partir d’un tampon circulaire réinscriptible. namespaces (depuis Linux 4.11) Cela active la génération d'enregistrements PERF_RECORD_NAMES- PACES lorsqu'une tâche entre dans un nouvel espace de noms. Chaque espace de noms a une combinaison de numéros de périphé- rique et d'inœud. ksymbol (depuis Linux 5.0) Cela active la génération d'enregistrements PERF_RECORD_KSYMBOL quand de nouveaux symboles du noyau sont enregistrés ou désenre- gistrés. Cela concerne les fonctions dynamiques d’analyse du noyau comme eBPF. bpf_event (depuis Linux 5.0) Cela active la génération d'enregistrements PERF_RE- CORD_BPF_EVENT lorsqu'un programme eBPF est chargé ou déchargé. aux_output (depuis Linux 5.4) Cela permet aux événements normaux (non-AUX) de générer des don- nées pour des événements AUX si le matériel le prend en charge. cgroup (depuis Linux 5.7) Cela active la génération d'enregistrements PERF_RECORD_CGROUP quand un nouveau cgroup est créé (et activé). text_poke (depuis Linux 5.8) Cela active la génération d'enregistrements PERF_RE- CORD_TEXT_POKE quand un changement se produit dans le texte du noyau (c'est-à-dire quand du code se modifie lui-même). build_id (depuis Linux 5.12) Cela modifie le contenu dePERF_RECORD_MMAP2 pour avoir un build-id à la place des numéros de périphérique et d'inœud. inherit_thread (depuis Linux 5.13) Cela désactive l'héritage de l'événement vers un processus en- fant. Seuls les nouveaux threads dans le même processus (qui est cloné avec CLONE_THREAD) hériteront de l'événement. remove_on_exec (depuis Linux 5.13) Cela clôt l'événement quand il démarre une nouvelle image de processus avec execve(2). sigtrap (depuis Linux 5.13) Cela permet l'envoi d'un signal synchrone de SIGTRAP quand un événement déborde. wakeup_events, wakeup_watermark Cette union indique le nombre d'échantillons (wakeup_events) ou d'octets (wakeup_watermark) qui arrivent avant un signal de dé- passement. Celui utilisé est sélectionné par l'attribut water- mark. wakeup_events ne compte que les types d’enregistrement PERF_RE- CORD_SAMPLE. Pour recevoir un signal pour tous les types PERF_RECORD arrivant, choisissez watermark et définissez wa- keup_watermark à 1. Avant Linux 3.0, positionner wakeup_events à 0 ne signalait au- cun dépassement ; les noyaux plus récents traitent 0 comme 1. bp_type (depuis Linux 2.6.33) Cela choisit le type de point d'arrêt. Il s'agit d'un des sui- vants : HW_BREAKPOINT_EMPTY pas de point d'arrêt ; HW_BREAKPOINT_R compte lors de la lecture de l'emplacement mémoire ; HW_BREAKPOINT_W compte lors de l'écriture à l'emplacement mémoire ; HW_BREAKPOINT_RW compte lors de la lecture ou l'écriture à l'emplacement mémoire ; HW_BREAKPOINT_X compte lors de l'exécution de code à l'emplacement mé- moire. Les valeurs peuvent être combinées à l'aide d'un OU binaire, mais les combinaisons de HW_BREAKPOINT_R ou HW_BREAKPOINT_W avec HW_BREAKPOINT_X ne sont pas permises. bp_addr (depuis Linux 2.6.33) Il s'agit de l'adresse du point d'arrêt. Pour les points d'arrêt d'exécution, c'est l'adresse mémoire de l'instruction d'inté- rêt ; pour les points d'arrêt de lecture et écriture, c'est l'adresse mémoire de l'emplacement mémoire d'intérêt. config1 (depuis Linux 2.6.39) config1 est utilisé pour définir des événements qui ont besoin d'un registre supplémentaire ou qui sinon ne rentrent pas dans le champ config normal. OFFCORE_EVENTS brut sur Nehalem/West- mere/SandyBridge utilise ce champ sur Linux 3.3 et les noyaux suivants. bp_len (depuis Linux 2.6.33) bp_len est la taille du point d'arrêt mesuré si type est PERF_TYPE_BREAKPOINT. Les options sont HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, HW_BREAKPOINT_LEN_4 et HW_BREAKPOINT_LEN_8. Pour un point d'arrêt, définissez-la à sizeof(long). config2 (depuis Linux 2.6.39) config2 est une extension supplémentaire du champ config1. branch_sample_type (depuis Linux 3.4) Si PERF_SAMPLE_BRANCH_STACK est activé, alors cela indique les branchements à inclure dans l’enregistrement de branchements. La première partie de la valeur est le niveau de droits qui est une combinaison d’une des valeurs suivantes. Si l’utilisateur ne définit pas explicitement le niveau de droits, le noyau utili- sera celui de l’événement. Les niveaux de droits de l’événement et du branchement ne doivent pas nécessairement correspondre. PERF_SAMPLE_BRANCH_USER La cible de branchement est dans l'espace utilisateur. PERF_SAMPLE_BRANCH_KERNEL La cible de branchement est dans l'espace du noyau. PERF_SAMPLE_BRANCH_HV La cible de branchement est dans l'hyperviseur. PERF_SAMPLE_BRANCH_PLM_ALL Une valeur pratique qui correspond aux trois valeurs pré- cédentes combinées avec un OU. En plus de la valeur de droits, au moins un des bits suivants doit être défini. PERF_SAMPLE_BRANCH_ANY N'importe quel type de branchement. PERF_SAMPLE_BRANCH_ANY_CALL N'importe quelle branche d'appel (y compris les appels directs, indirects et les grands sauts). PERF_SAMPLE_BRANCH_IND_CALL Appels indirects. PERF_SAMPLE_BRANCH_CALL (depuis Linux 4.4) Appels directs. PERF_SAMPLE_BRANCH_ANY_RETURN N'importe quel branchement de retour. PERF_SAMPLE_BRANCH_IND_JUMP (depuis Linux 4.2) Sauts indirects. PERF_SAMPLE_BRANCH_COND (depuis Linux 3.16) Branches conditionnelles. PERF_SAMPLE_BRANCH_ABORT_TX (depuis Linux 3.11) Abandons de mémoire transactionnelle. PERF_SAMPLE_BRANCH_IN_TX (depuis Linux 3.11) Branchement dans une transaction de mémoire transaction- nelle. PERF_SAMPLE_BRANCH_NO_TX (depuis Linux 3.11) Branchement non dans la transaction de la mémoire tran- sactionnelle. PERF_SAMPLE_BRANCH_CALL_STACK (depuis Li- nux 4.1). Le branchement faitpartie d'une pile d'appel générée par le matériel. Cela implique la prise en charge par le matériel, qui n'existe actuellement que sur le x86 Haswell d'Intel ou plus récent. sample_regs_user (depuis Linux 3.7) Ce masque binaire définit l’ensemble des registres processeur utilisateur à renvoyer dans les échantillons. La disposition du masque de registre est spécifique à l’architecture et définie dans l’en-tête du noyau arch/ARCH/include/uapi/asm/perf_regs.h. sample_stack_user (depuis Linux 3.7) Cela définit la taille de la pile utilisateur à renvoyer si PERF_SAMPLE_STACK_USER est indiqué. clockid (depuis Linux 4.1) Si use_clockid est positionné, ce champ sélectionne l'horloge interne de Linux à utiliser pour les horodatages. Les horloges disponibles sont définies dans linux/time.h, où sont actuelle- ment prises en charge CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME, CLOCK_BOOTTIME et CLOCK_TAI. aux_watermark (depuis Linux 4.1) Cela indique la quantité de données nécessaires pour récupérer un échantillonnage PERF_RECORD_AUX. sample_max_stack (depuis Linux 4.8) Quand sample_type comprend PERF_SAMPLE_CALLCHAIN, ce champ in- dique le nombre de trames de pile à rendre compte lors de la gé- nération de la chaîne d'appels. aux_sample_size (depuis Linux 5.5) Quand l'attribut PERF_SAMPLE_AUX est défini, spécification de la taille souhaitée aux données AUX. Notez qu'il peut recevoir des données plus petites que la taille indiquée. sig_data (depuis Linux 5.13) Cette donnée sera copiée vers le gestionnaire de signal de l'utilisateur (au moyen de si_perf dans siginfo_t ) pour disam- biguïser l'événement qui a déclenché le signal. Lecture des résultats Une fois qu'un descripteur de fichier perf_event_open() a été ouvert, les valeurs des événements peuvent être lues depuis le descripteur de fichier. Les valeurs présentes sont indiquées par le champ read_format de la structure attr au moment de l'ouverture. Si vous essayez de lire un tampon utilisé pour la lecture qui n'est pas assez grand pour contenir les données, ENOSPC est renvoyé. Voici la disposition des données renvoyées par une lecture : • Si PERF_FORMAT_GROUP a été indiqué pour permettre de lire tous les événements d'un groupe en une fois : struct read_format { u64 nr; /* Le nombre d'événements */ u64 time_enabled; /* si PERF_FORMAT_TOTAL_TIME_ENABLED */ u64 time_running; /* si PERF_FORMAT_TOTAL_TIME_RUNNING */ struct u64 value; /* La valeur de l'événement */ u64 id; /* si PERF_FORMAT_ID */ u64 lost; /* si PERF_FORMAT_LOST */ } values[nr]; }; • Si PERF_FORMAT_GROUP n'a pas été indiqué : struct read_format { u64 value; /* La valeur de l'événement */ u64 time_enabled; /* si PERF_FORMAT_TOTAL_TIME_ENABLED */ u64 time_running; /* si PERF_FORMAT_TOTAL_TIME_RUNNING */ u64 id; /* si PERF_FORMAT_ID */ u64 lost; /* si PERF_FORMAT_LOST */ }; Les valeurs lues sont les suivantes. nr Le nombre d'événements dans le descripteur de fichier. Seulement disponible si PERF_FORMAT_GROUP a été indiqué. time_enabled, time_running Temps total pendant lequel l'événement a été activé et exécuté. Normalement ce sont les mêmes. Si plus d'événements sont démar- rés que d'emplacements de compteur disponibles sur la PMU, alors il y a multiplexage et les événements ne sont pas exécutés tout le temps. Dans ce cas, les valeurs time_enabled et time running peuvent être utilisées pour estimer une valeur d'ordre de gran- deur du décompte. value Une valeur positive sur 64 bits contenant le résultat du comp- teur. id Une valeur unique globale pour cet événement en particulier, seulement si PERF_FORMAT_ID a été indiqué dans read_format. lost Le nombre des échantillons perdus de cet événement ; seulement si PERF_FORMAT_LOST a été indiqué dans read_format. Disposition MMAP En utilisant perf_event_open() en mode d'échantillonnage, les événe- ments asynchrones (comme un dépassement de compteur ou un suivi mmap PROT_EXEC) sont journalisés dans un tampon circulaire. Ce tampon circu- laire est créé et accédé à l'aide de mmap(2). La taille de mmap devrait être 1+2^n pages, où la première page est une page de métadonnées (struct perf_event_mmap_page) qui contient plu- sieurs informations comme l'emplacement de la tête du tampon circu- laire. Avant Linux 2.6.39, un bogue oblige à allouer un tampon circulaire mmap lors de l'échantillonnage même s'il n'est pas prévu de l'utiliser. La structure de la première page mmap de métadonnées est la suivante : struct perf_event_mmap_page { __u32 version; /* numéro de version de la structure */ __u32 compat_version; /* plus petite version compatible */ __u32 lock; /* seqlock pour synchronisation */ __u32 index; /* identifiant de compteur matériel */ __s64 offset; /* ajouter au compteur matériel */ __u64 time_enabled; /* temps d'événement actif */ __u64 time_running; /* temps d'événement sur processeur */ union { __u64 capabilities; struct { __u64 cap_usr_time / cap_usr_rdpmc / cap_bit0 : 1, cap_bit0_is_deprecated : 1, cap_user_rdpmc : 1, cap_user_time : 1, cap_user_time_zero : 1, }; }; __u16 pmc_width; __u16 time_shift; __u32 time_mult; __u64 time_offset; __u64 __reserved[120]; /* remplissage à 1 k */ __u64 data_head; /* tête de la section de données */ __u64 data_tail; /* queue écrite en espace utilisateur */ __u64 data_offset; /* où commence le tampon */ __u64 data_size; /* taille du tampon de données */ __u64 aux_head; __u64 aux_tail; __u64 aux_offset; __u64 aux_size; } } La liste suivante décrit les champs de la structure perf_event_mmap_page plus précisément. version Numéro de version de cette structure. compat_version La plus petite version avec laquelle elle est compatible. lock Un seqlock (sequence lock) pour la synchronisation. index Un identifiant unique de compteur matériel. décalage Quand l’instruction rdpmc est utilisée pour lire, cette valeur de position doit être ajoutée à celle renvoyée par rdpmc pour obtenir le décompte total actuel d’événements. time_enabled Temps d'activité de l'événement. time_running Temps d'exécution de l'événement. cap_usr_time / cap_usr_rdpmc / cap_bit0 (depuis Linux 3.4) Un bogue existait dans la définition de cap_usr_time et cap_usr_rdpmc de Linux 3.4 à Linux 3.11. Les deux bits étaient définis pour pointer vers le même endroit, il était donc impos- sible de savoir si cap_usr_time ou cap_usr_rdpmc étaient vrai- ment définis. Depuis Linux 3.12, ils ont été renommés en cap_bit0 et vous de- vriez plutôt utiliser les nouveaux champs cap_user_time et cap_user_rdpmc à la place. cap_bit0_is_deprecated (depuis Linux 3.12) Si défini, ce bit indique que le noyau est capable de gérer les bits cap_user_time et cap_user_rdpmc différenciés correctement. Si non, cela indique qu’il s’agit d’un ancien noyau où cap_usr_time et cap_usr_rdpmc pointent vers le même bit et donc que ces deux fonctionnalités devraient être utilisées avec pru- dence. cap_usr_rdpmc (depuis Linux 3.12) Si le matériel permet la lecture en espace utilisateur des comp- teurs de performance sans appel système (c'est l'instruction « rdpmc » sur x86), alors le code suivant peut être utilisé pour faire une lecture : u32 seq, time_mult, time_shift, idx, width; u64 count, enabled, running; u64 cyc, time_offset; do { seq = pc->lock; barrier(); enabled = pc->time_enabled; running = pc->time_running; if (pc->cap_usr_time && enabled != running) { cyc = rdtsc(); time_offset = pc->time_offset; time_mult = pc->time_mult; time_shift = pc->time_shift; } idx = pc->index; count = pc->offset; if (pc->cap_usr_rdpmc && idx) { width = pc->pmc_width; count += rdpmc(idx - 1); } barrier(); } while (pc->lock != seq); cap_user_time (depuis Linux 3.12) Ce bit indique que le matériel a un compteur temporel sans ar- rêt, constant (TSC sur x86). cap_usr_time_zero (depuis Linux 3.12) Indique la présence de time_zero qui permet d’associer les va- leurs d’horodatage à l’horloge matérielle. pmc_width Si cap_usr_rdpmc, ce champ fournit la taille en bit de la valeur lue en utilisant l'instruction rdpmc ou équivalente. Cela permet d'étendre avec signe le résultat comme ceci : pmc <<= 64 - pmc_width; pmc >>= 64 - pmc_width; // déplacement du signe à droite count += pmc; time_shift, time_mult, time_offset Si cap_usr_time, ces champs peuvent être utilisés pour calculer la différence de temps depuis time_enabled (en nanoseconde) en utilisant rdtsc ou similaire. u64 quot, rem; u64 delta; quot = cyc >> time_shift; rem = cyc & (((u64)1 << time_shift) - 1); delta = time_offset + quot * time_mult + ((rem * time_mult) >> time_shift); Où time_offset, time_mult, time_shift et cyc sont lus dans la boucle seqcount décrite ci-dessus. Cette différence peut être ajoutée à enabled et éventuellement running (si idx), pour amé- liorer l'échelle : enabled += delta; if (idx) running += delta; quot = count / running; rem = count % running; count = quot * enabled + (rem * enabled) / running; time_zero (depuis Linux 3.12) Si cap_usr_time_zero est défini, alors l'horloge matérielle (le compteur temporel TSC sur x86) peut être calculée à partir des valeurs time_zero, time_mult et time_shift : time = timestamp - time_zero; quot = time / time_mult; rem = time % time_mult; cyc = (quot << time_shift) + (rem << time_shift) / time_mult; et vice versa : quot = cyc >> time_shift; rem = cyc & (((u64)1 << time_shift) - 1); timestamp = time_zero + quot * time_mult + ((rem * time_mult) >> time_shift); data_head Cela pointe vers la tête de la section de données. La valeur augmente continuellement, elle n'est pas coupée. Vous devrez couper vous-même la valeur à la taille du tampon mmap avant d'accéder aux échantillons. Sur les plateformes compatibles SMP, après la lecture de la va- leur data_head, l'espace utilisateur devrait renvoyer un rmb(). data_tail Quand l'association est PROT_WRITE, la valeur data_tail devrait être écrite par l'espace utilisateur pour refléter les dernières données lues. Dans ce cas, le noyau n'écrasera pas les données non lues. data_offset (depuis Linux 4.1) Contient la position de l'emplacement du tampon mmap où les don- nées de l'échantillon de perf commencent. data_size (depuis Linux 4.1) Contient la taille de la zone de l'échantillon de perf dans le tampon mmap. aux_head, aux_tail, aux_offset, aux_size (depuis Linux 4.1) La zone AUX permet d'appliquer à un mmap(2) un tampon d'échan- tillonnage distinct pour les flux de données à forte bande pas- sante (séparément du tampon d'échantillonnage de perf princi- pal). Un exemple de flux à forte bande passante est la prise en charge du traçage d'une instruction telle qu'elle se fait dans les nouveaux processeurs Intel. Pour définir une zone AUX, il faut d'abord positionner aux_off- set à une position supérieure à data_offset+data_size puis posi- tionner aux_size à la taille de tampon désirée. La position et la taille désirée doivent être alignées sur la page et la taille doit être une puissance de deux. Ces valeurs sont alors passées à mmap pour projeter le tampon AUX. Les pages du tampon AUX sont comprises dans la limite de ressource RLIMIT_MEMLOCK (voir setr- limit(2)) et dans la gestion des droits perf_event_mlock_kb. Par défaut, le tampon AUX sera tronqué s'il ne rentre pas dans l'espace disponible du tampon circulaire. Si le tampon AUX est projeté en tant que tampon en lecture seule, il agira dans le mode du tampon circulaire là où les données seront remplacées par de nouvelles. En mode remplacement, il se pourrait qu'il ne soit pas possible de présumer l'endroit où commencent les don- nées et il appartient au consommateur de désactiver la mesure pendant la lecture pour éviter les possibles collisions de don- nées. Les pointeurs de tampon circulaire aux_head et aux_tail ont le même comportement et les mêmes règles d'organisation que celles décrites précédemment pour data_head et data_tail. Les 2^n pages suivantes du tampon circulaire ont la disposition décrite ci-dessous. Si perf_event_attr.sample_id_all est défini, alors tous les types d'événements auront les champs sample_type sélectionnés relatifs à l'emplacement et à la date (identité) où un événement a eu lieu (TID, TIME, ID, CPU, STREAM_ID) conformément à la description de PERF_RE- CORD_SAMPLE ci-dessous, il sera stocké juste après le perf_event_header et les champs déjà présents pour les champs existants, c'est-à-dire à la fin de la charge utile. De cette façon, un nouveau perf.data sera pris en charge par les outils de performances plus anciens, avec ces nouveaux champs facultatifs ignorés. Les valeurs mmap commencent par un en-tête : struct perf_event_header { __u32 type; __u16 misc; __u16 size; }; Les champs perf_event_header sont décrits plus précisément ci-dessous. Par commodité de lecture, les champs avec les descriptions les plus courtes sont d’abord présentés. size Cela indique la taille de l'enregistrement. misc Le champ misc contient des renseignements supplémentaires sur l'échantillon. Le mode de processeur peut être déterminé à partir de cette va- leur en la masquant avec PERF_RECORD_MISC_CPUMODE_MASK et en re- cherchant un des suivants (remarquez que ce ne sont pas des masques de bits, un seul peut être défini à la fois). PERF_RECORD_MISC_CPUMODE_UNKNOWN Mode de processeur inconnu. PERF_RECORD_MISC_KERNEL L'échantillon a eu lieu dans le noyau. PERF_RECORD_MISC_USER L'échantillon a eu lieu dans le code utilisateur. PERF_RECORD_MISC_HYPERVISOR L'échantillon a eu lieu dans l'hyperviseur. PERF_RECORD_MISC_GUEST_KERNEL (depuis Linux 2.6.35) L'échantillon a eu lieu dans le noyau client. PERF_RECORD_MISC_GUEST_USER (depuis Linux 2.6.35) L'échantillon a eu lieu dans le code utilisateur client. Comme les trois états suivants sont générés par différents types d'enregistrement, ils constituent des alias du même bit : PERF_RECORD_MISC_MMAP_DATA (depuis Linux 3.10) C’est défini quand l’association n’est pas exécutable ; sinon l’association est exécutable. PERF_RECORD_MISC_COMM_EXEC (depuis Linux 3.16) Il est positionné pour un enregistrement PERF_RECORD_COMM sur les noyaux plus récents que Linux 3.16 si le change- ment de nom d'un processus est causé par un appel système execve(2). PERF_RECORD_MISC_SWITCH_OUT (depuis Linux 4.3) Quand un enregistrement PERF_RECORD_SWITCH ou PERF_RE- CORD_SWITCH_CPU_WIDE est généré, ce bit indique que le changement de contexte est distinct du processus actuel (et n'en fait pas partie). De plus, les bits suivants peuvent être définis : PERF_RECORD_MISC_EXACT_IP Cela indique que le contenu de PERF_SAMPLE_IP pointe vers la véritable instruction qui a déclenché l'événement. Consultez aussi perf_event_attr.precise_ip. PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (depuis Linux 4.17) Quand un enregistrement PERF_RECORD_SWITCH ou PERF_RE- CORD_SWITCH_CPU_WIDE est généré, cela indique que le changement de contexte était une préemption. PERF_RECORD_MISC_MMAP_BUILD_ID (depuis Linux 5.12) Cela indique que le contenu de PERF_SAMPLE_MMAP2 renferme les données de build-ID plutôt que les numéros majeur et mineur du périphérique ainsi que le numéro d'inœud. PERF_RECORD_MISC_EXT_RESERVED (depuis Linux 2.6.35) Cela indique que des données étendues sont disponibles (actuellement pas utilisées). PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT Ce bit n'est pas défini par le noyau. Il est réservé à l'outil perf dans l'espace utilisateur pour indiquer que l'analyse de /proc/i[pid]/maps a trop duré et a été arrê- tée, ainsi les enregistrements mmap peuvent être tron- qués. type La valeur type est une des suivantes. Les valeurs dans l'enre- gistrement correspondant (qui suit l'en-tête) dépendent du type sélectionné comme c'est montré. PERF_RECORD_MMAP Les événements MMAP enregistrent les associations PROT_EXEC pour pouvoir mettre en corrélation les pointeurs d'instruc- tion en espace utilisateur et le code. Ils ont la structure suivante : struct { struct perf_event_header header; u32 pid, tid; u64 addr; u64 len; u64 pgoff; char filename[]; }; pid est l'identifiant de processus. tid est l'identifiant de thread. addr est l'adresse de la mémoire allouée. len est la taille de la mémoire allouée. pgoff est la position de la page de la mémoire allouée. filename est une chaîne décrivant la base de la mémoire allouée. PERF_RECORD_LOST Cet enregistrement indique quand des événements sont perdus. struct { struct perf_event_header header; u64 id; u64 lost; struct sample_id sample_id; }; id est l'identifiant unique d'événement pour les échan- tillons perdus. lost est le nombre d'événements perdus. PERF_RECORD_COMM Cet enregistrement indique une modification du nom de pro- cessus. struct { struct perf_event_header header; u32 pid; u32 tid; char comm[]; struct sample_id sample_id; }; pid est l'identifiant de processus. tid est l'identifiant de thread. comm est une chaîne contenant le nouveau nom du processus. PERF_RECORD_EXIT Cet enregistrement indique un événement de fin de processus. struct { struct perf_event_header header; u32 pid, ppid; u32 tid, ptid; u64 time; struct sample_id sample_id; }; PERF_RECORD_THROTTLE, PERF_RECORD_UNTHROTTLE Cet enregistrement indique un événement de variation de fré- quence du processeur. struct { struct perf_event_header header; u64 time; u64 id; u64 stream_id; struct sample_id sample_id; }; PERF_RECORD_FORK Cet enregistrement indique un événement de création d’en- fant. struct { struct perf_event_header header; u32 pid, ppid; u32 tid, ptid; u64 time; struct sample_id sample_id; }; PERF_RECORD_READ Cet enregistrement indique un événement de lecture. struct { struct perf_event_header header; u32 pid, tid; struct read_format values; struct sample_id sample_id; }; PERF_RECORD_SAMPLE Cet enregistrement indique un échantillon. struct { struct perf_event_header header; u64 sample_id; /* if PERF_SAMPLE_IDENTIFIER */ u64 ip; /* if PERF_SAMPLE_IP */ u32 pid, tid; /* if PERF_SAMPLE_TID */ u64 time; /* if PERF_SAMPLE_TIME */ u64 addr; /* if PERF_SAMPLE_ADDR */ u64 id; /* if PERF_SAMPLE_ID */ u64 stream_id; /* if PERF_SAMPLE_STREAM_ID */ u32 cpu, res; /* if PERF_SAMPLE_CPU */ u64 period; /* if PERF_SAMPLE_PERIOD */ struct read_format v; /* if PERF_SAMPLE_READ */ u64 nr; /* if PERF_SAMPLE_CALLCHAIN */ u64 ips[nr]; /* if PERF_SAMPLE_CALLCHAIN */ u32 size; /* if PERF_SAMPLE_RAW */ char data[size]; /* if PERF_SAMPLE_RAW */ u64 bnr; /* if PERF_SAMPLE_BRANCH_STACK */ struct perf_branch_entry lbr[bnr]; /* if PERF_SAMPLE_BRANCH_STACK */ u64 abi; /* if PERF_SAMPLE_REGS_USER */ u64 regs[weight(mask)]; /* if PERF_SAMPLE_REGS_USER */ u64 size; /* if PERF_SAMPLE_STACK_USER */ char data[size]; /* if PERF_SAMPLE_STACK_USER */ u64 dyn_size; /* if PERF_SAMPLE_STACK_USER && size != 0 */ union perf_sample_weight weight; /* if PERF_SAMPLE_WEIGHT */ /* || PERF_SAMPLE_WEIGHT_STRUCT */ u64 data_src; /* if PERF_SAMPLE_DATA_SRC */ u64 transaction; /* if PERF_SAMPLE_TRANSACTION */ u64 abi; /* if PERF_SAMPLE_REGS_INTR */ u64 regs[weight(mask)]; /* if PERF_SAMPLE_REGS_INTR */ u64 phys_addr; /* if PERF_SAMPLE_PHYS_ADDR */ u64 cgroup; /* if PERF_SAMPLE_CGROUP */ u64 data_page_size; /* if PERF_SAMPLE_DATA_PAGE_SIZE */ u64 code_page_size; /* if PERF_SAMPLE_CODE_PAGE_SIZE */ u64 size; /* if PERF_SAMPLE_AUX */ char data[size]; /* if PERF_SAMPLE_AUX */ }; sample_id Si PERF_SAMPLE_IDENTIFIER est activé, un identifiant unique sur 64 bits est inclus. C’est une copie de la va- leur id de PERF_SAMPLE_ID, mais incluse au début de l’échantillon pour permettre aux analyseurs d’obtenir facilement la valeur. ip Si PERF_SAMPLE_IP est activé, alors une valeur de poin- teur d'instruction sur 64 bits est incluse. pid, tid Si PERF_SAMPLE_TID est activé, alors un identifiant de processus sur 32 bits et un identifiant de thread sur 32 bits sont inclus. time Si PERF_SAMPLE_TIME est activé, alors un horodatage sur 64 bits est inclus. C'est obtenu à l'aide de lo- cal_clock() qui est un horodatage matériel si disponible et la valeur jiffy sinon. addr Si PERF_SAMPLE_ADDR est activé, alors une adresse sur 64 bits est incluse. C'est généralement l'adresse d'un point de trace, point d'arrêt ou événement logiciel ; sinon la valeur est 0. id Si PERF_SAMPLE_ID est activé, un identifiant unique sur 64 bits est inclus. Si l'événement est membre d'un groupe d'événements, l'identifiant du leader de groupe est renvoyé. Cet identifiant est le même que celui ren- voyé par PERF_FORMAT_ID. stream_id Si PERF_SAMPLE_STREAM_ID est activé, un identifiant unique sur 64 bits est inclus. Contrairement à PERF_SAMPLE_ID, le véritable identifiant est renvoyé, pas celui du leader de groupe. Cet identifiant est le même que celui renvoyé par PERF_FORMAT_ID. cpu, res Si PERF_SAMPLE_CPU est activé, c'est une valeur sur 32 bits indiquant le processeur qui a été utilisé, en supplément d'une valeur réservée (non utilisée) sur 32 bits. period Si PERF_SAMPLE_PERIOD est activé, une valeur sur 64 bits indiquant la période d'échantillonnage actuelle est écrite. v Si PERF_SAMPLE_READ est activé, une structure de type read_format est incluse avec des valeurs pour tous les événements du groupe d'événements. Les valeurs incluses dépendent de la valeur read_format utilisée au moment de perf_event_open(). nr, ips[nr] Si PERF_SAMPLE_CALLCHAIN est activé, alors un nombre sur 64 bits est inclus, indiquant le nombre de pointeurs d'instruction sur 64 bits qui suivent. C'est l'appel en chaîne actuel. size, data[size] Si PERF_SAMPLE_RAW est activé, alors une valeur sur 32 bits indiquant la taille est incluse, suivie par un tableau de valeurs sur 8 bits de taille size. Les va- leurs sont remplies avec des 0 pour avoir un alignement à 64 bits. Ces données brutes d'enregistrement sont opaques du point de vue de l'ABI. L'ABI ne fait pas de promesses sur la stabilité de son contenu qui pourrait varier en fonction de l'événement, du matériel ou de la version du noyau. bnr, lbr[bnr] Si PERF_SAMPLE_BRANCH_STACK est activé, alors une valeur de 64 bits indiquant le nombre d'enregistrements est in- cluse, suivie des structures bnr perf_branch_entry qui chacune contient les champs suivants. from Cela indique l’instruction source (qui pourrait ne pas être un branchement). to La cible de branchement. mispred La cible de branchement a été mal prédite. predicted La cible de branchement a été prédite. in_tx (depuis Linux 3.11) Le branchement était dans une transaction de mé- moire transactionnelle. abort (depuis Linux 3.11) Le branchement était dans une transaction aban- donnée de mémoire transactionnelle. cycles (depuis Linux 4.3) Cela rend compte du nombre de cycles qui se sont déroulés depuis la dernière mise à jour de la pile de branchement. Les entrées sont présentées dans l’ordre chronologique, de telle sorte que la première entrée a le branchement le plus récent. La prise en charge de mispred, predicted et cycles est facultative. En absence de prise en charge, les deux va- leurs seront 0. Le type de branchements enregistrés est indiqué par le champ branch_sample_type. abi, regs[weight(mask)] Si PERF_SAMPLE_REGS_USER est activé, alors les registres processeur utilisateur sont enregistrés. Le champ abi est parmi PERF_SAMPLE_REGS_ABI_NONE, PERF_SAMPLE_REGS_ABI_32 ou PERF_SAMPLE_REGS_ABI_64. Le champ regs est un tableau de registres processeur qui ont été indiqués par le champ attr sample_regs_user. Le nombre de valeurs est le nombre de bits définis dans le masque binaire sample_regs_user. size, data[size], dyn_size Si PERF_SAMPLE_STACK_USER est activé, la pile utilisa- teur est enregistrée. Cela peut être utilisé pour géné- rer les backtraces de la pile. size est la taille deman- dée par l’utilisateur dans sample_stack_user ou autre- ment la taille maximale d’enregistrement. data contient les données de pile (un contenu brut de la mémoire indi- quée par le pointeur de pile au moment de l'échantillon- nage). dyn_size est la quantité de données vraiment ren- voyée (peut être inférieure à size). Remarquez que dyn_size est omis si size vaut 0. weight Si PERF_SAMPLE_WEIGHT ou PERF_SAMPLE_WEIGHT_STRUCT sont activés, une valeur de 64 bits fournie par le matériel est enregistrée pour indiquer le coût de l’événement. Cela permet aux événements coûteux de ressortir plus clairement dans les profils. data_src Si PERF_SAMPLE_DATA_SRC est activé, alors une valeur de 64 bits est enregistrée, constituée des champs suivants. mem_op Type de code opération (opcode), une combinaison bit à bit de : PERF_MEM_OP_NA Non disponible PERF_MEM_OP_LOAD Instruction de chargement PERF_MEM_OP_STORE Instruction de stockage PERF_MEM_OP_PFETCH Prélecture PERF_MEM_OP_EXEC Code exécutable mem_lvl Niveau de hiérarchie de mémoire atteint ou raté, une combinaison bit à bit de ce qui suit, envoyés à gauche par PERF_MEM_LVL_SHIFT : PERF_MEM_LVL_NA Non disponible PERF_MEM_LVL_HIT Atteint PERF_MEM_LVL_MISS Raté PERF_MEM_LVL_L1 Cache de niveau 1 PERF_MEM_LVL_LFB Tampon de capacité PERF_MEM_LVL_L2 Cache de niveau 2 PERF_MEM_LVL_L3 Cache de niveau 3 PERF_MEM_LVL_LOC_RAM DRAM local PERF_MEM_LVL_REM_RAM1 DRAM distant 1 saut PERF_MEM_LVL_REM_RAM2 DRAM distant 2 sauts PERF_MEM_LVL_REM_CCE1 Cache distant 1 saut PERF_MEM_LVL_REM_CCE2 Cache distant 2 sauts PERF_MEM_LVL_IO Mémoire d'entrée et sortie. PERF_MEM_LVL_UNC Mémoire sans cache mem_snoop Mode espionnage, une combinaison bit-à-bit de ce qui suit, décalé vers la gauche par PERF_MEM_SNOOP_SHIFT : PERF_MEM_SNOOP_NA Non disponible PERF_MEM_SNOOP_NONE Pas d'espionnage PERF_MEM_SNOOP_HIT Espionnage atteint PERF_MEM_SNOOP_MISS Espionnage raté PERF_MEM_SNOOP_HITM Espionnage atteint modifié mem_lock Instruction de verrouillage, une combinaison bit à bit de ce qui suit, renvoyée vers la gauche par PERF_MEM_LOCK_SHIFT : PERF_MEM_LOCK_NA Non disponible PERF_MEM_LOCK_LOCKED Transaction verrouillée mem_dtlb Accès TLB atteint ou raté, une combinaison bit à bit de ce qui suit, renvoyée vers la gauche par PERF_MEM_TLB_SHIFT : PERF_MEM_TLB_NA Non disponible PERF_MEM_TLB_HIT Atteint PERF_MEM_TLB_MISS Raté PERF_MEM_TLB_L1 TLB de niveau 1 PERF_MEM_TLB_L2 TLB de niveau 2 PERF_MEM_TLB_WK Parcours matériel PERF_MEM_TLB_OS Gestionnaire d'erreur du SE transaction Si l’attribut PERF_SAMPLE_TRANSACTION est défini, alors un champ de 64 bits est enregistré pour décrire les sources de tous les abandons de mémoire transaction- nelle. Le champ est une combinaison bit à bit des valeurs sui- vantes : PERF_TXN_ELISION Abandon d’une transaction de type élision (spéci- fique aux processeurs Intel). PERF_TXN_TRANSACTION Abandon d’une transaction générique. PERF_TXN_SYNC Abandon synchrone (relatif à l’instruction signa- lée). PERF_TXN_ASYNC Abandon asynchrone (non relatif à l’instruction signalée). PERF_TXN_RETRY Abandon réessayable (réessayer la transaction pourrait réussir). PERF_TXN_CONFLICT Abandon à cause de conflits de mémoire avec d’autres threads. PERF_TXN_CAPACITY_WRITE Abandon à cause de dépassement de la capacité d’écriture. PERF_TXN_CAPACITY_READ Abandon à cause de dépassement de la capacité de lecture. De plus, un code d’abandon spécifique à l’utilisateur peut être obtenu à partir des premiers 32 bits du champ en déplaçant vers la droite avec PERF_TXN_ABORT_SHIFT et en masquant avec PERF_TXN_ABORT_MASK. abi, regs[weight(mask)] Si PERF_SAMPLE_REGS_INTR est activé, alors les registres processeur utilisateur sont enregistrés. Le champ abi est parmi PERF_SAMPLE_REGS_ABI_NONE, PERF_SAMPLE_REGS_ABI_32 ou PERF_SAMPLE_REGS_ABI_64. Le champ regs est un tableau des registres processeur qui ont été indiqués par le champ attr sample_regs_intr. Le nombre de valeurs est le nombre de bits définis dans le masque binaire sample_regs_intr. phys_addr Si l'attribut PERF_SAMPLE_PHYS_ADDR est positionné, l'adresse physique en 64 bits est enregistrée. cgroup Si l'attribut PERF_SAMPLE_CGROUP est positionné, l'iden- tifiant de cgroup 64 bits (pour le sous-système perf_event) est enregistré. Pour récupérer le chemin du cgroup, l'identifiant doit correspondre à un de ceux se trouvant dans PERF_RECORD_CGROUP. data_page_size Si l'attribut PERF_SAMPLE_DATA_PAGE_SIZE est positionné, la valeur en 64 bits de la taille de la page de l'adresse de data est enregistrée. code_page_size Si l'attribut PERF_SAMPLE_CODE_PAGE_SIZE est positionné, la valeur en 64 bits de la taille de la page de l'adresse ip est enregistrée. size data[size] Si PERF_SAMPLE_AUX est activé, alors un instantané du tampon aux est enregistré. PERF_RECORD_MMAP2 Cet enregistrement inclut des informations étendues sur les appels mmap(2) renvoyant des projections exécutables. Le format est identique à celui de l'enregistrement PERF_RE- CORD_MMAP mais il comprend des valeurs supplémentaires qui permettent uniquement d'identifier des projections parta- gées. Selon le bit PERF_RECORD_MISC_MMAP_BUILD_ID dans l'en-tête, les valeurs supplémentaires ont des présentations et des significations différentes. struct { struct perf_event_header header; u32 pid; u32 tid; u64 addr; u64 len; u64 pgoff; union { struct { u32 maj; u32 min; u64 ino; u64 ino_generation; }; struct { /* if PERF_RECORD_MISC_MMAP_BUILD_ID */ u8 build_id_size; u8 __reserved_1; u16 __reserved_2; u8 build_id[20]; }; }; u32 prot; u32 flags; char filename[]; struct sample_id sample_id; }; pid est l'identifiant de processus. tid est l'identifiant de thread. addr est l'adresse de la mémoire allouée. len est la taille de la mémoire allouée. pgoff est la position de la page de la mémoire allouée. maj est l'identifiant majeur du périphérique sous-jacent. min est l'identifiant mineur du périphérique sous-jacent. ino est le numéro d'inœud. ino_generation est la génération d'inœud. build_id_size est la taille réelle du champ build_id (jusqu'à 20). build_id ce sont des données brutes pour identifier un bi- naire. prot sont les informations de protection. drapeaux sont les informations d'attributs. filename est une chaîne décrivant la base de la mémoire al- louée. PERF_RECORD_AUX (depuis Linux 4.1) Cet enregistrement rend compte des nouvelles données dispo- nibles dans la zone séparée du tampon AUX. struct { struct perf_event_header header; u64 aux_offset; u64 aux_size; u64 flags; struct sample_id sample_id; }; aux_offset position dans la zone mmap AUX où commencent les nou- velles données. aux_size taille des données disponibles. drapeaux décrit la mise à jour AUX. PERF_AUX_FLAG_TRUNCATED s'il est positionné, les données renvoyées ont été tronquées pour rentrer dans la taille du tampon disponible. PERF_AUX_FLAG_OVERWRITE s'il est positionné, les données renvoyées ont écrasé des données précédentes. PERF_RECORD_ITRACE_START (depuis Linux 4.1) Cet enregistrement indique le processus qui a initié un évé- nement de traçage d'instruction, permettant aux outils de corréler correctement les adresses d'instruction du tampon AUX avec le bon exécutable. struct { struct perf_event_header header; u32 pid; u32 tid; }; pid identifiant de processus du thread ayant commencé un traçage d'instruction. tid identifiant du thread ayant commencé le traçage d'instruction. PERF_RECORD_LOST_SAMPLES (depuis Linux 4.2) Lors de l'utilisation de l'échantillonnage matériel (comme les PEBS d'Intel), cet enregistrement indique le nombre d'échantillons qui peuvent avoir été perdus. struct { struct perf_event_header header; u64 lost; struct sample_id sample_id; }; lost est le nombre d'échantillons potentiellement perdus. PERF_RECORD_SWITCH (depuis Linux 4.3) Cet enregistrement indique qu'un changement de contexte a eu lieu. Le bit PERF_RECORD_MISC_SWITCH_OUT du champ misc in- dique si ce changement s'est fait dans ou hors du processus. struct { struct perf_event_header header; struct sample_id sample_id; }; PERF_RECORD_SWITCH_CPU_WIDE (depuis Linux 4.3) Comme avec PERF_RECORD_SWITCH, cet enregistrement indique qu'un changement de contexte a eu lieu mais il n'arrive que lors de l'échantillonnage en mode processeur complet et il fournit des informations supplémentaires sur le processus faisant l'objet du changement. Le bit PERF_RE- CORD_MISC_SWITCH_OUT du champ misc indique si le changement a eu lieu dans ou hors du processus actuel. struct { struct perf_event_header header; u32 next_prev_pid; u32 next_prev_tid; struct sample_id sample_id; }; next_prev_pid L'identifiant du processus précédent ou suivant (se- lon le sens du changement) sur le processeur. next_prev_tid L'identifiant du thread précédent ou suivant (selon le sens du changement) sur le processeur. PERF_RECORD_NAMESPACES (depuis Linux 4.11) Cet enregistrement comprend diverses informations sur l'es- pace de noms d'un processus. struct { struct perf_event_header header; u32 pid; u32 tid; u64 nr_namespaces; struct { u64 dev, inode } [nr_namespaces]; struct sample_id sample_id; }; pid est l'identifiant de processus. tid est l'identifiant de thread. nr_namespace est le nombre d'espaces de noms de cet enregistre- ment. Chaque espace de noms a des champs dev et inode et il est enregistré dans une position fixe comme celle ci-dessous : NET_NS_INDEX=0 espace de noms réseau UTS_NS_INDEX=1 espace de noms UTS IPC_NS_INDEX=2 espace de noms IPC PID_NS_INDEX=3 espace de noms PID USER_NS_INDEX=4 espace de noms utilisateur MNT_NS_INDEX=5 Espace de noms de montage CGROUP_NS_INDEX=6 espace de noms de groupe de contrôle PERF_RECORD_KSYMBOL (depuis Linux 5.0) Cet enregistrement indique un événement d'enregistre- ment/désenregistrement des symboles du noyau. struct { struct perf_event_header header; u64 addr; u32 len; u16 ksym_type; u16 flags; char name[]; struct sample_id sample_id; }; addr est l'adresse du symbole du noyau. len est la taille du symbole du noyau. ksym_type est le type de symbole du noyau. Actuellement, les types suivants sont disponibles : PERF_RECORD_KSYMBOL_TYPE_BPF Le symbole du noyau est une fonction BPF. drapeaux Si PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER est posi- tionné, cet événement se produit lors du désenregis- trement d'un symbole du noyau. PERF_RECORD_BPF_EVENT (depuis Linux 5.0) Cet enregistrement indique si un programme BPF est chargé ou déchargé. struct { struct perf_event_header header; u16 type; u16 flags; u32 id; u8 tag[BPF_TAG_SIZE]; struct sample_id sample_id; }; type est une des valeurs suivantes : PERF_BPF_EVENT_PROG_LOAD Un programme BPF est chargé. PERF_BPF_EVENT_PROG_UNLOAD Un programme BPF est déchargé id est l'identifiant du programme BPF. tag est l'étiquette du programme BPF. Actuellement, BPF_TAG_SIZE est défini à 8. PERF_RECORD_CGROUP (depuis Linux 5.7) Cet enregistrement indique si un cgroup est créé et activé. struct { struct perf_event_header header; u64 id; char path[]; struct sample_id sample_id; }; id est l'identifiant du cgroup. Il peut aussi être récu- péré à l'aide de name_to_handle_at(2) sur le chemin du cgroup (en tant que gestion de fichier). path est le chemin du cgroup depuis la racine. PERF_RECORD_TEXT_POKE (depuis Linux 5.8) Cet enregistrement indique une modification dans le texte du noyau. Cela comprend les ajouts et les suppressions de texte et la taille correspondante est de zéro dans ce cas. struct { struct perf_event_header header; u64 addr; u16 old_len; u16 new_len; u8 bytes[]; struct sample_id sample_id; }; addr est l'adresse de la modification. old_len est l'ancienne taille. new_len est la nouvelle taille. bytes contient les anciens octets immédiatement suivis des nouveaux. Gestion du dépassement Des événements peuvent être positionnés pour signaler quand on dépasse une limite, indiquant un dépassement. Les conditions d'un dépassement peuvent être récupérées avec poll(2), select(2) ou epoll(7). Alternati- vement, les évènements de dépassement peuvent être capturés à l'aide d'un gestionnaire de signal en activant les signaux d'E/S sur le des- cripteur de fichier ; voir le point sur les opérations F_SETOWN et F_SETSIG dans fcntl(2). Les débordements ne sont générés que par les événements d'échantillon- nage (sample_period doit avoir une valeur non nulle). Deux façons permettent de générer des notifications de débordement. La première est de paramétrer une valeur wakeup_events ou wakeup_water- mark qui générera un signal si un certain nombre d'échantillons ou d'octets ont été écrits dans le tampon circulaire mmap. Dans ce cas, un signal de type POLL_IN est envoyé. L'autre façon est d'utiliser l'ioctl PERF_EVENT_IOC_REFRESH. Cet ioctl ajoute à un compteur qui décrémente à chaque fois que l'événement dé- passe. Quand il est non nul, un signal POLL_IN est envoyé en cas de dé- passement, mais une fois que la valeur a atteint 0, un signal de type POLL_HUP est envoyé et l'événement sous-jacent est désactivé. Le rafraîchissement d'un leader de groupe d'événements rafraîchit toute la fratrie, et un rafraîchissement avec un paramètre de 0 active un ra- fraîchissement infini. Ces comportements ne sont pas gérés et ne de- vraient pas être utilisés. À partir de Linux 3.18, POLL_HUP est initié si l'événement à surveiller est rattaché à un processus différent et que celui-ci se termine. Instruction rdpmc À partir de Linux 3.4 sur x86, l'instruction rdpmc permet d'obtenir des lectures à faible latence sans avoir à entrer dans le noyau. Remarquez que l'utilisation de rdpmc n'est pas nécessairement plus rapide que d'autres méthodes pour lire des valeurs d'événement. Cette prise en charge peut être détectée avec le champ cap_usr_rdpmc dans la page mmap ; de la documentation pour calculer les valeurs d'événement est disponible dans cette section. À l'origine, quand la prise en charge de rdpmc a été activée, tout pro- cessus (pas seulement ceux ayant un événement perf actif) pouvait uti- liser l'instruction rdpmc pour accéder aux compteurs. À partir de Li- nux 4.0, la prise en charge de rdpmc n'est autorisée que si un événe- ment est actuellement activé dans le contexte d'un processus. Pour res- taurer l'ancien comportement, inscrivez la valeur 2 dans /sys/de- vices/cpu/rdpmc. Appels ioctl perf_event Plusieurs ioctls agissent sur les descripteurs de fichier de perf_event_open(). PERF_EVENT_IOC_ENABLE Cela active l'événement individuel ou le groupe d'événements in- diqué par l'argument de descripteur de fichier. Si le bit PERF_IOC_FLAG_GROUP est défini dans l’argument ioctl, alors tous les événements d’un groupe sont activés, même si l’événement indiqué n’est pas le leader de groupe (mais consul- tez la section BOGUES). PERF_EVENT_IOC_DISABLE Cela désactive le compteur individuel ou le groupe d'événements indiqué par l'argument de descripteur de fichier. L'activation ou la désactivation du leader d'un groupe active ou désactive la totalité du groupe. Autrement dit pendant que le leader de groupe est désactivé, aucun des compteurs du groupe ne compte. L'activation ou la désactivation d'un membre du groupe qui n'est pas le leader arrête ce son compteur, mais n'affecte aucun des autres compteurs. Si le bit PERF_IOC_FLAG_GROUP est défini dans l’argument ioctl, alors tous les événements d’un groupe sont désactivés, même si l’événement indiqué n’est pas le leader de groupe (mais consul- tez la section BOGUES). PERF_EVENT_IOC_REFRESH Les compteurs de dépassements non hérités peuvent utiliser cela pour activer un compteur pour un nombre de dépassements indiqué par l'argument, après lequel il est désactivé. Les appels sui- vants de cet ioctl ajoutent la valeur de l'argument au décompte actuel. Un signal avec POLL_IN défini est envoyé à chaque dépas- sement jusqu'à ce que ce compte atteigne 0 ; quand cela arrive, un signal avec POLL_HUP défini est envoyé et l'événement est désactivé. L'utilisation de 0 comme argument est considéré comme un comportement indéfini. PERF_EVENT_IOC_RESET Redéfinir le compte d'événements indiqué par l'argument à zéro. Cela ne réinitialise que les décomptes ; réinitialiser les va- leurs de multiplexage time_enabled et time_running est impos- sible. Si le bit PERF_IOC_FLAG_GROUP est défini dans l’argument ioctl, alors tous les événements d’un groupe sont réinitialisés, même si l’événement indiqué n’est pas le leader de groupe (mais consultez la section BOGUES). PERF_EVENT_IOC_PERIOD Cela met à jour la période de dépassement pour l’événement. Depuis Linux 3.7 (sur ARM) et Linux 3.14 (toutes les autres ar- chitectures), la nouvelle période est effective immédiatement. Sur les noyaux précédents, la nouvelle période n’était effective qu’après le dépassement suivant. L'argument est un pointeur vers une valeur sur 64 bits contenant la nouvelle période voulue. Avant Linux 2.6.36, cet ioctl échouait toujours à cause d’un bogue dans le noyau. PERF_EVENT_IOC_SET_OUTPUT Cela indique au noyau de signaler les notifications d'événement dans le descripteur de fichier indiqué plutôt que dans celui par défaut. Les descripteurs de fichier doivent tous être sur le même processeur. L'argument indique le descripteur de fichier désiré ou -1 si la sortie devrait être ignorée. PERF_EVENT_IOC_SET_FILTER (depuis Linux 2.6.33) Cela ajoute un filtre ftrace à cet événement. L'argument est un pointeur vers le filtre ftrace voulu. PERF_EVENT_IOC_ID (depuis Linux 3.12) Cela renvoie la valeur d’identifiant de l’événement pour le des- cripteur de fichier d’événement donné. L'argument est un pointeur vers un entier non signé de 64 bits pour garder le résultat. PERF_EVENT_IOC_SET_BPF (depuis Linux 4.1) Cela permet de rattacher un programme Berkeley Packet Filter (BPF) à un événement de traçage d'un kprobe existant. Vous avez besoin des privilèges CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN pour utiliser cet ioctl. Le paramètre est un descripteur de fichier de programme BPF créé par un appel système bpf(2) précédent. PERF_EVENT_IOC_PAUSE_OUTPUT (depuis Linux 4.7) Cela permet de mettre en pause et de relancer le tampon circu- laire d'un événement. Un tampon mis en pause n'empêche pas la génération d'échantillons mais il les désactive. Les échan- tillons désactivés sont considérés comme perdus et provoquent la génération d'un PERF_RECORD_LOST si possible. Un signal de dé- passement peut toujours être récupéré par l'échantillon désac- tivé bien que le tampon circulaire reste vide. Le paramètre est un entier 32 bits non signé. Une valeur autre que zéro met en pause le tampon circulaire alors qu'une valeur de zéro réactive le tampon circulaire. PERF_EVENT_MODIFY_ATTRIBUTES (depuis Linux 4.17) Cela permet de modifier un événement existant sans le gaspillage de fermeture et réouverture d’un nouvel événement. Actuellement, cela n'est pris en charge que pour les événements de points d'arrêt. L'argument est un pointeur vers une structure perf_event_attr contenant les paramètres de l'événement mis à jour. PERF_EVENT_IOC_QUERY_BPF (depuis Linux 4.16) Cela permet de chercher les programmes Berkeley Packet Filter (BPF) rattachés à un point de traçage kprobe existant. Vous ne pouvez rattacher qu'un programme BPF par événement mais vous pouvez avoir plusieurs événements rattachés à un point de tra- çage. Rechercher cette valeur sur un événement de point de tra- çage renvoie l'identifiant de tous les programmes BPF dans tous les événements rattachés au point de traçage. Il vous faut les privilèges CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN pour utiliser cet ioctl. L'argument est un pointeur vers une structure struct perf_event_query_bpf { __u32 ids_len; __u32 prog_cnt; __u32 ids[0]; }; Le champ ids_len indique le nombre d'identifiants pouvant entrer dans le tableau ids fourni. La valeur prog_cnt est remplie par le noyau avec le nombre de programmes BPF rattachés. Le tableau ids est rempli par l'identifiant de chaque programme BPF ratta- ché. S'il y a plus de programmes que de place dans le tableau, le noyau renverra ENOSPC et ids_len indiquera le nombre d'iden- tifiants de programme copiés avec succès. Utilisation de prctl(2) Un processus peut activer ou désactiver tous les groupes d'événements actuellement ouverts en utilisant les opérations PR_TASK_PERF_EVENTS_ENABLE et PR_TASK_PERF_EVENTS_DISABLE de prctl(2). Cela ne s'applique qu'aux événements créés localement par le processus appelant. Cela ne s'applique pas aux événements créés par d'autres pro- cessus rattachés au processus appelant ou aux événements d'un processus parent. Cela n'active et désactive que les leaders de groupe, aucun autre des membres des groupes. Fichiers de configuration relatifs à perf_event Fichiers de /proc/sys/kernel/ /proc/sys/kernel/perf_event_paranoid Le fichier perf_event_paranoid peut être défini pour res- treindre l'accès aux compteurs de performance : 2 ne permettre que les mesures en espace utilisateur (par défaut depuis Linux 4.6). 1 permettre à la fois les mesures noyau et utilisateur (par défaut avant Linux 4.6). 0 permettre l'accès aux données spécifiques au proces- seur sauf les échantillons de point de trace bruts ; -1 pas de restriction. L'existence du fichier perf_event_paranoid est la méthode officielle pour déterminer si un noyau gère perf_event_open(). /proc/sys/kernel/perf_event_max_sample_rate Cela définit le taux d'échantillonnage maximal. Un réglage trop haut peut permettre aux utilisateurs d'échantillonner à un taux ayant un impact sur les performances de la machine et éventuellement planter la machine. La valeur par défaut est 100 000 (échantillons par seconde). /proc/sys/kernel/perf_event_max_stack Ce fichier définit la profondeur maximale des entrées de trame de pile signalées lors de la génération d'une trace. /proc/sys/kernel/perf_event_mlock_kb Le nombre maximal de pages qu'un utilisateur sans droit peut verrouiller avec mlock(2). La valeur par défaut est 516 (ko). Fichiers de /sys/bus/event_source/devices/ Depuis Linux 2.6.34, le noyau permet d'avoir plusieurs PMU dispo- nibles pour la surveillance. Les informations sur la façon de pro- grammer ces PMU sont disponibles dans /sys/bus/event_source/de- vices/. Tous les sous-répertoires correspondent à une PMU diffé- rente. /sys/bus/event_source/devices/*/type (depuis Linux 2.6.38) Cela contient un entier qui peut être utilisé dans le champ type de perf_event_attr pour indiquer la volonté d'utiliser cette PMU. /sys/bus/event_source/devices/cpu/rdpmc (depuis Linux 3.4) Si ce fichier est 1, alors l’accès direct de l’espace utili- sateur aux registres de compteurs de performance est permis à l’aide de l’instruction rdpmc. Cela peut être désactivé en écrivant 0 dans le fichier. À partir de Linux 4.0, le comportement a changé pour que 1 n'autorise désormais que l'accès aux processus ayant des événements perf actifs et que 2 indique l'ancien comporte- ment autorisant l'accès à n'importe quoi. /sys/bus/event_source/devices/*/format/ (depuis Linux 3.4) Ce sous-répertoire contient des renseignements sur les sous-champs spécifiques à l’architecture disponibles pour la programmation des divers champs config de la structure perf_event_attr. Le contenu de chaque fichier est le nom du champ de configu- ration, suivi d’un deux-points, suivi d’une suite d’inter- valles d’entiers séparés par des virgules. Par exemple, le fichier event pourrait contenir la valeur config1:1,6-10,44 qui indique que l’événement est un attribut qui occupe les bits 1, 6 à 10 et 44 de perf_event_attr::config1. /sys/bus/event_source/devices/*/events/ (depuis Linux 3.4) Ce sous-répertoire contient des fichiers avec des événements prédéfinis. Les contenus sont des chaînes décrivant les ré- glages d'événements exprimés en termes des champs trouvés dans le répertoire ./format/ mentionné précédemment. Ce ne sont pas nécessairement des listes complètes de tous les évènements pris en charge par une PMU, mais généralement un sous-ensemble d'événements jugés utiles ou intéressants. Le contenu de chaque fichier est une liste de noms d’attri- but séparés par des virgules. Chaque entrée a une valeur fa- cultative (soit hexadécimale, soit décimale). Si aucune va- leur n’est indiquée, alors un champ d’un seul bit de valeur 1 est supposé. Un exemple d’entrée pourrait ressembler à event=0x2,inv,ldlat=3. /sys/bus/event_source/devices/*/uevent Ce fichier est l’interface standard de périphérique du noyau pour l’injection d’événements de branchement à chaud. /sys/bus/event_source/devices/*/cpumask (depuis Linux 3.7) Le fichier cpumask contient une liste d’entiers séparés par des virgules indiquant un numéro représentatif de processeur pour chaque socket (boîtier) de la carte mère. C’est néces- saire lors de la définition d’événements uncore ou north- bridge, puisque ces PMU présentent des événements à travers tous les sockets. VALEUR RENVOYÉE En cas de succès, perf_event_open() renvoie le nouveau descripteur de fichier. En cas d'échec, -1 est renvoyé et errno est défini pour indi- quer l'erreur. ERREURS Les erreurs renvoyées par perf_event_open() peuvent être incohérentes et peuvent varier suivant les architectures de processeur et les unités de surveillance des performances. E2BIG Renvoyé si la valeur size de perf_event_attr est trop petite (plus petite que PERF_ATTR_SIZE_VER0), trop grande (plus grande que la taille de page) ou plus grande que ce que le noyau peut gérer et que les octets supplémentaires ne sont pas zéro. Lorsque E2BIG est renvoyé, le champ size de perf_event_attr est remplacé, par le noyau, par la taille attendue de la structure. EACCES Renvoyé quand l’événement demandé nécessite les droits CAP_PERF- MON (depuis Linux 5.8) ou CAP_SYS_ADMIN (ou un réglage para- noïaque de perf_event plus permissif). Quelques cas habituels où un processus non privilégié pourrait tomber sur cette erreur : l’attachement à un processus appartenant à un autre utilisateur, la surveillance de tous les processus sur un processeur donné (c’est-à-dire en indiquant -1 pour l’argument pid) et l’absence de réglage exclude_kernel quand le réglage paranoïaque le néces- site. EBADF Renvoyé si le descripteur de fichier group_fd n’est pas valable, ou, si PERF_FLAG_PID_CGROUP est défini, si le descripteur de fi- chier cgroup dans pid n’est pas valable. EBUSY (depuis Linux 4.1) Renvoyé si un événement a déjà un accès exclusif à la PMU. EFAULT Renvoyé si le pointeur attr pointe vers un adresse de mémoire non valable. EINTR Renvoyé si on essaie de mélanger la gestion de perf et de ftrace pour un uprobe. EINVAL Renvoyé si l’événement indiqué n’est pas valable. De nombreuse raisons sont possibles pour cela. Une liste non exhaustive : sample_freq est plus grand que le réglage maximal ; le cpu à surveiller n’existe pas ; read_format est hors intervalle ; sample_type est hors intervalle ; la valeur flags est hors in- tervalle ; exclusive ou pinned sont définis et l’événement n’est pas un leader de groupe ; les valeurs config de l’événement sont hors de l’intervalle ou des bits réservés définis ; l’événement générique sélectionné n’est pas pris en charge ; la place est insuffisante pour ajouter l’événement sélectionné. EMFILE Chaque événement ouvert utilise un descripteur de fichier. Si un grand nombre d’événements est ouvert, la limite de descripteurs de fichier par processus sera atteinte et aucun événement sup- plémentaire ne pourra être créé. ENODEV Renvoyé quand l’événement implique une fonctionnalité non prise en charge par le processeur actuel. ENOENT Renvoyé si le réglage type n’est pas valable. Cette erreur est également renvoyée pour certains événements génériques non pris en charge. ENOSPC Avant Linux 3.3, s'il manquait de la place pour l'événement, EN- OSPC était renvoyé. Dans Linux 3.3, cela a été modifié en EIN- VAL. ENOSPC est toujours renvoyé en cas de tentative d’ajout de plus d’événements de point d'arrêt que permis par le matériel. ENOSYS Renvoyé si PERF_SAMPLE_STACK_USER est défini dans sample_type et que ce n’est pas pris en charge par le matériel. EOPNOTSUPP Renvoyé si un événement nécessitant une fonctionnalité spéci- fique du matériel est demandé alors qu’il n’y a pas de prise en charge matérielle. Cela comprend la demande d’événement à faible dérapage si ce n’est pas pris en charge, le suivi de branchement s’il n’est pas pris en charge, l’échantillonnage si aucune in- terruption PMU n’est disponible et les piles de branchement pour les événements logiciels. EOVERFLOW (depuis Linux 4.8) Renvoyé si PERF_SAMPLE_CALLCHAIN est demandé et si sample_max_stack est plus grand que le maximum indiqué dans /proc/sys/kernel/perf_event_max_stack. EPERM Renvoyé sur beaucoup d’architectures (mais pas toutes) quand un des réglages exclude_hv, exclude_idle, exclude_user ou ex- clude_kernel non pris en charge est indiqué. Cela peut aussi arriver, comme avec EACCES, quand l’événement demandé nécessite les droits CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN (ou un réglage paranoïaque de perf_event plus per- missif). Cela comprend le réglage d’un point d'arrêt sur une adresse du noyau et (depuis Linux 3.13) le réglage d’un point de trace de fonction du noyau. ESRCH Renvoyé en cas de tentative d’attachement à un processus qui n’existe pas. VERSIONS perf_event_open() a été introduite dans Linux 2.6.31 mais était appelée perf_counter_open(). Elle a été renommée dans Linux 2.6.32. STANDARDS Cet appel système perf_event_open() est spécifique à Linux et ne de- vrait pas être employé dans des programmes destinés à être portables. NOTES Le moyen officiel pour savoir si la prise en charge de perf_event_open() est activée est de vérifier si le fichier /proc/sys/kernel/perf_event_paranoid existe. La capacité CAP_PERFMON (depuis Linux 5.58) fournit une approche sécu- risée de la surveillance des performances et des opérations de visibi- lité d'un système suivant un principe du moindre privilège (POSIX IEEE 1003.1e). Ces modalités d'accès qui utilisent CAP_PERFMON au lieu du beaucoup plus puissant CAP_SYS_ADMIN enlève des chances d'une mauvaise utilisation des droits et rend les opérations plus sécurisées. L'utili- sation de CAP_SYS_ADMIN pour la surveillance sécurisée des performances du système et une meilleure visibilité est déconseillée et vous devriez préférer la capacité CAP_PERFMON. BOGUES L'option F_SETOWN_EX de fcntl(2) est nécessaire pour obtenir correcte- ment les signaux de dépassement dans les threads. Cela a été introduit dans Linux 2.6.32. Avant Linux 3.3 (en tout cas pour x86), le noyau ne vérifiait pas si les événements pouvaient être programmés ensemble avant le moment de la lecture. La même chose arrive sur tous les noyaux connus si le watchdog NMI est activé. Cela signifie que pour voir si un ensemble donné d'évé- nements fonctionne, il faut appeler perf_event_open(), démarrer, puis lire avant d'être sûr de pouvoir obtenir des mesures valables. Avant Linux 2.6.34, les contraintes d'événements n'étaient pas renfor- cées par le noyau. Dans ce cas, certains événements renverraient « 0 » silencieusement si le noyau les avait programmés dans un emplacement de compteur incorrect. Avant Linux 2.6.34, à cause d'un bogue lors du multiplexage, de mauvais résultats pouvaient être renvoyés. Les noyaux de Linux 2.6.35 à Linux 2.6.39 peuvent planter rapidement si inherit est activé et que de nombreux threads sont démarrés. Avant Linux 2.6.35, PERF_FORMAT_GROUP ne fonctionnait pas avec les pro- cessus attachés. À cause d'un bogue dans le code du noyau entre Linux 2.6.36 et Li- nux 3.0, le champ watermark était ignoré et agissait comme si wa- keup_event avait été choisi si l'union contenait une valeur non nulle. De Linux 2.6.31 à Linux 3.4, l’argument ioctl PERF_IOC_FLAG_GROUP était cassé et opérait à répétition sur l’événement indiqué au lieu d’itérer parmi tous les événements d’une fratrie d’un groupe. De Linux 3.4 à Linux 3.11, les bits mmap cap_usr_rdpmc et cap_usr_time étaient associés au même emplacement. Le code devrait plutôt être modi- fié pour utiliser les nouveaux champs cap_user_rdpmc et cap_user_time à la place. Vérifiez toujours deux fois les résultats. Plusieurs événements généra- lisés ont eu de fausses valeurs. Par exemple, les branchements retirés ne mesuraient pas la bonne chose sur les machines AMD jusqu'au noyau 2.6.35. EXEMPLES Ce qui suit est un court exemple qui mesure le décompte total d'ins- tructions d'un appel à printf(3). #include <linux/perf_event.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/syscall.h> #include <unistd.h> static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) { int ret; ret = syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); return ret; } int main(void) { int fd; long long count; struct perf_event_attr pe; memset(&pe, 0, sizeof(pe)); pe.type = PERF_TYPE_HARDWARE; pe.size = sizeof(pe); pe.config = PERF_COUNT_HW_INSTRUCTIONS; pe.disabled = 1; pe.exclude_kernel = 1; pe.exclude_hv = 1; fd = perf_event_open(&pe, 0, -1, -1, 0); if (fd == -1) { fprintf(stderr, "Erreur d'ouverture du leader %llx\n", pe.config); exit(EXIT_FAILURE); } ioctl(fd, PERF_EVENT_IOC_RESET, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); printf("Mesure du décompte d'instructions pour ce printf\n"); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(count)); printf("%lld instructions utilisées\n", count); close(fd); } VOIR AUSSI perf(1), fcntl(2), mmap(2), open(2), prctl(2), read(2) Documentation/admin-guide/perf-security.rst dans l'arborescence des sources du noyau TRADUCTION La traduction française de cette page de manuel a été créée par Chris- tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <ste- phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran- çois Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Gué- rard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.cou- lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centra- liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <si- mon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@de- bian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩. Pages du manuel de Linux 6.03 10 février 2023 perf_event_open(2)
Generated by dwww version 1.15 on Sat Jun 29 01:50:36 CEST 2024.