perf_event_open(2) System Calls Manual perf_event_open(2) NOM perf_event_open - Definir la surveillance des performances BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include /* Definition des constantes PERF_* */ #include /* Definition des constantes HW_* */ #include /* Definition des constantes SYS_* */ #include 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 A partir d'une liste de parametres, perf_event_open() renvoie un descripteur de fichier, pour une utilisation dans les appels systeme suivants (read(2), mmap(2), prctl(2), fcntl(2), etc.). Un appel de perf_event_open() cree un descripteur de fichier qui permet de mesurer les renseignements de performance. Tous les descripteurs de fichier correspondent chacun a un evenement mesure ; ils peuvent etre regroupes pour mesurer plusieurs evenements simultanement. Les evenements peuvent etre actives et desactives de deux facons : a l'aide de ioctl(2) ou de prctl(2). Quand un evenement est desactive, il ne decompte ni ne genere de depassement, mais continue vraiment d'exister et maintient sa valeur de decompte. Les evenements sont de deux types : comptage et echantillonnage. Un evenement de comptage sert a comptabiliser le nombre total d'evenements qui se produisent. En general, les resultats d'un evenement de comptage sont recueillis avec un appel read(2). Un evenement d'echantillonnage ecrit periodiquement les mesures dans un tampon qui peut ensuite etre accede a l'aide de mmap(2). Arguments Les arguments pid et cpu permettent d'indiquer le processus et le processeur a surveiller : pid == 0 et cpu == -1 Cela mesure le processus ou thread appelant sur tous les processeurs. pid == 0 et cpu >= 0 Cela ne mesure le processus ou thread appelant que s'il est en cours d'execution sur le processeur indique. pid > 0 et cpu == -1 Cela mesure le processus ou thread indique sur tous les processeurs. pid > 0 et cpu >= 0 Cela ne mesure le processus ou thread indique que s'il est en cours d'execution sur le processeur indique. pid == -1 et cpu >= 0 Cela mesure tous les processus et threads du processeur indique. Cela necessite la capacite CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN ou une valeur /proc/sys/kernel/perf_event_paranoid strictement inferieure a 1. pid == -1 et cpu == -1 Ce reglage est incorrect et renverra une erreur. Quand pid est superieur a zero, le droit d'effectuer cet appel systeme est gere par CAP_PERFMON (depuis Linux 5.9) et une verification PTRACE_MODE_READ_REALCREDS du mode d'acces ptrace sur les anciennes versions du noyau ; voir ptrace(2). L'argument group_fd permet aux groupes d'evenements d'etre crees. Un groupe d'evenements a un evenement qui est le leader de groupe. Le leader est d'abord cree avec group_fd = -1. Les autres membres du groupe sont crees par les appels perf_event_open() suivants, avec group_fd defini au descripteur de fichier du leader de groupe (un evenement unique cree avec group_fd = -1 est considere comme formant un groupe d'un seul membre). Un evenement de groupe est programme dans le processeur comme un bloc : il ne sera mis dans le processeur que si tous les evenements du groupe peuvent etre mis dans le processeur. Cela veut dire que les valeurs des evenements de tous les membres peuvent etre comparees -- ajoutees, divisees (pour obtenir des rapports), etc. -- ensemble de maniere significative, puisqu'elles ont compte les evenements pendant les memes instructions executees. L'argument flags est constitue 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 descripteur de fichier de l'evenement cree, de telle sorte que le descripteur de fichier est automatiquement ferme par execve(2). L'attribution de << close-on-exec >> au moment de la creation, plutot qu'ensuite avec fcntl(2), evite de potentielles situations de competition ou le thread appelant invoque perf_event_open() et fcntl() en meme temps qu'un autre thread appelle fork(2) puis execve(2). PERF_FLAG_FD_NO_GROUP Cet attribut dit a l'evenement d'ignorer le parametre group_fd, sauf pour initialiser la redirection de la sortie en utilisant l'attribut PERF_FLAG_FD_OUTPUT. PERF_FLAG_FD_OUTPUT (casse depuis Linux 2.6.35) Cet attribut redirige la sortie echantillonnee de l'evenement vers le tampon mmap de l'evenement indique par group_fd. PERF_FLAG_PID_CGROUP (depuis Linux 2.6.39) Cet attribut active la surveillance par conteneur sur tout le systeme. Un conteneur est une abstraction qui isole un ensemble de ressources a controler plus finement (processeurs, memoire, etc.). Dans ce mode, l'evenement n'est mesure que si le thread execute sur le processeur surveille appartient au conteneur designe (cgroup). Le cgroup est identifie en passant un fichier au descripteur de fichier ouvert sur son repertoire dans le systeme de fichiers cgroupfs. Par exemple, si le cgroup a surveiller est appele test, alors un descripteur de fichier ouvert sur /dev/cgroup/test (en supposant que cgroupfs est monte sur /dev/cgroup) doit etre passe au parametre pid. La surveillance de cgroup n'est disponible que pour les evenements sur tout le systeme et pourrait donc necessiter des droits supplementaires. La structure perf_event_attr fournit des renseignements de configuration detailles pour les evenements en cours de creation. struct perf_event_attr { __u32 type; /* Type d'evenement */ __u32 size; /* Taille de la structure d'attributs */ __u64 config; /* Configuration specifique au type */ union { __u64 sample_period; /* Periode d'echantillonnage */ __u64 sample_freq; /* Frequence d'echantillonnage */ }; __u64 sample_type; /* Indique les valeurs incluses dans l'echantillon */ __u64 read_format; /* Indique les valeurs renvoyees en lecture */ __u64 disabled : 1, /* desactive par defaut */ inherit : 1, /* les enfants en heritent */ pinned : 1, /* doit toujours etre 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 donnees mmap */ comm : 1, /* inclure les donnees comm */ freq : 1, /* utiliser la frequence, pas la periode */ inherit_stat : 1, /* decomptes par tache */ enable_on_exec : 1, /* prochain exec active */ task : 1, /* tracer la creation d'enfant et la fin */ watermark : 1, /* wakeup_watermark */ precise_ip : 2, /* contrainte de derapage */ mmap_data : 1, /* donnees mmap non executees */ sample_id_all : 1, /* tous les evenements sample_type */ exclude_host : 1, /* ne pas compter dans l'hote */ exclude_guest : 1, /* ne pas compter dans l'invite */ exclude_callchain_kernel : 1, /* exclure les appels en chaine du noyau */ exclude_callchain_user : 1, /* exclure les appels en chaine d'utilisateur */ mmap2 : 1, /* inclure mmap avec les donnees d'inoeud */ comm_exec : 1, /* evenements flag comm devant etre executes */ use_clockid : 1, /* utiliser clockid pour les champs de temps */ context_switch : 1, /* donnees de changement de contexte */ write_backward : 1, /* Ecrire le tampon circulaire de la fin vers le debut */ namespaces : 1, /* inclure les donnees des espaces de noms */ ksymbol : 1, /* inclure les evenements ksymbol */ bpf_event : 1, /* inclure les evenements BPF */ aux_output : 1, /* generer les enregistrements AUX au lieu des evenements */ cgroup : 1, /* inclure les evenements cgroup */ text_poke : 1, /* inclure les evenements de poke de texte */ build_id : 1, /* utiliser build id dans les evenements mmap2 */ inherit_thread : 1, /* seuls les enfants en heritent */ /* si clone avec CLONE_THREAD */ remove_on_exec : 1, /* l'evenement est supprime des taches a l'execution */ sigtrap : 1, /* envoyer un SIGTRAP synchrone lors d'un evenement */ __reserved_1 : 26; union { __u32 wakeup_events; /* reveil tous les n evenements */ __u32 wakeup_watermark; /* octets avant le reveil */ }; __u32 bp_type; /* type de point d'arret */ union { __u64 bp_addr; /* adresse de point d'arret */ __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'arret */ __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 a renvoyer dans les echantillons */ __u32 sample_stack_user; /* taille de pile a renvoyer dans les echantillons */ __s32 clockid; /* horloge a utiliser pour les champs de temps */ __u64 sample_regs_intr; /* registres a renvoyer dans les echantillons */ __u32 aux_watermark; /* octets supp. avant le reveil */ __u16 sample_max_stack; /* nombre maximal de trames dans la chaine d'appel */ __u32 __reserved_2; /* aligner sur u64 */ __u32 aux_sample_size; /* taille maximale d'echantillon aux */ __u32 __reserved_3; /* aligner sur u64 */ __u64 sig_data; /* donnees utilisateur pour sigtrap */ }; Les champs de la structure perf_event_attr sont decrits en detail ci-dessous. type Ce champ indique le type d'evenement dans son ensemble. Il a une des valeurs suivantes : PERF_TYPE_HARDWARE Cela indique un des evenements materiels << generalises >> fournis par le noyau. Consultez la definition du champ config pour plus de precisions. PERF_TYPE_SOFTWARE Cela indique un des evenements logiciels fournis par le noyau (meme si aucune prise en charge materielle n'est disponible). PERF_TYPE_TRACEPOINT Cela indique un point de trace fourni par l'infrastructure de point de trace du noyau. PERF_TYPE_HW_CACHE Cela indique un evenement de cache materiel. Cela a un encodage particulier decrit dans la definition du champ config. PERF_TYPE_RAW Cela indique un evenement << brut >> specifique a l'implementation dans le champ config. PERF_TYPE_BREAKPOINT (depuis Linux 2.6.33) Cela indique un point d'arret materiel tel que fourni par le processeur. Les points d'arret peuvent etre des acces en lecture ou ecriture sur une adresse ainsi que l'execution d'une adresse d'instruction. PMU dynamique Depuis Linux 2.6.38, perf_event_open() permet de gerer plusieurs PMU. Pour activer cela, une valeur exportee par le noyau peut etre utilisee dans le champ type pour indiquer la PMU a utiliser. La valeur a utiliser est trouvable dans le systeme de fichiers sysfs : un sous-repertoire existe par instance PMU sous /sys/bus/event_source/devices. Le fichier type dans chaque sous-repertoire contient un entier qui peut etre utilise dans le champ type. Par exemple, /sys/bus/event_source/devices/cpu/type contient la valeur de PMU du processeur principal, c'est-a-dire 4 en general. kprobe et uprobe (depuis Linux 4.17) Ces deux PMU dynamiques creent un kprobe/uprobe et le rattachent a un descripteur de fichier genere par perf_event_open. kprobe/uprobe sera detruit lors de la destruction du descripteur de fichier. Voir les champs kprobe_func, uprobe_path, kprobe_addr et probe_offset pour plus de details. size La taille de la structure perf_event_attr pour compatibilites ascendante et descendante. Definissez-la en utilisant sizeof(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 defini a 64 ; c'etait la taille de la premiere struct publiee. PERF_ATTR_SIZE_VER1 est 72, correspondant a l'addition des points d'arrets dans Linux 2.6.33. PERF_ATTR_SIZE_VER2 est 80, correspondant a l'addition d'echantillonnage de branchement dans Linux 3.4. PERF_ATR_SIZE_VER3 est 96, correspondant a l'addition de sample_regs_user et sample_stack_user dans Linux 3.7. PERF_ATTR_SIZE_VER4 vaut 104, correspondant a l'ajout de sample_regs_intr dans Linux 3.19. PERF_ATTR_SIZE_VER5 vaut 112, correspondant a l'ajout de aux_watermark dans Linux 4.1. config Cela indique l'evenement voulu, en conjonction avec le champ type. Les champs config1 et config2 sont aussi pris en compte dans les cas ou 64 bits ne suffisent pas pour specifier completement l'evenement. L'encodage de ces champs depend de l'evenement. Le champ config peut etre defini de differentes facons, en fonction de la valeur du champ type precedemment decrit. Suivent les divers reglages possibles pour config, distingues par type. Si type est PERF_TYPE_HARDWARE, un des evenements processeur materiel generalise est mesure. Ils ne sont pas tous disponibles sur toutes les plateformes. Definissez config a une des valeurs suivantes : PERF_COUNT_HW_CPU_CYCLES Nombre total de cycles. Mefiez-vous de ce qui arrive lors de la variation de frequence du processeur. PERF_COUNT_HW_INSTRUCTIONS Instructions retirees. Prenez garde, elles peuvent etre affectees par plusieurs problemes, en particulier les decomptes d'interruptions materielles. PERF_COUNT_HW_CACHE_REFERENCES Acces au cache. En general, cela indique les acces au cache de dernier niveau, mais cela peut dependre du processeur. Cela pourrait inclure des messages de prelecture et de coherence ; cela depend toujours de la conception du processeur. PERF_COUNT_HW_CACHE_MISSES Absences dans le cache. Cela indique generalement les absences dans le cache de dernier niveau, c'est destine a etre utilise en conjonction avec l'evenement PERF_COUNT_HW_CACHE_REFERENCES pour calculer le taux d'absence du cache. PERF_COUNT_HW_BRANCH_INSTRUCTIONS Instructions de branchements retires. Avant Linux 2.6.34, cela utilisait l'evenement incorrect sur les processeurs AMD. PERF_COUNT_HW_BRANCH_MISSES Instructions de branchements mal predits. PERF_COUNT_HW_BUS_CYCLES Cycles de bus, ce qui peut etre different du decompte total de cycles. PERF_COUNT_HW_STALLED_CYCLES_FRONTEND (depuis Linux 3.0) Cycles bloques pendant un probleme. PERF_COUNT_HW_STALLED_CYCLES_BACKEND (depuis Linux 3.0) Cycles bloques pendant un retrait. PERF_COUNT_HW_REF_CPU_CYCLES (depuis Linux 3.3) Nombre total de cycles ; non affecte par la variation de frequence du processeur. Si type est PERF_TYPE_SOFTWARE, les evenements logiciels fournis par le noyau sont mesures. Definissez config a une des valeurs suivantes : PERF_COUNT_SW_CPU_CLOCK Cela rend compte de l'horloge du processeur, un temporisateur par processeur a haute resolution. PERF_COUNT_SW_TASK_CLOCK Cela rend compte de l'horloge specifique a la tache en cours d'execution. 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'a Linux 2.6.34, ils etaient tous signales comme des evenements en espace utilisateur, ils sont maintenant signales comme ayant lieu dans le noyau. PERF_COUNT_SW_CPU_MIGRATIONS Cela rend compte du nombre de fois ou le processus a migre vers un nouveau processeur. PERF_COUNT_SW_PAGE_FAULTS_MIN Cela compte le nombre d'erreurs mineures de pagination. Elles n'ont pas necessite d'entrees ou sorties du disque pour les traiter. PERF_COUNT_SW_PAGE_FAULTS_MAJ Cela compte le nombre d'erreurs majeures de pagination. Elles ont necessite des entrees ou sorties de disque pour les traiter. PERF_COUNT_SW_ALIGNMENT_FAULTS (depuis Linux 2.6.33) Cela compte le nombre de defauts d'alignement. Ils ont lieu lors d'acces non alignes en memoire ; le noyau peut les traiter mais cela reduit les performances. Cela n'arrive que sur certaines architectures (jamais sur x86). PERF_COUNT_SW_EMULATION_FAULTS (depuis Linux 2.6.33) Cela compte le nombre de defauts d'emulation. Le noyau intercepte parfois des instructions non implementees et les emule pour l'espace utilisateur. Cela peut avoir des consequences negatives sur les performances. PERF_COUNT_SW_DUMMY (depuis Linux 3.12) C'est un evenement fictif qui ne compte rien. Les types d'enregistrement d'echantillonnage informatif comme mmap ou comm doivent etre associes a un evenement actif. Cet evenement factice permet de recuperer ce genre d'enregistrements sans necessiter d'evenement de comptage. PERF_COUNT_SW_BPF_OUTPUT (depuis Linux 4.4) Cela est utilise pour generer des donnees d'echantillonnage brutes a partir de BPF. Les programmes BPF peuvent ecrire sur cet evenement 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 tache dans un cgroup different. En d'autres termes, si la tache suivante est dans le meme cgroup, il ne comptera le changement. Si type est PERF_TYPE_TRACEPOINT, alors les points de trace du noyau sont mesures. La valeur a utiliser dans config peut etre obtenue depuis tracing/events/*/*/id de debugfs si ftrace est active dans le noyau. Si type est PERF_TYPE_HW_CACHE, alors un evenement de cache du processeur materiel est mesure. Utilisez l'equation suivante pour calculer la valeur config appropriee. config = (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) | (perf_hw_cache_op_result_id << 16); ou perf_hw_cache_id peut etre : PERF_COUNT_HW_CACHE_L1D pour mesurer le cache de donnees de niveau 1 ; PERF_COUNT_HW_CACHE_L1I pour mesurer le cache d'instructions de niveau 1 ; PERF_COUNT_HW_CACHE_LL pour mesurer le cache de dernier niveau ; PERF_COUNT_HW_CACHE_DTLB pour mesurer les donnees TLB ; PERF_COUNT_HW_CACHE_ITLB pour mesurer les instructions TLB ; PERF_COUNT_HW_CACHE_BPU pour mesurer l'unite de prediction de branchement ; PERF_COUNT_HW_CACHE_NODE (depuis Linux 3.1) pour mesurer les acces a la memoire locale. et perf_hw_cache_op_id est parmi : PERF_COUNT_HW_CACHE_OP_READ pour les acces en lecture ; PERF_COUNT_HW_CACHE_OP_WRITE pour les acces en ecriture ; PERF_COUNT_HW_CACHE_OP_PREFETCH pour les acces de prelecture et perf_hw_cache_op_result_id peut etre : PERF_COUNT_HW_CACHE_RESULT_ACCESS pour mesurer les acces ; PERF_COUNT_HW_CACHE_RESULT_MISS pour mesurer les echecs. Si type est PERF_TYPE_RAW, alors une valeur config << brute >> personnalisee est necessaire. La plupart des processeurs gerent les evenements qui ne sont pas couverts par les evenements << generalises >>. Ceux-ci sont definis par l'implementation ; consultez le manuel du processeur (par exemple la documentation Intel Volume 3B ou le guide du developpeur de BIOS et noyau AMD). La bibliotheque libpfm4 peut etre utilisee pour traduire le nom, dans les manuels architecturaux, en valeur hexadecimale brute que perf_event_open() attend dans ce champ. Si type est PERF_TYPE_BREAKPOINT, alors laissez config defini a zero. Ses parametres sont definis ailleurs. Si type est kprobe ou uprobe, definir 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 details. kprobe_func uprobe_path kprobe_addr probe_offset Ces champs decrivent les kprobe/uprobe pour les PMU dynamiques kprobe et uprobe. Pour kprobe utilisez kprobe_func et probe_offset ou alors utilisez kprobe_addr et laissez le champ kprobe_func a NULL. Pour uprobe, utilisez uprobe_path et probe_offset. sample_period sample_freq Un compteur d'<< echantillonnage >> genere une notification de depassement tous les N evenements, ou N est donne par sample_period. Un compteur d'echantillonnage a sample_period > 0. Quand un depassement arrive, les donnees demandees sont enregistrees dans le tampon mmap. Le champ sample_type controle les donnees qui sont enregistrees a chaque depassement. sample_freq permet d'utiliser la frequence au lieu de la periode. Dans ce cas, l'attribut freq doit etre defini. Le noyau ajustera la periode d'echantillonnage 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 a inclure dans l'echantillon. Elles seront enregistrees dans un tampon circulaire, disponible en espace utilisateur avec mmap(2). L'ordre de sauvegarde des valeurs dans l'echantillon est documente 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 decompte de tous les evenements d'un groupe, pas seulement du leader de groupe. PERF_SAMPLE_CALLCHAIN Enregistrement de l'appel en chaine (backtrace de pile). PERF_SAMPLE_ID Enregistrement d'un identifiant unique pour le leader de groupe d'evenements ouvert. PERF_SAMPLE_CPU Enregistrement de numero de processeur. PERF_SAMPLE_PERIOD Enregistrement de la periode d'echantillonnage actuelle. PERF_SAMPLE_STREAM_ID Enregistrement d'un identifiant unique pour l'evenement ouvert. Contrairement a PERF_SAMPLE_ID, le veritable identifiant est renvoye, pas celui du leader de groupe. Cet identifiant est le meme que celui renvoye par PERF_FORMAT_ID. PERF_SAMPLE_RAW Enregistrement de donnees supplementaires, si applicable. Normalement renvoyees par les evenements de point de trace. PERF_SAMPLE_BRANCH_STACK (depuis Linux 3.4) Cela fournit un enregistrement des derniers branchements tels que fournis par le materiel d'echantillonnage de branchement processeur (comme le LBR - Last Branch Record - d'Intel). Les materiels ne prennent pas tous en charge cette fonctionnalite. Consultez le champ branch_sample_type pour la facon de filtrer les branchements signales. PERF_SAMPLE_REGS_USER (depuis Linux 3.7) Enregistrement de l'etat 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, permettant le defilement de la pile. PERF_SAMPLE_WEIGHT (depuis Linux 3.10) Enregistrement d'une valeur de poids fournie par le materiel qui exprime le cout de l'evenement d'echantillonnage. Cela permet au materiel de mettre en valeur les evenements couteux dans un profil. PERF_SAMPLE_DATA_SRC (depuis Linux 3.10) Enregistrement des sources de donnees : d'ou viennent, dans la hierarchie de memoire, les donnees associees a l'instruction d'echantillonnage. Ce n'est disponible que si le materiel sous-jacent prend en charge cette fonctionnalite. PERF_SAMPLE_IDENTIFIER (depuis Linux 3.12) Placement de la valeur SAMPLE_ID a un endroit fixe de l'enregistrement, soit au debut (pour les evenements d'echantillonnage), soit a la fin (si ce n'est pas un evenement d'echantillonnage). C'etait necessaire parce qu'un flux d'echantillonnage pourrait avoir des enregistrements provenant de differentes sources d'evenements avec des reglages de sample_type differents. L'analyse correcte du flux d'evenements n'etait pas possible parce que le format de l'enregistrement etait necessaire pour trouver SAMPLE_ID, mais le format ne pouvait pas etre trouve sans savoir a quel evenement l'echantillonnage appartenait (provoquant une dependance circulaire). Ce nouveau reglage PERF_SAMPLE_IDENTIFIER rend le flux d'evenements toujours analysable en placant SAMPLE_ID a une position fixe, meme si cela a pour consequence de dupliquer les valeurs SAMPLE_ID dans les enregistrements. PERF_SAMPLE_TRANSACTION (depuis Linux 3.13) Enregistrement des raisons pour les evenements d'abandon de memoire transactionnelle (venant par exemple de la prise en charge de memoire transactionnelle TSX Intel). Le reglage precise_ip doit etre positif et un evenement d'abandon de memoire transactionnelle doit etre mesure sinon aucune valeur ne sera enregistree. Remarquez egalement que certaines mesures perf_event, comme le comptage de cycles d'echantillonnage, peuvent provoquer des abandons supplementaires (en provoquant une interruption lors d'une transaction). PERF_SAMPLE_REGS_INTR (depuis Linux 3.19) Enregistrement d'un sous-ensemble de l'etat actuel du registre du processeur comme indique par sample_regs_intr. Contrairement a PERF_SAMPLE_REGS_USER, les valeurs du registre renverront l'etat du registre du noyau si le depassement s'est produit alors que le code du noyau est en cours d'execution. Si le processeur gere l'echantillonnage materiel de l'etat du registre (a savoir PEBS sur Intel x86) et si precise_ip est superieur a zero, les valeurs du registre renvoyees sont celles recuperees par le materiel au moment du retrait de l'instruction echantillonnee. PERF_SAMPLE_PHYS_ADDR (depuis Linux 4.13) Enregistrement de l'adresse physique des donnees 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'evenement PERF_RECORD_CGROUP. PERF_SAMPLE_DATA_PAGE_SIZE (depuis Linux 5.11) Enregistrement de la taille de la page de donnees 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 materiel comme PERF_SAMPLE_WEIGHT, mais il peut representer plusieurs valeur dans un struct. Il partage le meme espace que PERF_SAMPLE_WEIGHT, aussi les utilisateurs peuvent appliquer l'un ou l'autre, mais pas les deux a la fois. Il a le format suivant et la signification de chaque champ depend de l'implementation materielle. 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 donnees renvoyees 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 a calculer les totaux estimes si la PMU est surutilisee 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 estimes si la PMU est surutilisee et qu'il y a multiplexage. PERF_FORMAT_ID Ajout d'une valeur unique de 64 bits qui correspond au groupe d'evenements. PERF_FORMAT_GROUP Permettre a toutes les valeurs de decompte d'un groupe d'evenements d'etre lues en une seule lecture. PERF_FORMAT_LOST (depuis Linux 6.0) Ajout d'une valeur 64 bits qui est le nombre d'echantillons perdus pour cet evenement. Ce ne devrait significatif uniquement quand sample_period ou sample_freq est defini. disabled Le bit disabled indique si le compteur commence desactive ou active. Si desactive, l'evenement peut etre active plus tard par ioctl(2), prctl(2) ou enable_on_exec. Lors de la creation d'un groupe d'evenements, le leader de groupe est generalement initialise avec disabled defini a 1 et tous les evenements enfants sont initialises avec disabled defini a 0. Bien que disabled soit 0, les evenements enfants ne demarrent pas avant que le leader de groupe ne soit active. inherit Le bit inherit indique que le compteur devrait compter les evenements des taches enfant comme les taches indiquees. Cela ne s'applique qu'aux nouveaux enfants, pas a ceux existants au moment ou le compteur est cree (ni aux nouveaux enfants des enfants existants). L'heritage ne fonctionne pas pour certaines combinaisons de read_format, comme PERF_FORMAT_GROUP. pinned Le bit pinned indique que le compteur devrait toujours etre sur le processeur si c'est possible. Cela ne s'applique qu'aux compteurs materiels et seulement aux leaders de groupe. Si un compteur epingle ne peut pas etre mis dans le processeur (par exemple s'il n'y a pas assez de compteurs materiels ou en cas de confit avec n'importe quel autre evenement), alors le compteur arrive en etat d'<< erreur >>, ou les lectures renvoient une fin de fichier (c'est-a-dire que read(2) renvoie 0) jusqu'a ce que le compteur soit ensuite active ou desactive. exclusive Le bit exclusive indique que si ce groupe du compteur est sur le processeur, il devrait etre le seul groupe utilisant les compteurs du processeur. Cela pourrait permettre a l'avenir de surveiller des programmes pour gerer les fonctionnalites PMU qui doivent fonctionner seules, sans perturber d'autres compteurs materiels. Remarquez que de nombreuses situations non attendues pourraient empecher de demarrer les evenements avec le bit exclusive defini. Cela concerne tous les utilisateurs executant des mesures au niveau du systeme ainsi que toutes les utilisations par le noyau des compteurs de performance (y compris l'interface NMI Watchdog Timer habituellemen activee). exclude_user Si ce bit est defini, le decompte exclut les evenements qui arrivent dans l'espace utilisateur. exclude_kernel Si ce bit est defini, le decompte exclut les evenements qui arrivent dans l'espace du noyau. exclude_hv Si ce bit est defini, le decompte exclut les evenements qui arrivent dans l'hyperviseur. C'est surtout pour les PMU avec prise en charge integree de leur traitement (comme POWER). Une prise en charge supplementaire est necessaire pour traiter les mesures d'hyperviseur sur la plupart des machines. exclude_idle S'il est defini, ne pas decompter quand le processeur execute la tache inactive. Si vous pouvez actuellement activer cela pour n'importe quel type d'evenement, il est ignore pour tous, sauf ceux de type logiciel. mmap Le bit mmap active la generation des echantillons PERF_RECORD_MMAP pour tous les appels mmap(2) qui ont PROT_EXEC defini. Cela permet aux outils de remarquer le nouveau code executable en train d'etre associe dans un programme (les bibliotheques partagees dynamiques par exemple) de telle sorte que les adresses peuvent etre reassociees au code d'origine. comm Le bit comm active le suivi du nom de commande de processus tel que modifie par les appels systeme execve(2) et prctl(PR_SET_NAME) ainsi que l'ecriture dans /proc/self/comm. Si l'attribut comm_exec est positionne avec succes (ce qui est possible depuis Linux 3.16), l'attribut general PERF_RECORD_MISC_COMM_EXEC peut etre utilise pour differencier le cas execve(2) des autres. freq Si ce bit est active, alors sample_frequency est utilise au lieu de sample_period lors du reglage de l'intervalle d'echantillonnage. inherit_stat Ce bit active la sauvegarde des decomptes d'evenements lors du changement de contexte pour les taches heritees. Cela n'a de sens que si le champ inherit est defini. enable_on_exec Si ce bit est defini, un compteur est automatiquement active apres un appel d'execve(2). task Si ce bit est defini, alors les notifications de creation d'enfant et de fin sont inclues au tampon circulaire. watermark Si defini, une notification de debordement arrive lors du passage de la frontiere wakeup_watermark. Sinon, les notifications arrivent apres les echantillons wakeup_events. precise_ip (depuis Linux 2.6.35) Cela controle la quantite de derapage. Le derapage est le nombre d'instructions qui s'executent entre l'arrivee d'un evenement d'interet et la possibilite du noyau de s'arreter pour enregistrer l'evenement. Les plus petits derapages sont meilleurs et permettent d'associer plus precisement les evenements correspondant aux instructions, mais le materiel est souvent limite par leur taille. Les valeurs possibles du champ sont les suivantes : 0 SAMPLE_IP peut avoir un derapage arbitraire ; 1 SAMPLE_IP doit avoir un derapage constant ; 2 SAMPLE_IP a demande un derapage nul ; 3 SAMPLE_IP doit avoir un derapage nul. Consultez aussi la description de PERF_RECORD_MISC_EXACT_IP. mmap_data (depuis Linux 2.6.36) L'oppose du champ mmap. Cela active la generation des echantillons PERF_RECORD_MMAP pour les appels mmap(2) qui n'ont pas PROT_EXEC defini (par exemple les donnees et la memoire partagee SysV). sample_id_all (depuis Linux 2.6.38) Si defini, alors TID, TIME, ID, STREAM_ID et CPU peuvent de plus etre inclus dans les non PERF_RECORD_SAMPLE si le sample_type correspondant est selectionne. Si PERF_SAMPLE_IDENTIFIER est indique, alors une valeur d'identifiant supplementaire est incluse en derniere valeur pour faciliter l'analyse du flux d'enregistrement. Cela peut avoir pour consequence de voir apparaitre la valeur id deux fois. La disposition est decrite par cette pseudostructure : struct sample_id { { u32 pid, tid; } /* si PERF_SAMPLE_TID est defini */ { u64 time; } /* si PERF_SAMPLE_TIME est defini */ { u64 id; } /* si PERF_SAMPLE_ID est defini */ { u64 stream_id;} /* si PERF_SAMPLE_STREAM_ID est defini */ { u32 cpu, res; } /* si PERF_SAMPLE_CPU est defini */ { u64 id; } /* si PERF_SAMPLE_IDENTIFIER est defini */ }; exclude_host (depuis Linux 3.2) Quand on prend des mesures comprenant les processus executant des instances de VM (a savoir si on execute ioctl(2) KVM_RUN), ne mesurer que les evenements dans l'instance de l'invite. Cela n'a de sens qu'a l'exterieur de l'invite ; ce parametre ne modifie pas les compteurs a l'interieur d'un invite. Actuellement, cette fonctionnalite n'existe que sur x86. exclude_guest (depuis Linux 3.2) Quand on prend des mesures comprenant les processus executant des instances de VM (a savoir si on execute ioctl(2) KVM_RUN), ne pas mesurer les evenements dans l'instance de l'invite. Cela n'a de sens qu'a l'exterieur de l'invite ; ce parametre ne modifie pas les compteurs a l'interieur d'un invite. Actuellement, cette fonctionnalite n'existe que sur x86. exclude_callchain_kernel (depuis Linux 3.7) Ne pas inclure les appels en chaine du noyau. exclude_callchain_user (depuis Linux 3.7) Ne pas inclure les appels en chaine d'utilisateur. mmap2 (depuis Linux 3.16) Generer un enregistrement mmap executable etendu contenant assez d'informations supplementaires pour n'identifier que les projections partagees. L'attribut mmap doit aussi etre defini pour que cela fonctionne. comm_exec (depuis Linux 3.16) Il s'agit d'un attribut de pure detection de fonctionnalite, il ne modifie pas le comportement du noyau. Si cet attribut peut etre positionne avec succes, quand comm est active, l'attribut PERF_RECORD_MISC_COMM_EXEC sera positionne dans le champ misc de l'entete de l'enregistrement comm si l'evenement de renommage signale a ete cause par un appel a execve(2). Cela permet aux outils de distinguer les types de renommage du processus. use_clockid (depuis Linux 4.1) Cela permet de selectionner l'horloge interne du noyau Linux a utiliser lors de la generation des horodatages a l'aide du champ clockid. Cela peut faciliter la correlation des durees d'echantillonnage des perf avec les horodatages generes par d'autres outils. context_switch (depuis Linux 4.3) Cela active la generation d'enregistrements PERF_RECORD_SWITCH lors d'un changement de contexte. Cela active aussi la generation d'enregistrements PERF_RECORD_SWITCH_CPU_WIDE lors d'un echantillonnage en mode processeur complet. Cette fonctionnalite s'ajoute aux points de trace existants et aux evenements logiciels de mesure des changements de contexte. L'avantage de cette methode est qu'elle fournira toutes les informations meme avec des reglages perf_event_paranoid stricts. write_backward (depuis Linux 4.6) Cela fait ecrire le tampon circulaire de la fin vers le debut. Cela permet de gerer la lecture a partir d'un tampon circulaire reinscriptible. namespaces (depuis Linux 4.11) Cela active la generation d'enregistrements PERF_RECORD_NAMESPACES lorsqu'une tache entre dans un nouvel espace de noms. Chaque espace de noms a une combinaison de numeros de peripherique et d'inoeud. ksymbol (depuis Linux 5.0) Cela active la generation d'enregistrements PERF_RECORD_KSYMBOL quand de nouveaux symboles du noyau sont enregistres ou desenregistres. Cela concerne les fonctions dynamiques d'analyse du noyau comme eBPF. bpf_event (depuis Linux 5.0) Cela active la generation d'enregistrements PERF_RECORD_BPF_EVENT lorsqu'un programme eBPF est charge ou decharge. aux_output (depuis Linux 5.4) Cela permet aux evenements normaux (non-AUX) de generer des donnees pour des evenements AUX si le materiel le prend en charge. cgroup (depuis Linux 5.7) Cela active la generation d'enregistrements PERF_RECORD_CGROUP quand un nouveau cgroup est cree (et active). text_poke (depuis Linux 5.8) Cela active la generation d'enregistrements PERF_RECORD_TEXT_POKE quand un changement se produit dans le texte du noyau (c'est-a-dire quand du code se modifie lui-meme). build_id (depuis Linux 5.12) Cela modifie le contenu dePERF_RECORD_MMAP2 pour avoir un build-id a la place des numeros de peripherique et d'inoeud. inherit_thread (depuis Linux 5.13) Cela desactive l'heritage de l'evenement vers un processus enfant. Seuls les nouveaux threads dans le meme processus (qui est clone avec CLONE_THREAD) heriteront de l'evenement. remove_on_exec (depuis Linux 5.13) Cela clot l'evenement quand il demarre 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 evenement deborde. wakeup_events wakeup_watermark Cette union indique le nombre d'echantillons (wakeup_events) ou d'octets (wakeup_watermark) qui arrivent avant un signal de depassement. Celui utilise est selectionne par l'attribut watermark. wakeup_events ne compte que les types d'enregistrement PERF_RECORD_SAMPLE. Pour recevoir un signal pour tous les types PERF_RECORD arrivant, choisissez watermark et definissez wakeup_watermark a 1. Avant Linux 3.0, positionner wakeup_events a 0 ne signalait aucun depassement ; les noyaux plus recents traitent 0 comme 1. bp_type (depuis Linux 2.6.33) Cela choisit le type de point d'arret. Il s'agit d'un des suivants : HW_BREAKPOINT_EMPTY pas de point d'arret ; HW_BREAKPOINT_R compte lors de la lecture de l'emplacement memoire ; HW_BREAKPOINT_W compte lors de l'ecriture a l'emplacement memoire ; HW_BREAKPOINT_RW compte lors de la lecture ou l'ecriture a l'emplacement memoire ; HW_BREAKPOINT_X compte lors de l'execution de code a l'emplacement memoire. Les valeurs peuvent etre combinees a 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'arret. Pour les points d'arret d'execution, c'est l'adresse memoire de l'instruction d'interet ; pour les points d'arret de lecture et ecriture, c'est l'adresse memoire de l'emplacement memoire d'interet. config1 (depuis Linux 2.6.39) config1 est utilise pour definir des evenements qui ont besoin d'un registre supplementaire ou qui sinon ne rentrent pas dans le champ config normal. OFFCORE_EVENTS brut sur Nehalem/Westmere/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'arret mesure 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'arret, definissez-la a sizeof(long). config2 (depuis Linux 2.6.39) config2 est une extension supplementaire du champ config1. branch_sample_type (depuis Linux 3.4) Si PERF_SAMPLE_BRANCH_STACK est active, alors cela indique les branchements a inclure dans l'enregistrement de branchements. La premiere partie de la valeur est le niveau de droits qui est une combinaison d'une des valeurs suivantes. Si l'utilisateur ne definit pas explicitement le niveau de droits, le noyau utilisera celui de l'evenement. Les niveaux de droits de l'evenement et du branchement ne doivent pas necessairement 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 precedentes combinees avec un OU. En plus de la valeur de droits, au moins un des bits suivants doit etre defini. 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 memoire transactionnelle. PERF_SAMPLE_BRANCH_IN_TX (depuis Linux 3.11) Branchement dans une transaction de memoire transactionnelle. PERF_SAMPLE_BRANCH_NO_TX (depuis Linux 3.11) Branchement non dans la transaction de la memoire transactionnelle. PERF_SAMPLE_BRANCH_CALL_STACK (depuis Linux 4.1). Le branchement faitpartie d'une pile d'appel generee par le materiel. Cela implique la prise en charge par le materiel, qui n'existe actuellement que sur le x86 Haswell d'Intel ou plus recent. sample_regs_user (depuis Linux 3.7) Ce masque binaire definit l'ensemble des registres processeur utilisateur a renvoyer dans les echantillons. La disposition du masque de registre est specifique a l'architecture et definie dans l'en-tete du noyau arch/ARCH/include/uapi/asm/perf_regs.h. sample_stack_user (depuis Linux 3.7) Cela definit la taille de la pile utilisateur a renvoyer si PERF_SAMPLE_STACK_USER est indique. clockid (depuis Linux 4.1) Si use_clockid est positionne, ce champ selectionne l'horloge interne de Linux a utiliser pour les horodatages. Les horloges disponibles sont definies dans linux/time.h, ou sont actuellement prises en charge CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME, CLOCK_BOOTTIME et CLOCK_TAI. aux_watermark (depuis Linux 4.1) Cela indique la quantite de donnees necessaires pour recuperer un echantillonnage PERF_RECORD_AUX. sample_max_stack (depuis Linux 4.8) Quand sample_type comprend PERF_SAMPLE_CALLCHAIN, ce champ indique le nombre de trames de pile a rendre compte lors de la generation de la chaine d'appels. aux_sample_size (depuis Linux 5.5) Quand l'attribut PERF_SAMPLE_AUX est defini, specification de la taille souhaitee aux donnees AUX. Notez qu'il peut recevoir des donnees plus petites que la taille indiquee. sig_data (depuis Linux 5.13) Cette donnee sera copiee vers le gestionnaire de signal de l'utilisateur (au moyen de si_perf dans siginfo_t ) pour disambiguiser l'evenement qui a declenche le signal. Lecture des resultats Une fois qu'un descripteur de fichier perf_event_open() a ete ouvert, les valeurs des evenements peuvent etre lues depuis le descripteur de fichier. Les valeurs presentes sont indiquees par le champ read_format de la structure attr au moment de l'ouverture. Si vous essayez de lire un tampon utilise pour la lecture qui n'est pas assez grand pour contenir les donnees, ENOSPC est renvoye. Voici la disposition des donnees renvoyees par une lecture : - Si PERF_FORMAT_GROUP a ete indique pour permettre de lire tous les evenements d'un groupe en une fois : struct read_format { u64 nr; /* Le nombre d'evenements */ 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'evenement */ u64 id; /* si PERF_FORMAT_ID */ u64 lost; /* si PERF_FORMAT_LOST */ } values[nr]; }; - Si PERF_FORMAT_GROUP n'a pas ete indique : struct read_format { u64 value; /* La valeur de l'evenement */ 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'evenements dans le descripteur de fichier. Seulement disponible si PERF_FORMAT_GROUP a ete indique. time_enabled time_running Temps total pendant lequel l'evenement a ete active et execute. Normalement ce sont les memes. Si plus d'evenements sont demarres que d'emplacements de compteur disponibles sur la PMU, alors il y a multiplexage et les evenements ne sont pas executes tout le temps. Dans ce cas, les valeurs time_enabled et time running peuvent etre utilisees pour estimer une valeur d'ordre de grandeur du decompte. value Une valeur positive sur 64 bits contenant le resultat du compteur. id Une valeur unique globale pour cet evenement en particulier, seulement si PERF_FORMAT_ID a ete indique dans read_format. lost Le nombre des echantillons perdus de cet evenement ; seulement si PERF_FORMAT_LOST a ete indique dans read_format. Disposition MMAP En utilisant perf_event_open() en mode d'echantillonnage, les evenements asynchrones (comme un depassement de compteur ou un suivi mmap PROT_EXEC) sont journalises dans un tampon circulaire. Ce tampon circulaire est cree et accede a l'aide de mmap(2). La taille de mmap devrait etre 1+2^n pages, ou la premiere page est une page de metadonnees (struct perf_event_mmap_page) qui contient plusieurs informations comme l'emplacement de la tete du tampon circulaire. Avant Linux 2.6.39, un bogue oblige a allouer un tampon circulaire mmap lors de l'echantillonnage meme s'il n'est pas prevu de l'utiliser. La structure de la premiere page mmap de metadonnees est la suivante : struct perf_event_mmap_page { __u32 version; /* numero de version de la structure */ __u32 compat_version; /* plus petite version compatible */ __u32 lock; /* seqlock pour synchronisation */ __u32 index; /* identifiant de compteur materiel */ __s64 offset; /* ajouter au compteur materiel */ __u64 time_enabled; /* temps d'evenement actif */ __u64 time_running; /* temps d'evenement 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 a 1 k */ __u64 data_head; /* tete de la section de donnees */ __u64 data_tail; /* queue ecrite en espace utilisateur */ __u64 data_offset; /* ou commence le tampon */ __u64 data_size; /* taille du tampon de donnees */ __u64 aux_head; __u64 aux_tail; __u64 aux_offset; __u64 aux_size; } La liste suivante decrit les champs de la structure perf_event_mmap_page plus precisement. version Numero 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 materiel. decalage Quand l'instruction rdpmc est utilisee pour lire, cette valeur de position doit etre ajoutee a celle renvoyee par rdpmc pour obtenir le decompte total actuel d'evenements. time_enabled Temps d'activite de l'evenement. time_running Temps d'execution de l'evenement. cap_usr_time / cap_usr_rdpmc / cap_bit0 (depuis Linux 3.4) Un bogue existait dans la definition de cap_usr_time et cap_usr_rdpmc de Linux 3.4 a Linux 3.11. Les deux bits etaient definis pour pointer vers le meme endroit, il etait donc impossible de savoir si cap_usr_time ou cap_usr_rdpmc etaient vraiment definis. Depuis Linux 3.12, ils ont ete renommes en cap_bit0 et vous devriez plutot utiliser les nouveaux champs cap_user_time et cap_user_rdpmc a la place. cap_bit0_is_deprecated (depuis Linux 3.12) Si defini, ce bit indique que le noyau est capable de gerer les bits cap_user_time et cap_user_rdpmc differencies correctement. Si non, cela indique qu'il s'agit d'un ancien noyau ou cap_usr_time et cap_usr_rdpmc pointent vers le meme bit et donc que ces deux fonctionnalites devraient etre utilisees avec prudence. cap_usr_rdpmc (depuis Linux 3.12) Si le materiel permet la lecture en espace utilisateur des compteurs de performance sans appel systeme (c'est l'instruction << rdpmc >> sur x86), alors le code suivant peut etre utilise 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 materiel a un compteur temporel sans arret, constant (TSC sur x86). cap_usr_time_zero (depuis Linux 3.12) Indique la presence de time_zero qui permet d'associer les valeurs d'horodatage a l'horloge materielle. pmc_width Si cap_usr_rdpmc, ce champ fournit la taille en bit de la valeur lue en utilisant l'instruction rdpmc ou equivalente. Cela permet d'etendre avec signe le resultat comme ceci : pmc <<= 64 - pmc_width; pmc >>= 64 - pmc_width; // deplacement du signe a droite count += pmc; time_shift time_mult time_offset Si cap_usr_time, ces champs peuvent etre utilises pour calculer la difference 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); Ou time_offset, time_mult, time_shift et cyc sont lus dans la boucle seqcount decrite ci-dessus. Cette difference peut etre ajoutee a enabled et eventuellement running (si idx), pour ameliorer l'echelle : 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 defini, alors l'horloge materielle (le compteur temporel TSC sur x86) peut etre calculee a 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 tete de la section de donnees. La valeur augmente continuellement, elle n'est pas coupee. Vous devrez couper vous-meme la valeur a la taille du tampon mmap avant d'acceder aux echantillons. Sur les plateformes compatibles SMP, apres la lecture de la valeur data_head, l'espace utilisateur devrait renvoyer un rmb(). data_tail Quand l'association est PROT_WRITE, la valeur data_tail devrait etre ecrite par l'espace utilisateur pour refleter les dernieres donnees lues. Dans ce cas, le noyau n'ecrasera pas les donnees non lues. data_offset (depuis Linux 4.1) Contient la position de l'emplacement du tampon mmap ou les donnees de l'echantillon de perf commencent. data_size (depuis Linux 4.1) Contient la taille de la zone de l'echantillon de perf dans le tampon mmap. aux_head aux_tail aux_offset aux_size (depuis Linux 4.1) La zone AUX permet d'appliquer a un mmap(2) un tampon d'echantillonnage distinct pour les flux de donnees a forte bande passante (separement du tampon d'echantillonnage de perf principal). Un exemple de flux a forte bande passante est la prise en charge du tracage d'une instruction telle qu'elle se fait dans les nouveaux processeurs Intel. Pour definir une zone AUX, il faut d'abord positionner aux_offset a une position superieure a data_offset+data_size puis positionner aux_size a la taille de tampon desiree. La position et la taille desiree doivent etre alignees sur la page et la taille doit etre une puissance de deux. Ces valeurs sont alors passees a mmap pour projeter le tampon AUX. Les pages du tampon AUX sont comprises dans la limite de ressource RLIMIT_MEMLOCK (voir setrlimit(2)) et dans la gestion des droits perf_event_mlock_kb. Par defaut, le tampon AUX sera tronque s'il ne rentre pas dans l'espace disponible du tampon circulaire. Si le tampon AUX est projete en tant que tampon en lecture seule, il agira dans le mode du tampon circulaire la ou les donnees seront remplacees par de nouvelles. En mode remplacement, il se pourrait qu'il ne soit pas possible de presumer l'endroit ou commencent les donnees et il appartient au consommateur de desactiver la mesure pendant la lecture pour eviter les possibles collisions de donnees. Les pointeurs de tampon circulaire aux_head et aux_tail ont le meme comportement et les memes regles d'organisation que celles decrites precedemment pour data_head et data_tail. Les 2^n pages suivantes du tampon circulaire ont la disposition decrite ci-dessous. Si perf_event_attr.sample_id_all est defini, alors tous les types d'evenements auront les champs sample_type selectionnes relatifs a l'emplacement et a la date (identite) ou un evenement a eu lieu (TID, TIME, ID, CPU, STREAM_ID) conformement a la description de PERF_RECORD_SAMPLE ci-dessous, il sera stocke juste apres le perf_event_header et les champs deja presents pour les champs existants, c'est-a-dire a la fin de la charge utile. De cette facon, un nouveau perf.data sera pris en charge par les outils de performances plus anciens, avec ces nouveaux champs facultatifs ignores. Les valeurs mmap commencent par un en-tete : struct perf_event_header { __u32 type; __u16 misc; __u16 size; }; Les champs perf_event_header sont decrits plus precisement ci-dessous. Par commodite de lecture, les champs avec les descriptions les plus courtes sont d'abord presentes. size Cela indique la taille de l'enregistrement. misc Le champ misc contient des renseignements supplementaires sur l'echantillon. Le mode de processeur peut etre determine a partir de cette valeur en la masquant avec PERF_RECORD_MISC_CPUMODE_MASK et en recherchant un des suivants (remarquez que ce ne sont pas des masques de bits, un seul peut etre defini a la fois). PERF_RECORD_MISC_CPUMODE_UNKNOWN Mode de processeur inconnu. PERF_RECORD_MISC_KERNEL L'echantillon a eu lieu dans le noyau. PERF_RECORD_MISC_USER L'echantillon a eu lieu dans le code utilisateur. PERF_RECORD_MISC_HYPERVISOR L'echantillon a eu lieu dans l'hyperviseur. PERF_RECORD_MISC_GUEST_KERNEL (depuis Linux 2.6.35) L'echantillon a eu lieu dans le noyau client. PERF_RECORD_MISC_GUEST_USER (depuis Linux 2.6.35) L'echantillon a eu lieu dans le code utilisateur client. Comme les trois etats suivants sont generes par differents types d'enregistrement, ils constituent des alias du meme bit : PERF_RECORD_MISC_MMAP_DATA (depuis Linux 3.10) C'est defini quand l'association n'est pas executable ; sinon l'association est executable. PERF_RECORD_MISC_COMM_EXEC (depuis Linux 3.16) Il est positionne pour un enregistrement PERF_RECORD_COMM sur les noyaux plus recents que Linux 3.16 si le changement de nom d'un processus est cause par un appel systeme execve(2). PERF_RECORD_MISC_SWITCH_OUT (depuis Linux 4.3) Quand un enregistrement PERF_RECORD_SWITCH ou PERF_RECORD_SWITCH_CPU_WIDE est genere, 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 etre definis : PERF_RECORD_MISC_EXACT_IP Cela indique que le contenu de PERF_SAMPLE_IP pointe vers la veritable instruction qui a declenche l'evenement. 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_RECORD_SWITCH_CPU_WIDE est genere, cela indique que le changement de contexte etait une preemption. PERF_RECORD_MISC_MMAP_BUILD_ID (depuis Linux 5.12) Cela indique que le contenu de PERF_SAMPLE_MMAP2 renferme les donnees de build-ID plutot que les numeros majeur et mineur du peripherique ainsi que le numero d'inoeud. PERF_RECORD_MISC_EXT_RESERVED (depuis Linux 2.6.35) Cela indique que des donnees etendues sont disponibles (actuellement pas utilisees). PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT Ce bit n'est pas defini par le noyau. Il est reserve a l'outil perf dans l'espace utilisateur pour indiquer que l'analyse de /proc/pid/maps a trop dure et a ete arretee, ainsi les enregistrements mmap peuvent etre tronques. type La valeur type est une des suivantes. Les valeurs dans l'enregistrement correspondant (qui suit l'en-tete) dependent du type selectionne comme c'est montre. PERF_RECORD_MMAP Les evenements MMAP enregistrent les associations PROT_EXEC pour pouvoir mettre en correlation les pointeurs d'instruction 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 memoire allouee. len est la taille de la memoire allouee. pgoff est la position de la page de la memoire allouee. filename est une chaine decrivant la base de la memoire allouee. PERF_RECORD_LOST Cet enregistrement indique quand des evenements sont perdus. struct { struct perf_event_header header; u64 id; u64 lost; struct sample_id sample_id; }; id est l'identifiant unique d'evenement pour les echantillons perdus. lost est le nombre d'evenements perdus. PERF_RECORD_COMM Cet enregistrement indique une modification du nom de processus. 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 chaine contenant le nouveau nom du processus. PERF_RECORD_EXIT Cet enregistrement indique un evenement 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 evenement de variation de frequence 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 evenement de creation d'enfant. 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 evenement 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 echantillon. 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 active, un identifiant unique sur 64 bits est inclus. C'est une copie de la valeur id de PERF_SAMPLE_ID, mais incluse au debut de l'echantillon pour permettre aux analyseurs d'obtenir facilement la valeur. ip Si PERF_SAMPLE_IP est active, alors une valeur de pointeur d'instruction sur 64 bits est incluse. pid tid Si PERF_SAMPLE_TID est active, alors un identifiant de processus sur 32 bits et un identifiant de thread sur 32 bits sont inclus. time Si PERF_SAMPLE_TIME est active, alors un horodatage sur 64 bits est inclus. C'est obtenu a l'aide de local_clock() qui est un horodatage materiel si disponible et la valeur jiffy sinon. addr Si PERF_SAMPLE_ADDR est active, alors une adresse sur 64 bits est incluse. C'est generalement l'adresse d'un point de trace, point d'arret ou evenement logiciel ; sinon la valeur est 0. id Si PERF_SAMPLE_ID est active, un identifiant unique sur 64 bits est inclus. Si l'evenement est membre d'un groupe d'evenements, l'identifiant du leader de groupe est renvoye. Cet identifiant est le meme que celui renvoye par PERF_FORMAT_ID. stream_id Si PERF_SAMPLE_STREAM_ID est active, un identifiant unique sur 64 bits est inclus. Contrairement a PERF_SAMPLE_ID, le veritable identifiant est renvoye, pas celui du leader de groupe. Cet identifiant est le meme que celui renvoye par PERF_FORMAT_ID. cpu res Si PERF_SAMPLE_CPU est active, c'est une valeur sur 32 bits indiquant le processeur qui a ete utilise, en supplement d'une valeur reservee (non utilisee) sur 32 bits. period Si PERF_SAMPLE_PERIOD est active, une valeur sur 64 bits indiquant la periode d'echantillonnage actuelle est ecrite. v Si PERF_SAMPLE_READ est active, une structure de type read_format est incluse avec des valeurs pour tous les evenements du groupe d'evenements. Les valeurs incluses dependent de la valeur read_format utilisee au moment de perf_event_open(). nr ips[nr] Si PERF_SAMPLE_CALLCHAIN est active, 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 chaine actuel. size data[size] Si PERF_SAMPLE_RAW est active, alors une valeur sur 32 bits indiquant la taille est incluse, suivie par un tableau de valeurs sur 8 bits de taille size. Les valeurs sont remplies avec des 0 pour avoir un alignement a 64 bits. Ces donnees brutes d'enregistrement sont opaques du point de vue de l'ABI. L'ABI ne fait pas de promesses sur la stabilite de son contenu qui pourrait varier en fonction de l'evenement, du materiel ou de la version du noyau. bnr lbr[bnr] Si PERF_SAMPLE_BRANCH_STACK est active, alors une valeur de 64 bits indiquant le nombre d'enregistrements est incluse, suivie des structures bnr perf_branch_entry qui chacune contient les champs suivants. from Cela indique l'instruction source (qui pourrait ne pas etre un branchement). to La cible de branchement. mispred La cible de branchement a ete mal predite. predicted La cible de branchement a ete predite. in_tx (depuis Linux 3.11) Le branchement etait dans une transaction de memoire transactionnelle. abort (depuis Linux 3.11) Le branchement etait dans une transaction abandonnee de memoire transactionnelle. cycles (depuis Linux 4.3) Cela rend compte du nombre de cycles qui se sont deroules depuis la derniere mise a jour de la pile de branchement. Les entrees sont presentees dans l'ordre chronologique, de telle sorte que la premiere entree a le branchement le plus recent. La prise en charge de mispred, predicted et cycles est facultative. En absence de prise en charge, les deux valeurs seront 0. Le type de branchements enregistres est indique par le champ branch_sample_type. abi regs[weight(mask)] Si PERF_SAMPLE_REGS_USER est active, alors les registres processeur utilisateur sont enregistres. 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 ete indiques par le champ attr sample_regs_user. Le nombre de valeurs est le nombre de bits definis dans le masque binaire sample_regs_user. size data[size] dyn_size Si PERF_SAMPLE_STACK_USER est active, la pile utilisateur est enregistree. Cela peut etre utilise pour generer les backtraces de la pile. size est la taille demandee par l'utilisateur dans sample_stack_user ou autrement la taille maximale d'enregistrement. data contient les donnees de pile (un contenu brut de la memoire indiquee par le pointeur de pile au moment de l'echantillonnage). dyn_size est la quantite de donnees vraiment renvoyee (peut etre inferieure a size). Remarquez que dyn_size est omis si size vaut 0. weight Si PERF_SAMPLE_WEIGHT ou PERF_SAMPLE_WEIGHT_STRUCT sont actives, une valeur de 64 bits fournie par le materiel est enregistree pour indiquer le cout de l'evenement. Cela permet aux evenements couteux de ressortir plus clairement dans les profils. data_src Si PERF_SAMPLE_DATA_SRC est active, alors une valeur de 64 bits est enregistree, constituee des champs suivants. mem_op Type de code operation (opcode), une combinaison bit a 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 Prelecture PERF_MEM_OP_EXEC Code executable mem_lvl Niveau de hierarchie de memoire atteint ou rate, une combinaison bit a bit de ce qui suit, envoyes a gauche par PERF_MEM_LVL_SHIFT : PERF_MEM_LVL_NA Non disponible PERF_MEM_LVL_HIT Atteint PERF_MEM_LVL_MISS Rate PERF_MEM_LVL_L1 Cache de niveau 1 PERF_MEM_LVL_LFB Tampon de capacite 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 Memoire d'entree et sortie. PERF_MEM_LVL_UNC Memoire sans cache mem_snoop Mode espionnage, une combinaison bit-a-bit de ce qui suit, decale 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 rate PERF_MEM_SNOOP_HITM Espionnage atteint modifie mem_lock Instruction de verrouillage, une combinaison bit a bit de ce qui suit, renvoyee vers la gauche par PERF_MEM_LOCK_SHIFT : PERF_MEM_LOCK_NA Non disponible PERF_MEM_LOCK_LOCKED Transaction verrouillee mem_dtlb Acces TLB atteint ou rate, une combinaison bit a bit de ce qui suit, renvoyee vers la gauche par PERF_MEM_TLB_SHIFT : PERF_MEM_TLB_NA Non disponible PERF_MEM_TLB_HIT Atteint PERF_MEM_TLB_MISS Rate PERF_MEM_TLB_L1 TLB de niveau 1 PERF_MEM_TLB_L2 TLB de niveau 2 PERF_MEM_TLB_WK Parcours materiel PERF_MEM_TLB_OS Gestionnaire d'erreur du SE transaction Si l'attribut PERF_SAMPLE_TRANSACTION est defini, alors un champ de 64 bits est enregistre pour decrire les sources de tous les abandons de memoire transactionnelle. Le champ est une combinaison bit a bit des valeurs suivantes : PERF_TXN_ELISION Abandon d'une transaction de type elision (specifique aux processeurs Intel). PERF_TXN_TRANSACTION Abandon d'une transaction generique. PERF_TXN_SYNC Abandon synchrone (relatif a l'instruction signalee). PERF_TXN_ASYNC Abandon asynchrone (non relatif a l'instruction signalee). PERF_TXN_RETRY Abandon reessayable (reessayer la transaction pourrait reussir). PERF_TXN_CONFLICT Abandon a cause de conflits de memoire avec d'autres threads. PERF_TXN_CAPACITY_WRITE Abandon a cause de depassement de la capacite d'ecriture. PERF_TXN_CAPACITY_READ Abandon a cause de depassement de la capacite de lecture. De plus, un code d'abandon specifique a l'utilisateur peut etre obtenu a partir des premiers 32 bits du champ en deplacant 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 active, alors les registres processeur utilisateur sont enregistres. 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 ete indiques par le champ attr sample_regs_intr. Le nombre de valeurs est le nombre de bits definis dans le masque binaire sample_regs_intr. phys_addr Si l'attribut PERF_SAMPLE_PHYS_ADDR est positionne, l'adresse physique en 64 bits est enregistree. cgroup Si l'attribut PERF_SAMPLE_CGROUP est positionne, l'identifiant de cgroup 64 bits (pour le sous-systeme perf_event) est enregistre. Pour recuperer le chemin du cgroup, l'identifiant doit correspondre a un de ceux se trouvant dans PERF_RECORD_CGROUP. data_page_size Si l'attribut PERF_SAMPLE_DATA_PAGE_SIZE est positionne, la valeur en 64 bits de la taille de la page de l'adresse de data est enregistree. code_page_size Si l'attribut PERF_SAMPLE_CODE_PAGE_SIZE est positionne, la valeur en 64 bits de la taille de la page de l'adresse ip est enregistree. size data[size] Si PERF_SAMPLE_AUX est active, alors un instantane du tampon aux est enregistre. PERF_RECORD_MMAP2 Cet enregistrement inclut des informations etendues sur les appels mmap(2) renvoyant des projections executables. Le format est identique a celui de l'enregistrement PERF_RECORD_MMAP mais il comprend des valeurs supplementaires qui permettent uniquement d'identifier des projections partagees. Selon le bit PERF_RECORD_MISC_MMAP_BUILD_ID dans l'en-tete, les valeurs supplementaires ont des presentations et des significations differentes. 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 memoire allouee. len est la taille de la memoire allouee. pgoff est la position de la page de la memoire allouee. maj est l'identifiant majeur du peripherique sous-jacent. min est l'identifiant mineur du peripherique sous-jacent. ino est le numero d'inoeud. ino_generation est la generation d'inoeud. build_id_size est la taille reelle du champ build_id (jusqu'a 20). build_id ce sont des donnees brutes pour identifier un binaire. prot sont les informations de protection. flags sont les informations d'attributs. filename est une chaine decrivant la base de la memoire allouee. PERF_RECORD_AUX (depuis Linux 4.1) Cet enregistrement rend compte des nouvelles donnees disponibles dans la zone separee 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 ou commencent les nouvelles donnees. aux_size taille des donnees disponibles. flags decrit la mise a jour AUX. PERF_AUX_FLAG_TRUNCATED s'il est positionne, les donnees renvoyees ont ete tronquees pour rentrer dans la taille du tampon disponible. PERF_AUX_FLAG_OVERWRITE s'il est positionne, les donnees renvoyees ont ecrase des donnees precedentes. PERF_RECORD_ITRACE_START (depuis Linux 4.1) Cet enregistrement indique le processus qui a initie un evenement de tracage d'instruction, permettant aux outils de correler correctement les adresses d'instruction du tampon AUX avec le bon executable. struct { struct perf_event_header header; u32 pid; u32 tid; }; pid identifiant de processus du thread ayant commence un tracage d'instruction. tid identifiant du thread ayant commence le tracage d'instruction. PERF_RECORD_LOST_SAMPLES (depuis Linux 4.2) Lors de l'utilisation de l'echantillonnage materiel (comme les PEBS d'Intel), cet enregistrement indique le nombre d'echantillons qui peuvent avoir ete perdus. struct { struct perf_event_header header; u64 lost; struct sample_id sample_id; }; lost est le nombre d'echantillons 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 indique 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'echantillonnage en mode processeur complet et il fournit des informations supplementaires sur le processus faisant l'objet du changement. Le bit PERF_RECORD_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 precedent ou suivant (selon le sens du changement) sur le processeur. next_prev_tid L'identifiant du thread precedent ou suivant (selon le sens du changement) sur le processeur. PERF_RECORD_NAMESPACES (depuis Linux 4.11) Cet enregistrement comprend diverses informations sur l'espace 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 enregistrement. Chaque espace de noms a des champs dev et inode et il est enregistre dans une position fixe comme celle ci-dessous : NET_NS_INDEX=0 espace de noms reseau 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 controle PERF_RECORD_KSYMBOL (depuis Linux 5.0) Cet enregistrement indique un evenement d'enregistrement/desenregistrement 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. flags Si PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER est positionne, cet evenement se produit lors du desenregistrement d'un symbole du noyau. PERF_RECORD_BPF_EVENT (depuis Linux 5.0) Cet enregistrement indique si un programme BPF est charge ou decharge. 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 charge. PERF_BPF_EVENT_PROG_UNLOAD Un programme BPF est decharge id est l'identifiant du programme BPF. tag est l'etiquette du programme BPF. Actuellement, BPF_TAG_SIZE est defini a 8. PERF_RECORD_CGROUP (depuis Linux 5.7) Cet enregistrement indique si un cgroup est cree et active. struct { struct perf_event_header header; u64 id; char path[]; struct sample_id sample_id; }; id est l'identifiant du cgroup. Il peut aussi etre recupere a 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 zero 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 immediatement suivis des nouveaux. Gestion du depassement Des evenements peuvent etre positionnes pour signaler quand on depasse une limite, indiquant un depassement. Les conditions d'un depassement peuvent etre recuperees avec poll(2), select(2) ou epoll(7). Alternativement, les evenements de depassement peuvent etre captures a l'aide d'un gestionnaire de signal en activant les signaux d'E/S sur le descripteur de fichier ; voir le point sur les operations F_SETOWN et F_SETSIG dans fcntl(2). Les debordements ne sont generes que par les evenements d'echantillonnage (sample_period doit avoir une valeur non nulle). Deux facons permettent de generer des notifications de debordement. La premiere est de parametrer une valeur wakeup_events ou wakeup_watermark qui generera un signal si un certain nombre d'echantillons ou d'octets ont ete ecrits dans le tampon circulaire mmap. Dans ce cas, un signal de type POLL_IN est envoye. L'autre facon est d'utiliser l'ioctl PERF_EVENT_IOC_REFRESH. Cet ioctl ajoute a un compteur qui decremente a chaque fois que l'evenement depasse. Quand il est non nul, un signal POLL_IN est envoye en cas de depassement, mais une fois que la valeur a atteint 0, un signal de type POLL_HUP est envoye et l'evenement sous-jacent est desactive. Le rafraichissement d'un leader de groupe d'evenements rafraichit toute la fratrie, et un rafraichissement avec un parametre de 0 active un rafraichissement infini. Ces comportements ne sont pas geres et ne devraient pas etre utilises. A partir de Linux 3.18, POLL_HUP est initie si l'evenement a surveiller est rattache a un processus different et que celui-ci se termine. Instruction rdpmc A partir de Linux 3.4 sur x86, l'instruction rdpmc permet d'obtenir des lectures a faible latence sans avoir a entrer dans le noyau. Remarquez que l'utilisation de rdpmc n'est pas necessairement plus rapide que d'autres methodes pour lire des valeurs d'evenement. Cette prise en charge peut etre detectee avec le champ cap_usr_rdpmc dans la page mmap ; de la documentation pour calculer les valeurs d'evenement est disponible dans cette section. A l'origine, quand la prise en charge de rdpmc a ete activee, tout processus (pas seulement ceux ayant un evenement perf actif) pouvait utiliser l'instruction rdpmc pour acceder aux compteurs. A partir de Linux 4.0, la prise en charge de rdpmc n'est autorisee que si un evenement est actuellement active dans le contexte d'un processus. Pour restaurer l'ancien comportement, inscrivez la valeur 2 dans /sys/devices/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'evenement individuel ou le groupe d'evenements indique par l'argument de descripteur de fichier. Si le bit PERF_IOC_FLAG_GROUP est defini dans l'argument ioctl, alors tous les evenements d'un groupe sont actives, meme si l'evenement indique n'est pas le leader de groupe (mais consultez la section BOGUES). PERF_EVENT_IOC_DISABLE Cela desactive le compteur individuel ou le groupe d'evenements indique par l'argument de descripteur de fichier. L'activation ou la desactivation du leader d'un groupe active ou desactive la totalite du groupe. Autrement dit pendant que le leader de groupe est desactive, aucun des compteurs du groupe ne compte. L'activation ou la desactivation d'un membre du groupe qui n'est pas le leader arrete ce son compteur, mais n'affecte aucun des autres compteurs. Si le bit PERF_IOC_FLAG_GROUP est defini dans l'argument ioctl, alors tous les evenements d'un groupe sont desactives, meme si l'evenement indique n'est pas le leader de groupe (mais consultez la section BOGUES). PERF_EVENT_IOC_REFRESH Les compteurs de depassements non herites peuvent utiliser cela pour activer un compteur pour un nombre de depassements indique par l'argument, apres lequel il est desactive. Les appels suivants de cet ioctl ajoutent la valeur de l'argument au decompte actuel. Un signal avec POLL_IN defini est envoye a chaque depassement jusqu'a ce que ce compte atteigne 0 ; quand cela arrive, un signal avec POLL_HUP defini est envoye et l'evenement est desactive. L'utilisation de 0 comme argument est considere comme un comportement indefini. PERF_EVENT_IOC_RESET Redefinir le compte d'evenements indique par l'argument a zero. Cela ne reinitialise que les decomptes ; reinitialiser les valeurs de multiplexage time_enabled et time_running est impossible. Si le bit PERF_IOC_FLAG_GROUP est defini dans l'argument ioctl, alors tous les evenements d'un groupe sont reinitialises, meme si l'evenement indique n'est pas le leader de groupe (mais consultez la section BOGUES). PERF_EVENT_IOC_PERIOD Cela met a jour la periode de depassement pour l'evenement. Depuis Linux 3.7 (sur ARM) et Linux 3.14 (toutes les autres architectures), la nouvelle periode est effective immediatement. Sur les noyaux precedents, la nouvelle periode n'etait effective qu'apres le depassement suivant. L'argument est un pointeur vers une valeur sur 64 bits contenant la nouvelle periode voulue. Avant Linux 2.6.36, cet ioctl echouait toujours a cause d'un bogue dans le noyau. PERF_EVENT_IOC_SET_OUTPUT Cela indique au noyau de signaler les notifications d'evenement dans le descripteur de fichier indique plutot que dans celui par defaut. Les descripteurs de fichier doivent tous etre sur le meme processeur. L'argument indique le descripteur de fichier desire ou -1 si la sortie devrait etre ignoree. PERF_EVENT_IOC_SET_FILTER (depuis Linux 2.6.33) Cela ajoute un filtre ftrace a cet evenement. 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'evenement pour le descripteur de fichier d'evenement donne. L'argument est un pointeur vers un entier non signe de 64 bits pour garder le resultat. PERF_EVENT_IOC_SET_BPF (depuis Linux 4.1) Cela permet de rattacher un programme Berkeley Packet Filter (BPF) a un evenement de tracage d'un kprobe existant. Vous avez besoin des privileges CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN pour utiliser cet ioctl. Le parametre est un descripteur de fichier de programme BPF cree par un appel systeme bpf(2) precedent. PERF_EVENT_IOC_PAUSE_OUTPUT (depuis Linux 4.7) Cela permet de mettre en pause et de relancer le tampon circulaire d'un evenement. Un tampon mis en pause n'empeche pas la generation d'echantillons mais il les desactive. Les echantillons desactives sont consideres comme perdus et provoquent la generation d'un PERF_RECORD_LOST si possible. Un signal de depassement peut toujours etre recupere par l'echantillon desactive bien que le tampon circulaire reste vide. Le parametre est un entier 32 bits non signe. Une valeur autre que zero met en pause le tampon circulaire alors qu'une valeur de zero reactive le tampon circulaire. PERF_EVENT_MODIFY_ATTRIBUTES (depuis Linux 4.17) Cela permet de modifier un evenement existant sans le gaspillage de fermeture et reouverture d'un nouvel evenement. Actuellement, cela n'est pris en charge que pour les evenements de points d'arret. L'argument est un pointeur vers une structure perf_event_attr contenant les parametres de l'evenement mis a jour. PERF_EVENT_IOC_QUERY_BPF (depuis Linux 4.16) Cela permet de chercher les programmes Berkeley Packet Filter (BPF) rattaches a un point de tracage kprobe existant. Vous ne pouvez rattacher qu'un programme BPF par evenement mais vous pouvez avoir plusieurs evenements rattaches a un point de tracage. Rechercher cette valeur sur un evenement de point de tracage renvoie l'identifiant de tous les programmes BPF dans tous les evenements rattaches au point de tracage. Il vous faut les privileges 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 rattaches. Le tableau ids est rempli par l'identifiant de chaque programme BPF rattache. S'il y a plus de programmes que de place dans le tableau, le noyau renverra ENOSPC et ids_len indiquera le nombre d'identifiants de programme copies avec succes. Utilisation de prctl(2) Un processus peut activer ou desactiver tous les groupes d'evenements actuellement ouverts en utilisant les operations PR_TASK_PERF_EVENTS_ENABLE et PR_TASK_PERF_EVENTS_DISABLE de prctl(2). Cela ne s'applique qu'aux evenements crees localement par le processus appelant. Cela ne s'applique pas aux evenements crees par d'autres processus rattaches au processus appelant ou aux evenements d'un processus parent. Cela n'active et desactive que les leaders de groupe, aucun autre des membres des groupes. Fichiers de configuration relatifs a perf_event Fichiers de /proc/sys/kernel/ /proc/sys/kernel/perf_event_paranoid Le fichier perf_event_paranoid peut etre defini pour restreindre l'acces aux compteurs de performance : 2 ne permettre que les mesures en espace utilisateur (par defaut depuis Linux 4.6). 1 permettre a la fois les mesures noyau et utilisateur (par defaut avant Linux 4.6). 0 permettre l'acces aux donnees specifiques au processeur sauf les echantillons de point de trace bruts ; -1 pas de restriction. L'existence du fichier perf_event_paranoid est la methode officielle pour determiner si un noyau gere perf_event_open(). /proc/sys/kernel/perf_event_max_sample_rate Cela definit le taux d'echantillonnage maximal. Un reglage trop haut peut permettre aux utilisateurs d'echantillonner a un taux ayant un impact sur les performances de la machine et eventuellement planter la machine. La valeur par defaut est 100 000 (echantillons par seconde). /proc/sys/kernel/perf_event_max_stack Ce fichier definit la profondeur maximale des entrees de trame de pile signalees lors de la generation 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 defaut est 516 (ko). Fichiers de /sys/bus/event_source/devices/ Depuis Linux 2.6.34, le noyau permet d'avoir plusieurs PMU disponibles pour la surveillance. Les informations sur la facon de programmer ces PMU sont disponibles dans /sys/bus/event_source/devices/. Tous les sous-repertoires correspondent a une PMU differente. /sys/bus/event_source/devices/*/type (depuis Linux 2.6.38) Cela contient un entier qui peut etre utilise dans le champ type de perf_event_attr pour indiquer la volonte d'utiliser cette PMU. /sys/bus/event_source/devices/cpu/rdpmc (depuis Linux 3.4) Si ce fichier est 1, alors l'acces direct de l'espace utilisateur aux registres de compteurs de performance est permis a l'aide de l'instruction rdpmc. Cela peut etre desactive en ecrivant 0 dans le fichier. A partir de Linux 4.0, le comportement a change pour que 1 n'autorise desormais que l'acces aux processus ayant des evenements perf actifs et que 2 indique l'ancien comportement autorisant l'acces a n'importe quoi. /sys/bus/event_source/devices/*/format/ (depuis Linux 3.4) Ce sous-repertoire contient des renseignements sur les sous-champs specifiques a 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 configuration, suivi d'un deux-points, suivi d'une suite d'intervalles d'entiers separes par des virgules. Par exemple, le fichier event pourrait contenir la valeur config1:1,6-10,44 qui indique que l'evenement est un attribut qui occupe les bits 1, 6 a 10 et 44 de perf_event_attr::config1. /sys/bus/event_source/devices/*/events/ (depuis Linux 3.4) Ce sous-repertoire contient des fichiers avec des evenements predefinis. Les contenus sont des chaines decrivant les reglages d'evenements exprimes en termes des champs trouves dans le repertoire ./format/ mentionne precedemment. Ce ne sont pas necessairement des listes completes de tous les evenements pris en charge par une PMU, mais generalement un sous-ensemble d'evenements juges utiles ou interessants. Le contenu de chaque fichier est une liste de noms d'attribut separes par des virgules. Chaque entree a une valeur facultative (soit hexadecimale, soit decimale). Si aucune valeur n'est indiquee, alors un champ d'un seul bit de valeur 1 est suppose. Un exemple d'entree pourrait ressembler a event=0x2,inv,ldlat=3. /sys/bus/event_source/devices/*/uevent Ce fichier est l'interface standard de peripherique du noyau pour l'injection d'evenements de branchement a chaud. /sys/bus/event_source/devices/*/cpumask (depuis Linux 3.7) Le fichier cpumask contient une liste d'entiers separes par des virgules indiquant un numero representatif de processeur pour chaque socket (boitier) de la carte mere. C'est necessaire lors de la definition d'evenements uncore ou northbridge, puisque ces PMU presentent des evenements a travers tous les sockets. VALEUR RENVOYEE En cas de succes, perf_event_open() renvoie le nouveau descripteur de fichier. En cas d'echec, -1 est renvoye et errno est defini pour indiquer l'erreur. ERREURS Les erreurs renvoyees par perf_event_open() peuvent etre incoherentes et peuvent varier suivant les architectures de processeur et les unites de surveillance des performances. E2BIG Renvoye 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 gerer et que les octets supplementaires ne sont pas zero. Lorsque E2BIG est renvoye, le champ size de perf_event_attr est remplace, par le noyau, par la taille attendue de la structure. EACCES Renvoye quand l'evenement demande necessite les droits CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN (ou un reglage paranoiaque de perf_event plus permissif). Quelques cas habituels ou un processus non privilegie pourrait tomber sur cette erreur : l'attachement a un processus appartenant a un autre utilisateur, la surveillance de tous les processus sur un processeur donne (c'est-a-dire en indiquant -1 pour l'argument pid) et l'absence de reglage exclude_kernel quand le reglage paranoiaque le necessite. EBADF Renvoye si le descripteur de fichier group_fd n'est pas valable, ou, si PERF_FLAG_PID_CGROUP est defini, si le descripteur de fichier cgroup dans pid n'est pas valable. EBUSY (depuis Linux 4.1) Renvoye si un evenement a deja un acces exclusif a la PMU. EFAULT Renvoye si le pointeur attr pointe vers un adresse de memoire non valable. EINTR Renvoye si on essaie de melanger la gestion de perf et de ftrace pour un uprobe. EINVAL Renvoye si l'evenement indique n'est pas valable. De nombreuse raisons sont possibles pour cela. Une liste non exhaustive : sample_freq est plus grand que le reglage maximal ; le cpu a surveiller n'existe pas ; read_format est hors intervalle ; sample_type est hors intervalle ; la valeur flags est hors intervalle ; exclusive ou pinned sont definis et l'evenement n'est pas un leader de groupe ; les valeurs config de l'evenement sont hors de l'intervalle ou des bits reserves definis ; l'evenement generique selectionne n'est pas pris en charge ; la place est insuffisante pour ajouter l'evenement selectionne. EMFILE Chaque evenement ouvert utilise un descripteur de fichier. Si un grand nombre d'evenements est ouvert, la limite de descripteurs de fichier par processus sera atteinte et aucun evenement supplementaire ne pourra etre cree. ENODEV Renvoye quand l'evenement implique une fonctionnalite non prise en charge par le processeur actuel. ENOENT Renvoye si le reglage type n'est pas valable. Cette erreur est egalement renvoyee pour certains evenements generiques non pris en charge. ENOSPC Avant Linux 3.3, s'il manquait de la place pour l'evenement, ENOSPC etait renvoye. Dans Linux 3.3, cela a ete modifie en EINVAL. ENOSPC est toujours renvoye en cas de tentative d'ajout de plus d'evenements de point d'arret que permis par le materiel. ENOSYS Renvoye si PERF_SAMPLE_STACK_USER est defini dans sample_type et que ce n'est pas pris en charge par le materiel. EOPNOTSUPP Renvoye si un evenement necessitant une fonctionnalite specifique du materiel est demande alors qu'il n'y a pas de prise en charge materielle. Cela comprend la demande d'evenement a faible derapage si ce n'est pas pris en charge, le suivi de branchement s'il n'est pas pris en charge, l'echantillonnage si aucune interruption PMU n'est disponible et les piles de branchement pour les evenements logiciels. EOVERFLOW (depuis Linux 4.8) Renvoye si PERF_SAMPLE_CALLCHAIN est demande et si sample_max_stack est plus grand que le maximum indique dans /proc/sys/kernel/perf_event_max_stack. EPERM Renvoye sur beaucoup d'architectures (mais pas toutes) quand un des reglages exclude_hv, exclude_idle, exclude_user ou exclude_kernel non pris en charge est indique. Cela peut aussi arriver, comme avec EACCES, quand l'evenement demande necessite les droits CAP_PERFMON (depuis Linux 5.8) ou CAP_SYS_ADMIN (ou un reglage paranoiaque de perf_event plus permissif). Cela comprend le reglage d'un point d'arret sur une adresse du noyau et (depuis Linux 3.13) le reglage d'un point de trace de fonction du noyau. ESRCH Renvoye en cas de tentative d'attachement a un processus qui n'existe pas. STANDARDS Linux. HISTORIQUE perf_event_open() a ete introduite dans Linux 2.6.31 mais etait appelee perf_counter_open(). Elle a ete renommee dans Linux 2.6.32. NOTES Le moyen officiel pour savoir si la prise en charge de perf_event_open() est activee est de verifier si le fichier /proc/sys/kernel/perf_event_paranoid existe. La capacite CAP_PERFMON (depuis Linux 5.58) fournit une approche securisee de la surveillance des performances et des operations de visibilite d'un systeme suivant un principe du moindre privilege (POSIX IEEE 1003.1e). Ces modalites d'acces qui utilisent CAP_PERFMON au lieu du beaucoup plus puissant CAP_SYS_ADMIN enleve des chances d'une mauvaise utilisation des droits et rend les operations plus securisees. L'utilisation de CAP_SYS_ADMIN pour la surveillance securisee des performances du systeme et une meilleure visibilite est deconseillee et vous devriez preferer la capacite CAP_PERFMON. BOGUES L'option F_SETOWN_EX de fcntl(2) est necessaire pour obtenir correctement les signaux de depassement dans les threads. Cela a ete introduit dans Linux 2.6.32. Avant Linux 3.3 (en tout cas pour x86), le noyau ne verifiait pas si les evenements pouvaient etre programmes ensemble avant le moment de la lecture. La meme chose arrive sur tous les noyaux connus si le watchdog NMI est active. Cela signifie que pour voir si un ensemble donne d'evenements fonctionne, il faut appeler perf_event_open(), demarrer, puis lire avant d'etre sur de pouvoir obtenir des mesures valables. Avant Linux 2.6.34, les contraintes d'evenements n'etaient pas renforcees par le noyau. Dans ce cas, certains evenements renverraient << 0 >> silencieusement si le noyau les avait programmes dans un emplacement de compteur incorrect. Avant Linux 2.6.34, a cause d'un bogue lors du multiplexage, de mauvais resultats pouvaient etre renvoyes. Les noyaux de Linux 2.6.35 a Linux 2.6.39 peuvent planter rapidement si inherit est active et que de nombreux threads sont demarres. Avant Linux 2.6.35, PERF_FORMAT_GROUP ne fonctionnait pas avec les processus attaches. A cause d'un bogue dans le code du noyau entre Linux 2.6.36 et Linux 3.0, le champ watermark etait ignore et agissait comme si wakeup_event avait ete choisi si l'union contenait une valeur non nulle. De Linux 2.6.31 a Linux 3.4, l'argument ioctl PERF_IOC_FLAG_GROUP etait casse et operait a repetition sur l'evenement indique au lieu d'iterer parmi tous les evenements d'une fratrie d'un groupe. De Linux 3.4 a Linux 3.11, les bits mmap cap_usr_rdpmc et cap_usr_time etaient associes au meme emplacement. Le code devrait plutot etre modifie pour utiliser les nouveaux champs cap_user_rdpmc et cap_user_time a la place. Verifiez toujours deux fois les resultats. Plusieurs evenements generalises ont eu de fausses valeurs. Par exemple, les branchements retires 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 decompte total d'instructions d'un appel a printf(3). #include #include #include #include #include #include #include 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 decompte d'instructions pour ce printf\n"); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(count)); printf("%lld instructions utilisees\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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 19 novembre 2023 perf_event_open(2)