Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       perf_event_open - настройка слежения за производительностью

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <linux/perf_event.h>    /* определения констант PERF_* */
       #include <linux/hw_breakpoint.h> /* определения констант HW_* */
       #include <sys/syscall.h>         /* определения констант SYS_* */
       #include <unistd.h>

       int syscall(SYS_perf_event_open, struct perf_event_attr *attr,
                   pid_t pid, int cpu, int group_fd, unsigned long flags);

       Note:   glibc  provides  no  wrapper  for  perf_event_open(),  necessitating  the  use  of
       syscall(2).

ОПИСАНИЕ

       Получая список параметров, perf_event_open() возвращает файловый дескриптор, который можно
       использовать в последующих вызовах (read(2), mmap(2), prctl(2), fcntl(2) и т. п.).

       Вызов   perf_event_open()  создаёт  файловый  дескриптор,  через  который  можно  получать
       измерения производительности. Каждый файловый дескриптор соответствует одному  измеряемому
       событию; события можно группировать для одновременного измерения.

       События можно включать и выключать двумя способами: через ioctl(2) и через prctl(2). Когда
       событие отключено,  оно  не  учитывается  и  не  генерирует  переполнения,  но  продолжает
       существовать и содержать своё значение счётчика.

       События   бывают   двух   видов:   подсчитывающие   (counting)   и  измеряющие  (sampled).
       Подсчитывающее событие используется  для  сложения  числа  произошедших  событий.  Обычно,
       результат  подсчёта  событий  выбирается  с  помощью  вызова  read(2).  Измеряющее событие
       периодически пишет значения измерения в буфер, который доступен через вызов mmap(2).

   Аргументы
       Аргументы pid и cpu позволяют задать отслеживаемый процесс и ЦП:

       pid == 0 и cpu == -1
              Это позволяет измерять вызывающий процесс/нить на любом ЦП.

       pid == 0 и cpu >= 0
              Это позволяет измерять вызывающий процесс/нить только, когда выполнение  происходит
              на указанном ЦП.

       pid > 0 и cpu == -1
              Это позволяет измерять указанный процесс/нить на любом ЦП.

       pid > 0 и cpu >= 0
              Это  позволяет  измерять указанный процесс/нить только, когда выполнение происходит
              на указанном ЦП.

       pid == -1 и cpu >= 0
              This  measures  all  processes/threads  on  the  specified  CPU.    This   requires
              CAP_PERFMON    (since    Linux    5.8)    or    CAP_SYS_ADMIN   capability   or   a
              /proc/sys/kernel/perf_event_paranoid value of less than 1.

       pid == -1 и cpu == -1
              Это некорректные значения и будет возвращена ошибка.

       When pid is greater than zero, permission to perform  this  system  call  is  governed  by
       CAP_PERFMON (since Linux 5.9) and a ptrace access mode PTRACE_MODE_READ_REALCREDS check on
       older Linux versions; see ptrace(2).

       The group_fd argument allows event groups to be created.  An event  group  has  one  event
       which  is the group leader.  The leader is created first, with group_fd = -1.  The rest of
       the group members are created with subsequent perf_event_open()  calls with group_fd being
       set  to  the  file  descriptor of the group leader.  (A single event on its own is created
       with group_fd = -1 and is considered to be a group with only 1 member.)  An event group is
       scheduled onto the CPU as a unit: it will be put onto the CPU only if all of the events in
       the group can be put onto the CPU.  This means that the values of the member events can be
       meaningfully  compared—added,  divided  (to  get ratios), and so on—with each other, since
       they have counted events for the same set of executed instructions.

       Аргумент flags формируется с помощью объединения логической операцией ИЛИ нуля  или  более
       следующих значений:

       PERF_FLAG_FD_CLOEXEC (начиная с Linux 3.14)
              Этот флаг включает флаг close-on-exec на созданном файловом дескрипторе события, то
              есть файловый дескриптор автоматически закрывается при execve(2).  Установка  флага
              close-on-exec  при  создании,  а не в процессе работы с помощью fcntl(2), позволяет
              избежать   потенциальной   состязательности,   когда   вызывающая   нить   вызывает
              perf_event_open() и fcntl(2) одновременно с запуском другой нитью вызовов fork(2) и
              execve(2).

       PERF_FLAG_FD_NO_GROUP
              Этот флаг указывает событию игнорировать параметр  group_fd,  если  не  выполняется
              настройка перенаправления вывода с помощью флага PERF_FLAG_FD_OUTPUT.

       PERF_FLAG_FD_OUTPUT (не работает, начиная с Linux 2.6.35)
              Этот флаг переключает вывод измерений с буфера mmap в событие, указанное group_fd.

       PERF_FLAG_PID_CGROUP (начиная с Linux 2.6.39)
              Этот  флаг  включает поконтейнерное системное слежение. Контейнер — это абстракция,
              которая изолирует набор ресурсов для их точного расходования (ЦП, память и т.  п.).
              В  этом режиме событие измеряется только, если нить выполняется в отслеживаемом ЦП,
              принадлежащем назначенному контейнеру (cgroup). Значение cgroup задаётся переданным
              файловым  дескриптором,  открываемом  в  его  каталоге в файловой системе cgroupfs.
              Например, если отслеживаемая cgroup называется test,  то  файловый  дескриптор  для
              /dev/cgroup/test  (предполагается,  что cgroupfs смонтирована в /dev/cgroup) должен
              передаваться как параметр pid. Слежение за cgroup  доступно  только  для  системных
              событий и поэтому требуется дополнительных прав.

       Структура perf_event_attr предоставляет подробную информацию о создаваемом событии.

           struct perf_event_attr {
               __u32 type;         /* тип события */
               __u32 size;         /* размер структуры атрибутов */
               __u64 config;       /* настройки для типа */

               union {
                   __u64 sample_period;    /* период выборки */
                   __u64 sample_freq;      /* частота выборки */
               };

               __u64 sample_type;  /* значения, включённые в измерение */
               __u64 read_format;  /* значения, возвращаемые при чтении */

               __u64 disabled       : 1,   /* off by default */
                     inherit        : 1,   /* children inherit it */
                     pinned         : 1,   /* must always be on PMU */
                     exclusive      : 1,   /* only group on PMU */
                     exclude_user   : 1,   /* don't count user */
                     exclude_kernel : 1,   /* don't count kernel */
                     exclude_hv     : 1,   /* don't count hypervisor */
                     exclude_idle   : 1,   /* don't count when idle */
                     mmap           : 1,   /* include mmap data */
                     comm           : 1,   /* include comm data */
                     freq           : 1,   /* use freq, not period */
                     inherit_stat   : 1,   /* per task counts */
                     enable_on_exec : 1,   /* next exec enables */
                     task           : 1,   /* trace fork/exit */
                     watermark      : 1,   /* wakeup_watermark */
                     precise_ip     : 2,   /* skid constraint */
                     mmap_data      : 1,   /* non-exec mmap data */
                     sample_id_all  : 1,   /* sample_type all events */
                     exclude_host   : 1,   /* don't count in host */
                     exclude_guest  : 1,   /* don't count in guest */
                     exclude_callchain_kernel : 1,
                                           /* exclude kernel callchains */
                     exclude_callchain_user   : 1,
                                           /* exclude user callchains */
                     mmap2          :  1,  /* include mmap with inode data */
                     comm_exec      :  1,  /* flag comm events that are
                                              due to exec */
                     use_clockid    :  1,  /* use clockid for time fields */
                     context_switch :  1,  /* context switch data */
                     write_backward :  1,  /* Write ring buffer from end
                                              to beginning */
                     namespaces     :  1,  /* include namespaces data */
                     ksymbol        :  1,  /* include ksymbol events */
                     bpf_event      :  1,  /* include bpf events */
                     aux_output     :  1,  /* generate AUX records
                                              instead of events */
                     cgroup         :  1,  /* include cgroup events */
                     text_poke      :  1,  /* include text poke events */
                     build_id       :  1,  /* use build id in mmap2 events */
                     inherit_thread :  1,  /* children only inherit */
                                           /* if cloned with CLONE_THREAD */
                     remove_on_exec :  1,  /* event is removed from task
                                              on exec */
                     sigtrap        :  1,  /* send synchronous SIGTRAP
                                              on event */

                     __reserved_1   : 26;

               union {
                   __u32 wakeup_events;    /* пробуждаться каждые n событий */
                   __u32 wakeup_watermark; /* байт до пробуждения */
               };

               __u32     bp_type;          /* тип точки останова */

               union {
                   __u64 bp_addr;          /* адрес точки останова */
                   __u64 kprobe_func;      /* для perf_kprobe */
                   __u64 uprobe_path;      /* для perf_uprobe */
                   __u64 config1;          /* расширение of config */
               };

               union {
                   __u64 bp_len;           /* breakpoint length */
                   __u64 kprobe_addr;      /* with kprobe_func == NULL */
                   __u64 probe_offset;     /* for perf_[k,u]probe */
                   __u64 config2;          /* extension of config1 */
               };
               __u64 branch_sample_type;   /* enum perf_branch_sample_type */
               __u64 sample_regs_user;     /* user regs to dump on samples */
               __u32 sample_stack_user;    /* size of stack to dump on
                                              samples */
               __s32 clockid;              /* clock to use for time fields */
               __u64 sample_regs_intr;     /* regs to dump on samples */
               __u32 aux_watermark;        /* aux bytes before wakeup */
               __u16 sample_max_stack;     /* max frames in callchain */
               __u16 __reserved_2;         /* align to u64 */
               __u32 aux_sample_size;      /* max aux sample size */
               __u32 __reserved_3;         /* align to u64 */
               __u64 sig_data;             /* user data for sigtrap */

           };

       Описание полей структуры perf_event_attr:

       type   В этом поле указывается общий тип события. Может быть одно из следующих значений:

              PERF_TYPE_HARDWARE
                     Одно  из  «общих»   аппаратных  событий,  предоставляется  ядром.  Подробней
                     смотрите в описании поля config.

              PERF_TYPE_SOFTWARE
                     Одно  из  программных  событий,  предоставляется  ядром  (даже,   если   нет
                     аппаратной поддержки).

              PERF_TYPE_TRACEPOINT
                     Точка    трассировки,    предоставляется   ядерной   инфраструктурой   точек
                     трассировки.

              PERF_TYPE_HW_CACHE
                     Событие  аппаратного  кэша.  Создаётся  специальным  кодированием,  смотрите
                     описание к полю config.

              PERF_TYPE_RAW
                     «Неструктурированное», определяемое реализацией событие из поля config.

              PERF_TYPE_BREAKPOINT (начиная с Linux 2.6.33)
                     Аппаратная   точка   останова,  предоставляемая  ЦП.  Точки  останова  можно
                     настроить  на  событие  чтения/записи  по  адресу,  а  также  на  выполнение
                     инструкции по определённому адресу.

              динамический PMU
                     Начиная  с Linux 2.6.38, perf_event_open() поддерживает несколько PMU. Чтобы
                     задать используемый PMU,  его  указывают  в  значении  type,  экспортируемое
                     ядром.  Нужное  значение  можно  найти в файловой системе sysfs: для каждого
                     экземпляра       PMU       создаётся       подкаталог       в       каталоге
                     /sys/bus/event_source/devices.   В   каждом   подкаталоге  есть  файл  type,
                     содержащий целое число, которое можно использовать в поле type. Например,  в
                     /sys/bus/event_source/devices/cpu/type  содержится значение для PMU ядра ЦП,
                     которое, обычно равно 4.

              kprobe и uprobe (начиная с Linux 4.17)
                     Эти два динамических PMU создают kprobe/uprobe и  присоединяют  к  файловому
                     дескриптору,  сгенерованному  perf_event_open. kprobe/uprobe будет уничтожен
                     при уничтожении файлового дескриптора. Подробности смотрите в описании полей
                     kprobe_func, uprobe_path, kprobe_addr и probe_offset.

       size   Размер  структуры  perf_event_attr совместимости. Присвоение значения sizeof(struct
              perf_event_attr) позволяет ядру видеть размер структуры во время компиляции.

              Соответствующее  определение  PERF_ATTR_SIZE_VER0  равно  64;  это  размер   первой
              опубликованной  структуры.  Значение  PERF_ATTR_SIZE_VER1  равно  72, соответствует
              добавленным в Linux 2.6.33 точкам останова. Значение PERF_ATTR_SIZE_VER2 равно  80,
              соответствует  добавленным в Linux 3.4 ветвям замеров. Значение PERF_ATTR_SIZE_VER3
              равно  96,  соответствует  добавленным  в  Linux  3.7  полям   sample_regs_user   и
              sample_stack_user.    Значение   PERF_ATTR_SIZE_VER4   равно   104,   соответствует
              добавленному в Linux 3.19 полю sample_regs_intr. Значение PERF_ATTR_SIZE_VER5 равно
              112, соответствует добавленному в in Linux 4.1 полю aux_watermark.

       config Здесь  указывается  требуемое  событие  в  сочетании  с  полем type. Поля config1 и
              config2 также учитываются, если 64 бит недостаточно для полного  описания  события.
              Кодирование значения этих полей зависит от события.

              Есть  несколько  способов  присвоения  значения  полю  config,  которые  зависят от
              значения описанного ранее поля type. Содержимое различных возможных настроек config
              выделяется по type.

              Если  type равно PERF_TYPE_HARDWARE, то измеряется одно из общих аппаратных событий
              ЦП. Не все из них доступны  на  всех  платформах.  В  config  может  быть  одно  из
              следующих значений:

                   PERF_COUNT_HW_CPU_CYCLES
                          Общее  количество  циклов.  Опасайтесь  того,  что  происходит во время
                          частотного масштабирования ЦП.

                   PERF_COUNT_HW_INSTRUCTIONS
                          Запоздалые инструкции (retired instructions). Осторожно,  могут  влиять
                          различные ситуации, в основном, подсчёт аппаратных прерываний.

                   PERF_COUNT_HW_CACHE_REFERENCES
                          Доступ  к кэшу. Обычно, учитывается доступ к кэшу последнего уровня, но
                          для различных ЦП может быть  по-разному.  Может  включать  сообщения  о
                          предварительной выборке и связности; опять же, зависит от ЦП.

                   PERF_COUNT_HW_CACHE_MISSES
                          Промахи   кэша.   Обычно,  отражает  промахи  кэша  последнего  уровня;
                          предназначена     для     использования     вместе      с      событием
                          PERF_COUNT_HW_CACHE_REFERENCES для подсчёта коэффициента промахов кэша.

                   PERF_COUNT_HW_BRANCH_INSTRUCTIONS
                          Запоздалые   инструкции   ветвления.  До  Linux  2.6.35  использовалось
                          неправильное сообщение на процессорах AMD.

                   PERF_COUNT_HW_BRANCH_MISSES
                          Непредсказанные инструкции ветвления.

                   PERF_COUNT_HW_BUS_CYCLES
                          Количество циклов шины, которое может отличаться от  общего  количества
                          циклов.

                   PERF_COUNT_HW_STALLED_CYCLES_FRONTEND (начиная с Linux 3.0)
                          Блокировано циклов во время проблемы.

                   PERF_COUNT_HW_STALLED_CYCLES_BACKEND (начиная с Linux 3.0)
                          Блокировано циклов во время запаздывания.

                   PERF_COUNT_HW_REF_CPU_CYCLES (начиная с Linux 3.3)
                          Общее    количество    циклов;   не   подвержено   влиянию   частотного
                          масштабирования ЦП.

              Если значение type равно PERF_TYPE_SOFTWARE,  то  измеряются  программные  события,
              предоставляемые ядром. Значением config может быть одно из следующих:

                   PERF_COUNT_SW_CPU_CLOCK
                          Сообщить  о часах ЦП, таймере высокого разрешения, работающем на каждом
                          ЦП.

                   PERF_COUNT_SW_TASK_CLOCK
                          Сообщить о часах выполняющейся задачи.

                   PERF_COUNT_SW_PAGE_FAULTS
                          Сообщить о количестве сбойных страниц.

                   PERF_COUNT_SW_CONTEXT_SWITCHES
                          Подсчёт числа переключений контекста. До Linux  2.6.34,  это  считалось
                          событиями пользовательского пространства, теперь об этом сообщается как
                          о происходящем в ядре.

                   PERF_COUNT_SW_CPU_MIGRATIONS
                          Сообщить сколько раз процесс перемещался в другой ЦП.

                   PERF_COUNT_SW_PAGE_FAULTS_MIN
                          Сообщить о количестве незначительных промахов страниц. Они не связаны с
                          обработкой дисковых операций ввода-вывода.

                   PERF_COUNT_SW_PAGE_FAULTS_MAJ
                          Сообщить  о  количестве  значительных  промахов  страниц. Они связаны с
                          обработкой дисковых операций ввода-вывода.

                   PERF_COUNT_SW_ALIGNMENT_FAULTS (начиная с Linux 2.6.33)
                          Сообщить  о  количестве  ошибок  выравнивания.  Они  возникают,   когда
                          происходит  доступ  к  памяти  по  невыровненному  адресу;  ядро  может
                          обработать такую ситуацию, но  это снижает  производительность.  Бывает
                          только на некоторых архитектурах (на x86 — никогда).

                   PERF_COUNT_SW_EMULATION_FAULTS (начиная с Linux 2.6.33)
                          Сообщить  о  количестве ошибок эмуляции. Ядро иногда попадает в ловушки
                          нереализованных  инструкций   и   эмулирует   их   в   пользовательском
                          пространстве. Это может негативно отражаться на производительности.

                   PERF_COUNT_SW_DUMMY (начиная с Linux 3.12)
                          Заместитель   события,  которое  ничего  не  подсчитывает.  This  is  a
                          placeholder event that counts nothing.   Информационные  образцы  типов
                          записей,  таких  как  mmap  или  comm,  должны  быть связаны с активным
                          событием. Данное пустое событие позволяет  собирать  такие  записи  без
                          необходимости в подсчитывающем событии.

                   PERF_COUNT_SW_BPF_OUTPUT (since Linux 4.4)
                          This  is  used  to generate raw sample data from BPF.  BPF programs can
                          write to this event using bpf_perf_event_output helper.

                   PERF_COUNT_SW_CGROUP_SWITCHES (since Linux 5.13)
                          This counts context switches to a task in a different cgroup.  In other
                          words,  if  the  next  task  is  in the same cgroup, it won't count the
                          switch.

              Если  type  равно  PERF_TYPE_TRACEPOINT,  то  измеряется  точки  трассировки  ядра.
              Значение,  используемое  в config, можно получить из debugfs tracing/events/*/*/id,
              если ftrace включён в ядре.

              Если type равно PERF_TYPE_HW_CACHE, то измеряется событие кэша аппаратного ЦП.  Для
              вычисления соответствующего значения config используйте следующую формулу:

                      config = (perf_hw_cache_id) |
                               (perf_hw_cache_op_id << 8) |
                               (perf_hw_cache_op_result_id << 16);

                  где perf_hw_cache_id одно из:

                      PERF_COUNT_HW_CACHE_L1D
                             для измерения кэша данных 1-го уровня

                      PERF_COUNT_HW_CACHE_L1I
                             для измерения кэша инструкций 1-го уровня

                      PERF_COUNT_HW_CACHE_LL
                             для измерения кэша последнего уровня

                      PERF_COUNT_HW_CACHE_DTLB
                             для измерения TLB данных

                      PERF_COUNT_HW_CACHE_ITLB
                             для измерения TLB инструкций

                      PERF_COUNT_HW_CACHE_BPU
                             для измерения модуля предсказания ветвлений

                      PERF_COUNT_HW_CACHE_NODE (начиная с Linux 3.1)
                             для измерения доступа к локальной памяти

                  и perf_hw_cache_op_id одно из:

                      PERF_COUNT_HW_CACHE_OP_READ
                             для доступа на чтение

                      PERF_COUNT_HW_CACHE_OP_WRITE
                             для доступа на запись

                      PERF_COUNT_HW_CACHE_OP_PREFETCH
                             для доступа предварительной выборки

                  и perf_hw_cache_op_result_id одно из:

                      PERF_COUNT_HW_CACHE_RESULT_ACCESS
                             для измерения доступа

                      PERF_COUNT_HW_CACHE_RESULT_MISS
                             для измерения промахов

              Если  type равно PERF_TYPE_RAW, то требуется пользовательское «неструктурированное»
              значение config. Большинство ЦП поддерживают  события,  которые  не  подпадают  под
              «общие»   события.   Они  определяются  реализацией;  смотрите  руководство  на  ЦП
              (например,  документацию Intel Volume 3B или AMD BIOS  и  руководство  разработчика
              ядра).  Для  трансляции ожидаемых значений в этом поле шестнадцатеричных значений в
              perf_event_open() из имён справочников по архитектуре можно использовать библиотеку
              libpfm4.

              Если type равно PERF_TYPE_BREAKPOINT, то присвойте config значение 0. Его параметры
              задаются в других местах.

              Если type равно kprobe или uprobe, установите retprobe (бит 0  в  config,  смотрите
              /sys/bus/event_source/devices/[k,u]probe/format/retprobe)                    равным
              kretprobe/uretprobe.  Дополнительную   информацию   смотрите   в   описании   полей
              kprobe_func, uprobe_path, kprobe_addr и probe_offset.

       kprobe_func, uprobe_path, kprobe_addr и probe_offset
              Эти  поля  описывают  kprobe/uprobe в динамических PMU kprobe и uprobe. Для kprobe:
              используйте kprobe_func и probe_offset,  или  используйте  kprobe_addr  и  оставьте
              kprobe_func равным NULL. Для uprobe: используйте uprobe_path и probe_offset.

       sample_period, sample_freq
              «Измеряющее»  событие генерирует уведомление о переполнении каждые N событий, где N
              указывается  в  sample_period.  У  измеряющего  события  sample_period  >  0.  Если
              происходит  переполнение, то запрашиваемые данные записываются в буфер mmap. В поле
              sample_type указывается какие данные записываются при каждом переполнении.

              Если  вы  хотите  использовать  частоту,  а  не  период,  то   можно   использовать
              sample_freq.  В  этом  случае  установите  флаг  freq.  Ядро  откорректирует период
              измерений, чтобы попытаться  достигнуть  желаемой  частоты.  Частота  измеряется  в
              тактах таймера.

       sample_type
              Различными  битами этого поля определяется какие значения включать в измерение. Они
              будут записаны в кольцевой буфер, который доступен в пользовательском  пространстве
              через  mmap(2). Порядок сохраняемых значений описан в разделе «Разбивка MMAP» ниже;
              он не совпадает с порядком enum perf_event_sample_format.

              PERF_SAMPLE_IP
                     Сохранять указатель инструкций.

              PERF_SAMPLE_TID
                     Сохранять идентификатор процесса и нити.

              PERF_SAMPLE_TIME
                     Сохранять метку времени.

              PERF_SAMPLE_ADDR
                     Сохранять адрес (если используется).

              PERF_SAMPLE_READ
                     Сохранять значения счётчика для всех событий  в  группе,  а  не  только  для
                     лидера группы.

              PERF_SAMPLE_CALLCHAIN
                     Сохранять цепочку вызовов (обратная трассировка стека).

              PERF_SAMPLE_ID
                     Сохранять уникальный идентификатор для открытых лидером группы событий.

              PERF_SAMPLE_CPU
                     Сохранять номер ЦП.

              PERF_SAMPLE_PERIOD
                     Сохранять текущий период измерения.

              PERF_SAMPLE_STREAM_ID
                     Сохранять   уникальный   идентификатор   открытого  события.  В  отличии  от
                     PERF_SAMPLE_ID возвращается реальный идентификатор, а не лидера группы. Этот
                     же идентификатор возвращается PERF_FORMAT_ID.

              PERF_SAMPLE_RAW
                     Сохранять  дополнительные данные, если есть. Обычно возвращаются для событий
                     трассировки.

              PERF_SAMPLE_BRANCH_STACK (начиная с Linux 3.4)
                     Сохранять запись о новых ветвях, предоставляемых  аппаратурой  ветвления  ЦП
                     (например,  Intel  Last  Branch  Record).  Не каждая аппаратура поддерживает
                     данную возможность.

                     В описании поля branch_sample_type показано как выбирать  ветви,  о  которых
                     нужно сообщать.

              PERF_SAMPLE_REGS_USER (начиная с Linux 3.7)
                     Записывать текущее состояние регистров ЦП на уровне пользователя (значения в
                     процессе до вызова ядра).

              PERF_SAMPLE_STACK_USER (начиная с Linux 3.7)
                     Сохранять стек пользовательского уровня для размотки стека.

              PERF_SAMPLE_WEIGHT (начиная с Linux 3.10)
                     Сохранять  данные  аппаратуры,  предоставляющие  весовое  значение,  которое
                     отражает   насколько   затратным  было  измеряемое  событие.  Это  позволяет
                     аппаратуре выявлять затратные события в профиле.

              PERF_SAMPLE_DATA_SRC (начиная с Linux 3.10)
                     Сохранять источник данных: где в иерархии памяти находятся данные, связанные
                     с измеряемое инструкцией. Доступно только, если поддерживается аппаратурой.

              PERF_SAMPLE_IDENTIFIER (начиная с Linux 3.12)
                     Помещать  значение SAMPLE_ID в фиксированном месте записи, или в начале (для
                     измеряемых событий) или в конце (для не измеряемого события).

                     Это было необходимо потому, что поток измерений может  содержать  записи  из
                     различных   источников   событий   с   различными  параметрами  sample_type.
                     Корректный разбор потока событий невозможен,  так  как  для  формата  записи
                     необходимо  найти  SAMPLE_ID,  но  формат невозможно определить без значения
                     какому измерению принадлежит событие (что вызывает циклическую зависимость).

                     Значение PERF_SAMPLE_IDENTIFIER делает поток всегда  анализируемым,  помещая
                     SAMPLE_ID  в  фиксированное расположение, несмотря на уже имеющиеся значения
                     SAMPLE_ID в записях.

              PERF_SAMPLE_TRANSACTION (начиная с Linux 3.13)
                     Сохранять  причины  событий  аварий  транзакционной  памяти  (например,   из
                     поддержки транзакционной памяти Intel TSX).

                     Значение  precise_ip должно быть больше 0 и должно измеряться событие аварии
                     транзакционной памяти или значения не будут  записаны.  Также  отметим,  что
                     некоторые  измерения  perf_event,  такие  как  подсчёт  числа  циклов, могут
                     приводить  к  дополнительным  авариям  (вызванным   прерыванием   во   время
                     транзакции).

              PERF_SAMPLE_REGS_INTR (начиная с Linux 3.19)
                     Сохранять  поднабор  текущего  состояния  регистров ЦП, который определяется
                     sample_regs_intr.  В  отличии  от  PERF_SAMPLE_REGS_USER  будут   возвращены
                     значения  регистров  из  состояния  ядра,  если  произойдёт переполнение при
                     выполнении кода ядра. Если ЦП  аппаратно  поддерживает  измерение  состояния
                     регистра  (PEBS  в  Intel  x86)  и  precise_ip  больше нуля, то возвращаются
                     значения регистров, захваченных аппаратурой во  время  измерения  запоздалой
                     инструкции.

              PERF_SAMPLE_PHYS_ADDR (начиная с Linux 4.13)
                     Records physical address of data like in PERF_SAMPLE_ADDR.

              PERF_SAMPLE_CGROUP (начиная с Linux 5.7)
                     Records  (perf_event)  cgroup ID of the process.  This corresponds to the id
                     field in the PERF_RECORD_CGROUP event.

              PERF_SAMPLE_DATA_PAGE_SIZE (since Linux 5.11)
                     Records page size of data like in PERF_SAMPLE_ADDR.

              PERF_SAMPLE_CODE_PAGE_SIZE (since Linux 5.11)
                     Records page size of ip like in PERF_SAMPLE_IP.

              PERF_SAMPLE_WEIGHT_STRUCT (since Linux 5.12)
                     Records hardware provided weight values like in PERF_SAMPLE_WEIGHT,  but  it
                     can  represent  multiple  values in a struct.  This shares the same space as
                     PERF_SAMPLE_WEIGHT, so users can apply either of those, not  both.   It  has
                     the  following  format  and  the  meaning  of each field is dependent on the
                     hardware implementation.

                  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
              В этом поле задаётся формат данных, возвращаемых read(2) из  файлового  дескриптора
              perf_event_open().

              PERF_FORMAT_TOTAL_TIME_ENABLED
                     Добавлять 64-битное поле time_enabled. Его можно использовать для вычисления
                     общей оценки, если PMU слишком загружено и возникло мультиплексирование.

              PERF_FORMAT_TOTAL_TIME_RUNNING
                     Добавлять 64-битное поле time_running. Его можно использовать для вычисления
                     общей оценки, если PMU слишком загружено и возникло мультиплексирование.

              PERF_FORMAT_ID
                     Добавлять   64-битное  уникальное  значение,  которое  соответствует  группе
                     событий.

              PERF_FORMAT_GROUP
                     Позволить все значения счётчиков в группе событий читать за один проход.

              PERF_FORMAT_LOST  (since Linux 6.0)
                     Adds a 64-bit value that is the number of lost samples for this event.  This
                     would be only meaningful when sample_period or sample_freq is set.

       disabled
              Битом disabled определяется, будет ли счётчик изначально включен или выключен. Если
              выключен, то событие может быть включено позже с  помощью  ioctl(2),  prctl(2)  или
              enable_on_exec.

              Обычно, при создании группы событий значение disabled лидера группы устанавливается
              в 1, а у любого  дочернего  события  disabled  устанавливается  в  0.  Несмотря  на
              disabled  равное  0,  дочерние события не запускаются до тех пор, пока не включится
              лидер группы.

       inherit
              Битом inherit задаётся, должен ли этот счётчик  событий  считать  события  дочерних
              задач,  кроме  указанной  задачи.  Это  применяется только к новым потомкам, а не к
              существующим на момент создания  счётчика  (и  не  к  новым  потомкам  существующих
              потомков).

              Наследование  не работает с некоторыми  комбинациями значений read_format, например
              с PERF_FORMAT_GROUP.

       pinned Битом pinned определяется, что счётчик должен всегда быть на ЦП, если это возможно.
              Применяется  только  к  аппаратным  счётчикам  и  только  для  лидеров группы. Если
              прикреплённый счётчик невозможно поместить на ЦП (например,  потому  что  кончились
              аппаратные  счётчики или возник конфликт с другим событием), то счётчик переводится
              в состояние «ошибки», в котором чтение  возвращает  конец  файла  (т.  е.,  read(2)
              возвращает 0) до тех пор, пока счётчик не будет включен или выключен.

       exclusive
              Битом  exclusive определяется, что когда эта группа счётчиков на ЦП, то должна быть
              только одна группа  использующая  счётчики  ЦП.  В  будущем,  это  может  позволить
              следящим программам поддерживать возможности PMU, необходимые для автономной работы
              без нарушения других аппаратных счётчиков.

              Заметим, что многие неожиданные  ситуации  могут  не  позволить  событиям  с  битом
              exclusive  даже  выполниться.  К  ним  относятся  выполнение любых пользовательских
              системных измерений,  а  также  использование  ядром  счётчиков  производительности
              (включая обычно включённый интерфейс NMI Watchdog Timer).

       exclude_user
              Если  этот  бит  установлен,  то  счётчик  не  учитывает  события,  происходящие  в
              пользовательском пространстве.

       exclude_kernel
              Если  этот  бит  установлен,  то  счётчик  не  учитывает  события,  происходящие  в
              пространстве ядра.

       exclude_hv
              Если  этот  бит  установлен,  то  счётчик  не  учитывает  события,  происходящие  в
              гипервизоре. В основном для PMU, имеющего для этого возможности (такие как  POWER).
              На большинстве машин необходима дополнительная поддержка для измерений гипервизора.

       exclude_idle
              Если  установлен,  то  счётчик не учитывает когда ЦП выполняет задачу простоя. Хотя
              сейчас вы и можете включить его для любого типа события, он  игнорируется  во  всех
              кроме программных событий.

       mmap   Бит mmap включает генерацию измерений PERF_RECORD_MMAP для каждого вызова mmap(2) с
              установленными  битом  PROT_EXEC.  Это  позволяет   инструментам   замечать   новый
              исполняемый код, отображённый в программу (например, общие динамические библиотеки)
              так, чтобы адреса можно было отобразить обратно в первоначальный код.

       comm   Битом comm включается слежение за именем команды процесса,  изменяемого  системными
              вызовами  execve(2)  и  prctl(PR_SET_NAME), а также через запись в /proc/self/comm.
              Если флаг comm_exec также установлен (работает, начиная с  Linux  3.16),  то  можно
              использовать   вспомогательный   флаг  PERF_RECORD_MISC_COMM_EXEC,  чтобы  отличить
              использование execve(2) от остальных.

       freq   Если  этот  бит   установлен,   то   задания   интервала   измерения   используется
              sample_frequency, а не sample_period.

       inherit_stat
              Этот  бит  включает  сохранение  счётчика  событий  при  переключении контекста для
              наследуемых задач. Это полезно только, если установлен бит inherit.

       enable_on_exec
              Если  этот  бит  установлен,  то  счётчик  автоматически  включается  после  вызова
              execve(2).

       task   Если этот бит установлен, то в кольцевой буфер включаются уведомления fork/exit.

       watermark
              Если  установлен,  то  выдаётся  уведомление о переполнении при пересечении границы
              wakeup_watermark. В противном случае, уведомления  о  переполнении  выдаются  после
              wakeup_events измерений.

       precise_ip (начиная с Linux 2.6.35)
              Управляет  размером  ската  (skid). Скат — количество инструкций, выполняемое между
              возникновением интересующего события и когда ядро способно остановиться и  записать
              событие.  Чем  меньше  скат  тем  лучше:  это  приближает события к инструкциям, от
              которых они возникли, но часто значение ограничивается аппаратурой.

              Возможными значениями этого поля могут быть:

              0      SAMPLE_IP может иметь произвольный скат.

              1      SAMPLE_IP должен иметь постоянный скат.

              2      SAMPLE_IP запрашивает нулевой скат.

              3      Значение SAMPLE_IP должно иметь 0 скат (skid). Смотрите также описание  I  в
                     PERF_RECORD_MISC_EXACT_IP().

       mmap_data (начиная с Linux 2.6.36)
              Противоположно полю mmap. Включает генерацию измерений PERF_RECORD_MMAP для вызовов
              mmap(2), у которых не установлен бит PROT_EXEC (например, у данных и  общей  памяти
              SysV).

       sample_id_all (начиная с Linux 2.6.38)
              Если  установлен, то TID, TIME, ID, STREAM_ID и ЦП могут дополнительно включаться в
              не-PERF_RECORD_SAMPLE, если выбран соответствующий sample_type.

              Если указан PERF_SAMPLE_IDENTIFIER,  то  дополнительно  включается  значение  ID  в
              качестве  последнего  значения  для  облегчения  разбора  потока записей. Это может
              привести к появлению значения id дважды.

              Состав описывается следующей псевдо-структурой:

                  struct sample_id {
                      { u32 pid, tid; } /* если есть PERF_SAMPLE_TID */
                      { u64 time;     } /* если есть PERF_SAMPLE_TIME */
                      { u64 id;       } /* если есть PERF_SAMPLE_ID */
                      { u64 stream_id;} /* если есть PERF_SAMPLE_STREAM_ID */
                      { u32 cpu, res; } /* если есть PERF_SAMPLE_CPU */
                      { u64 id;       } /* если есть PERF_SAMPLE_IDENTIFIER */
                  };

       exclude_host (начиная с Linux 3.2)
              При проведении измерений, которые включают процессы, запускающие экземпляры VM  (т.
              е.  выполняют  I  ioctl(2)  KVM_RUN), измеряются только события, возникающие внутри
              гостевого экземпляра. Имеет смысл только  вне  гостевых  машин;  эта  настройка  не
              изменяет  счётчики,  собираемые внутри гостей. В настоящее время работает только на
              x86.

       exclude_guest (начиная с Linux 3.2)
              При проведении измерений, которые включают процессы, запускающие экземпляры VM  (т.
              е.  выполняют  I  ioctl(2)  KVM_RUN),  не  измеряются  события,  возникающие внутри
              гостевого экземпляра. Имеет смысл только  вне  гостевых  машин;  эта  настройка  не
              изменяет  счётчики,  собираемые внутри гостей. В настоящее время работает только на
              x86.

       exclude_callchain_kernel (начиная с Linux 3.7)
              Не включать цепочку вызовов ядра.

       exclude_callchain_user (начиная с Linux 3.7)
              Не включать цепочку вызовов пользовательского пространства.

       mmap2 (начиная с Linux 3.16)
              Генерировать расширенную запись выполняемого mmap, которая содержит  дополнительную
              информацию,  достаточную для определения уникальности общих отображений. Для работы
              также требуется установить флаг mmap.

       comm_exec (начиная с Linux 3.16)
              Флаг определения свойств, не изменяет поведение  ядра.  Если  флаг  установлен,  то
              когда  включён  comm,  будет устанавливаться флаг PERF_RECORD_MISC_COMM_EXEC в поле
              misc заголовка записи comm, если сообщается о  событии  переименования,  вызванного
              вызовом   execve(2).   Это   позволяет   инструментам   различать   различные   тип
              переименования процесса.

       use_clockid (начиная с Linux 4.1)
              Через clockid позволяет выбрать внутренние часы Linux, используемые  для  генерации
              меток времени. Это может облегчить соответствие времён измерений с метками времени,
              сгенерированными другими инструментами.

       context_switch (начиная с Linux 4.3)
              Включает генерацию записей PERF_RECORD_SWITCH  при  переключении  контекста.  Также
              включает  генерацию  записей  PERF_RECORD_SWITCH_CPU_WIDE  при  измерении  в режиме
              CPU-wide. Данная возможность дополняет существующие точки трассировки и программные
              события  для измерения переключений контекста. Преимущество этого метода в том, что
              он даёт полную информацию даже при ограничительных настройках perf_event_paranoid.

       write_backward (начиная с Linux 4.6)
              This causes the ring buffer to be written from the end to the beginning.   This  is
              to support reading from overwritable ring buffer.

       namespaces (начиная с Linux 4.11)
              This  enables the generation of PERF_RECORD_NAMESPACES records when a task enters a
              new namespace.  Each namespace has a combination of device and inode numbers.

       ksymbol (начиная с Linux 5.0)
              This enables the generation of PERF_RECORD_KSYMBOL records when new kernel  symbols
              are  registered  or  unregistered.  This is analyzing dynamic kernel functions like
              eBPF.

       bpf_event (начиная с Linux 5.0)
              This enables the generation of PERF_RECORD_BPF_EVENT records when an  eBPF  program
              is loaded or unloaded.

       aux_output (since Linux 5.4)
              This allows normal (non-AUX) events to generate data for AUX events if the hardware
              supports it.

       cgroup (начиная с Linux 5.7)
              This enables the generation of PERF_RECORD_CGROUP records  when  a  new  cgroup  is
              created (and activated).

       text_poke (начиная с Linux 5.8)
              This  enables the generation of PERF_RECORD_TEXT_POKE records when there's a change
              to the kernel text (i.e., self-modifying code).

       build_id (since Linux 5.12)
              This changes the contents in the PERF_RECORD_MMAP2 to have a  build-id  instead  of
              device and inode numbers.

       inherit_thread (since Linux 5.13)
              This disables the inheritance of the event to a child process.  Only new threads in
              the same process (which is cloned with CLONE_THREAD)  will inherit the event.

       remove_on_exec (since Linux 5.13)
              This closes the event when it starts a new process image by execve(2).

       sigtrap (since Linux 5.13)
              This enables synchronous signal delivery of SIGTRAP on event overflow.

       wakeup_events, wakeup_watermark
              Это   объединение   задаёт   как   много   измерений   (wakeup_events)   или   байт
              (wakeup_watermark)  должно  произойти  до  уведомления о переполнении. Используемое
              поле выбирается битом флага watermark.

              В wakeup_events подсчитываются только записи с типом PERF_RECORD_SAMPLE. Для приёма
              уведомления  о  переполнении  всех типов PERF_RECORD выберите watermark и присвойте
              wakeup_watermark значение 1.

              До Linux 3.0 установка wakeup_events в  0  приводила  к  выключению  уведомления  о
              переполнении; новые ядра считают 0 как 1.

       bp_type (начиная с Linux 2.6.33)
              Задаёт тип точки останова. Может быть:

              HW_BREAKPOINT_EMPTY
                     Нет точки останова.

              HW_BREAKPOINT_R
                     Считать, когда выполняется чтение из определённого места памяти.

              HW_BREAKPOINT_W
                     Считать, когда выполняется запись в определённое место памяти.

              HW_BREAKPOINT_RW
                     Считать, когда выполняется чтение или запись в определённое место памяти.

              HW_BREAKPOINT_X
                     Считать, когда выполняется код из определённого места памяти.

              Значения   можно   побитово   объединять,   но   комбинация   HW_BREAKPOINT_R   или
              HW_BREAKPOINT_W с HW_BREAKPOINT_X недопустима.

       bp_addr (начиная с Linux 2.6.33)
              Адрес точки останова. Для точек останова выполнения это адрес  памяти  интересующей
              инструкции;  для  точек  останова  чтения  и  записи это адрес памяти интересующего
              расположения в памяти.

       config1 (начиная с Linux 2.6.39)
              Значение config1 используется для задания  событий,  которым  нужен  дополнительный
              регистр  или  не хватает обычного поля config. Это поле используется в Linux 3.3  и
              новее     для     неструктурированного     OFFCORE_EVENTS      на      архитектурах
              Nehalem/Westmere/SandyBridge.

       bp_len (начиная с Linux 2.6.33)
              В  bp_len  содержится  длина  точки  измеряемой  останова, если значение type равно
              PERF_TYPE_BREAKPOINT.  Можно  указывать  HW_BREAKPOINT_LEN_1,  HW_BREAKPOINT_LEN_2,
              HW_BREAKPOINT_LEN_4  и HW_BREAKPOINT_LEN_8. Для точки останова выполнения присвойте
              sizeof(long).

       config2 (начиная с Linux 2.6.39)
              Поле config2 — дальнейшее расширение поля config1.

       branch_sample_type (начиная с Linux 3.4)
              Если установлен PERF_SAMPLE_BRANCH_STACK, то ветви будут включаться в запись ветви.

              В первой части значения задаётся уровень привилегий, который может быть комбинацией
              одного  из  показанных  ниже  значений.  Если  пользователь  явно  не задал уровень
              привилегий, то ядро будет использовать уровень привилегий события. Событие и уровни
              привилегий ветви не совпадают.

              PERF_SAMPLE_BRANCH_USER
                     Цель ветвления в пользовательском пространстве

              PERF_SAMPLE_BRANCH_KERNEL
                     Цель ветвления в пространстве ядра

              PERF_SAMPLE_BRANCH_HV
                     Цель ветвления в гипервизоре.

              PERF_SAMPLE_BRANCH_PLM_ALL
                     Подходящее значение состоит из трёх предшествующих значений объединённых OR.

              В  дополнении  к  значению  привилегий,  должно  быть  указано как минимум, одно из
              следующих:

              PERF_SAMPLE_BRANCH_ANY
                     Любой тип ветвления.

              PERF_SAMPLE_BRANCH_ANY_CALL
                     Любое ветвление (прямые вызовы, косвенные вызовы и дальние переходы).

              PERF_SAMPLE_BRANCH_IND_CALL
                     Косвенные вызовы.

              PERF_SAMPLE_BRANCH_CALL (начиная с Linux 4.4)
                     Прямые вызовы.

              PERF_SAMPLE_BRANCH_ANY_RETURN
                     Любой возврат из ветвления.

              PERF_SAMPLE_BRANCH_IND_JUMP (начиная с Linux 4.2)
                     Косвенные прыжки.

              PERF_SAMPLE_BRANCH_COND (начиная с Linux 3.16)
                     Ветвления по условию.

              PERF_SAMPLE_BRANCH_ABORT_TX (начиная с Linux 3.11)
                     Аварии транзакционной памяти.

              PERF_SAMPLE_BRANCH_IN_TX (начиная с Linux 3.11)
                     Ветвление в транзакции транзакционной памяти.

              PERF_SAMPLE_BRANCH_NO_TX (начиная с Linux 3.11)
                     Ветвление не транзакции транзакционной памяти. PERF_SAMPLE_BRANCH_CALL_STACK
                     (начиная  с  Linux  4.1)  Ветвление  это  часть аппаратно создаваемого стека
                     вызовов. Требует аппаратной поддержки, в настоящее время работает только  на
                     Intel x86 Haswell и новее.

       sample_regs_user (начиная с Linux 3.7)
              Данной  битовой  маской задаётся набор битов пользовательских регистров ЦП, которые
              сохраняются в измерениях. Значения битов в битовой маске зависят от  архитектуры  и
              описаны в заголовочном файле ядра arch/ARCH/include/uapi/asm/perf_regs.h.

       sample_stack_user (начиная с Linux 3.7)
              Задаёт     размер     сохраняемого    пользовательского    стека,    если    указан
              PERF_SAMPLE_STACK_USER.

       clockid (начиная с Linux 4.1)
              Если установлен use_clockid, то этим  полем  выбирается  внутренний  таймер  Linux,
              используемый  для  меток  времени.Доступные  таймеры  определены  в linux/time.h; в
              настоящее    время     поддерживаются     CLOCK_MONOTONIC,     CLOCK_MONOTONIC_RAW,
              CLOCK_REALTIME, CLOCK_BOOTTIME и CLOCK_TAI.

       aux_watermark (начиная с Linux 4.1)
              Определяет какое количество данных требуется для запуска измерения PERF_RECORD_AUX.

       sample_max_stack (начиная с Linux 4.8)
              Если sample_type содержит PERF_SAMPLE_CALLCHAIN, то в этом поле задаётся количество
              выводимых кадров стека при генерации цепочки вызовов.

       aux_sample_size (since Linux 5.5)
              When PERF_SAMPLE_AUX flag is set, specify the desired size of AUX data.  Note  that
              it can get smaller data than the specified size.

       sig_data (since Linux 5.13)
              This  data  will  be  copied  to  user's  signal  handler  (through  si_perf in the
              siginfo_t)  to disambiguate which event triggered the signal.

   Чтение результатов
       После  открытия  файлового  дескриптора  с  помощью  perf_event_open(),  значения  событий
       доступны на чтение. События задаются вв поле read_format структуры attr в момент открытия.

       Если  вы попытаетесь выполнить чтение в буфер недостаточного размера, то результатом будет
       ошибка ENOSPC.

       Вот компоновка данных, возвращаемых чтением:

       •  Если указан PERF_FORMAT_GROUP для разрешения чтения всех событий в группе за раз:

              struct read_format {
                  u64 nr;            /* The number of events */
                  u64 time_enabled;  /* if PERF_FORMAT_TOTAL_TIME_ENABLED */
                  u64 time_running;  /* if PERF_FORMAT_TOTAL_TIME_RUNNING */
                  struct {
                      u64 value;     /* The value of the event */
                      u64 id;        /* if PERF_FORMAT_ID */
                      u64 lost;      /* if PERF_FORMAT_LOST */
                  } values[nr];
              };

       •  Если PERF_FORMAT_GROUP не указан:

              struct read_format {
                  u64 value;         /* The value of the event */
                  u64 time_enabled;  /* if PERF_FORMAT_TOTAL_TIME_ENABLED */
                  u64 time_running;  /* if PERF_FORMAT_TOTAL_TIME_RUNNING */
                  u64 id;            /* if PERF_FORMAT_ID */
                  u64 lost;          /* if PERF_FORMAT_LOST */
              };

       Значения полей:

       nr     Количество событий в  этом  файловом  дескрипторе.  Доступно  только,  если  указан
              PERF_FORMAT_GROUP.

       time_enabled, time_running
              Полное  время  события  с  момента  включения  и  выполнения.  Обычно, эти значения
              одинаковы. Если событий больше, чем доступно счётчиков слотов в PMU,  то  возникает
              мультиплексирование.  В  этом  случае   события  выполняются только часть времени и
              значения time_enabled и time running можно использовать для градации  рассчитанного
              значения в счётчике.

       value  Целое беззнаковое 64-битное значение, содержащее счётчик-результат.

       id     Глобально   уникальное  значение  данного  события;  присутствует  только,  если  в
              read_format указан PERF_FORMAT_ID.

       lost   The number of lost samples of this event;  only  present  if  PERF_FORMAT_LOST  was
              specified in read_format.

   Разбивка MMAP
       При  использовании  perf_event_open()  в  режиме измерений, асинхронные события (такие как
       переполнение счётчика или слежение за PROT_EXEC mmap) протоколируются в  кольцевой  буфер.
       Этот кольцевой буфер создаётся и доступен через mmap(2).

       The  mmap  size  should  be  1+2^n  pages, where the first page is a metadata page (struct
       perf_event_mmap_page)  that contains  various  bits  of  information  such  as  where  the
       ring-buffer head is.

       Before  Linux 2.6.39, there is a bug that means you must allocate an mmap ring buffer when
       sampling even if you do not plan to access it.

       Структура первой страницы метаданных mmap:

           struct perf_event_mmap_page {
               __u32 version;        /* номер версии структуры */
               __u32 compat_version; /* наименьшая совместимая версия */
               __u32 lock;           /* seqlock для синхронизации */
               __u32 index;          /* идентификатор аппаратного счётчика */
               __s64 offset;         /* добавляется к значению аппаратного
                                        счётчика */
               __u64 time_enabled;   /* время активности события */
               __u64 time_running;   /* время события на ЦП */
               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];   /* дополнение до 1 k */
               __u64 data_head;         /* заголовок в секции данных */
               __u64 data_tail;         /* хвост, записываемый из
                                           пользовательского пространства */
               __u64 data_offset;       /* начало буфера */
               __u64 data_size;         /* размер буфера данных */
               __u64 aux_head;
               __u64 aux_tail;
               __u64 aux_offset;
               __u64 aux_size;

           }

       В следующем списке поля структуры perf_event_mmap_page описаны более подробно:

       version
              Номер версии этой структуры.

       compat_version
              Наименьший номер версии, совместимой с данной структурой.

       lock   Значение seqlock для синхронизации.

       index  Уникальный идентификатор аппаратного счётчика.

       offset При использовании rdpmc для чтения  это  значение  смещения  должно  добавляться  к
              возвращаемому rdpmc для получения текущего общего количества событий.

       time_enabled
              Время активности события.

       time_running
              Время выполнения события.

       cap_usr_time / cap_usr_rdpmc / cap_bit0 (начиная с Linux 3.4)
              С  Linux 3.4 по Linux 3.11 был дефект в определении cap_usr_time и cap_usr_rdpmc. В
              обоих биты указывали на одно место, поэтому было невозможно  узнать  что  на  самом
              деле установлено: cap_usr_time или cap_usr_rdpmc.

              Начиная  с  Linux  3.12,  они  были переименованы в cap_bit0 и вместо них вы должны
              использовать поля cap_user_time и cap_user_rdpmc.

       cap_bit0_is_deprecated (начиная с Linux 3.12)
              Если  установлен,  то  этот  бит  показывает,  что  ядро   поддерживает   правильно
              разделённые биты cap_user_time и cap_user_rdpmc.

              Если   не   установлен,  то  это  означает  используется  старое  ядро,  в  котором
              cap_usr_time и cap_usr_rdpmc отражают один и тот  же  бит,  и  оба  свойства  нужно
              использовать с осторожностью.

       cap_user_rdpmc (начиная с Linux 3.12)
              Если   есть   аппаратная   поддержка   чтения   счётчиков   производительности   из
              пользовательского пространства без системного вызова (инструкция «rdpmc» в x86), то
              для чтения можно использовать следующий код:

                  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 (начиная с Linux 3.12)
              Этот  бит  указывает  на  наличие  аппаратного,  неизменяемого,  неостанавливаемого
              счётчика временных меток (TSC на x86).

       cap_user_time_zero (начиная с Linux 3.12)
              Указывает на наличие time_zero, который  позволяет  отображать  значения  временных
              меток в аппаратные часы.

       pmc_width
              Если установлен cap_usr_rdpmc, то это поле предоставляет ширину (в битах) значения,
              считываемого с помощью rdpmc или эквивалентной инструкции. Может использоваться для
              расширения знаком:

                  pmc <<= 64 - pmc_width;
                  pmc >>= 64 - pmc_width; // сдвиг знака вправо
                  count += pmc;

       time_shift, time_mult, time_offset

              Если  установлен  cap_usr_time,  то  эти  поля  можно использоваться для вычисления
              разницы времени, начиная с  time_enabled  (в  наносекундах)  с  помощью  rdtsc  или
              подобной инструкции.

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

              Где  time_offset,  time_mult, time_shift и cyc читаются в цикле seqcount, описанном
              выше. Затем эта разница может быть добавлена для  включения  и,  возможно,  запуска
              (если idx) для улучшения масштабирования:

                  enabled += delta;
                  if (idx)
                      running += delta;
                  quot  = count / running;
                  rem   = count % running;
                  count = quot * enabled + (rem * enabled) / running;

       time_zero (начиная с Linux 3.12)

              Если  установлен cap_usr_time_zero, то аппаратные часы (счётчик временных меток TSC
              на x86) могут быть вычислены из значений time_zero, time_mult и time_shift:

                  time = timestamp - time_zero;
                  quot = time / time_mult;
                  rem  = time % time_mult;
                  cyc  = (quot << time_shift) + (rem << time_shift) / time_mult;

              И наоборот:

                  quot = cyc >> time_shift;
                  rem  = cyc & (((u64)1 << time_shift) - 1);
                  timestamp = time_zero + quot * time_mult +
                              ((rem * time_mult) >> time_shift);

       data_head
              Указывает на  начало  секции  данных.  Значение  непрерывно  увеличивается,  но  не
              возвращается  в  начало.  Перед  доступом  к образцам его нужно возвращать в начало
              вручную — на размер буфера mmap.

              На  платформах  с  SMP  после  чтения  значения  data_head   из   пользовательского
              пространства нужно вызвать функцию rmb().

       data_tail
              Если   отображение   PROT_WRITE,   то  значение  data_tail  будет  записываться  из
              пользовательского пространства для отражения последних прочитанных данных.  В  этом
              случае ядро не перезаписывает непрочитанные данные.

       data_offset (начиная с Linux 4.1)
              Содержит смещение расположения начала данных образца perf в буфере mmap.

       data_size (начиная с Linux 4.1)
              Содержит размер области образца perf в буфере mmap.

       aux_head, aux_tail, aux_offset, aux_size (начиная с Linux 4.1)
              The  AUX region allows mmap(2)-ing a separate sample buffer for high-bandwidth data
              streams  (separate  from  the  main  perf  sample  buffer).   An   example   of   a
              high-bandwidth  stream  is  instruction tracing support, as is found in newer Intel
              processors.

              Для задания области  AUX,  сначала  задайте  aux_offset  со  смещением  больше  чем
              data_offset+data_size,  а в aux_size нужно указать желаемых размер буфера. Желаемое
              смещение и размер должны быть выровнены по границе страницы, и размер  должен  быть
              степенью  двойки.  Затем эти значения передаются в mmap для отображения буфера AUX.
              Страницы буфера AUX учитываются  в  ограничении  ресурса  RLIMIT_MEMLOCK  (смотрите
              setrlimit(2)), а также проходят допустимость perf_event_mlock_kb.

              По умолчанию буфер AUX будет обрезан, если он не вмещается в доступное пространство
              кольцевого буфера. Если буфер AUX отображается  только  для  чтения,  то  он  будет
              работать  в  режиме кольцевого буфера, где старые данные перезаписываются новыми. В
              режиме перезаписи нельзя угадать место начала новых данных, и  задачей  потребителя
              становится отключение измерения для избежания возможной состязательности по данным.

              Указатели  кольцевого  буфера  aux_head  и  aux_tail  работают и подчиняются тем же
              правилам, которые описаны выше для data_head и data_tail.

       Далее приводится раскладка страниц кольцевого буфера размером 2^n.

       Если установлен perf_event_attr.sample_id_all, то все типы событий будут  иметь  выбранные
       поля  sample_type,  относящиеся  к  где/когда  (отличительность) происходило событие (TID,
       TIME, ID, CPU, STREAM_ID), описанные в PERF_RECORD_SAMPLE  ниже;  они  будут  спрятаны  за
       perf_event_header и уже имеющимися полями, то есть в записываться в конец полезных данных.
       Это позволяет читать новый файл perf.data  старыми  инструментами  perf,  игнорируя  новые
       необязательные поля.

       Значения mmap начинаются с заголовка:

           struct perf_event_header {
               __u32   type;
               __u16   misc;
               __u16   size;
           };

       Далее  мы  опишем  поля  perf_event_header  более  подробно. Для простоты поля с короткими
       описаниями показаны первыми.

       size   Показывает размер записи.

       misc   В поле misc содержится дополнительная информация об образце.

              По  этому  значению  можно   определить   режим   ЦП,   наложив   на   него   маску
              PERF_RECORD_MISC_CPUMODE_MASK  и   одно  из следующих значений (заметим, что это не
              битовые маски, можно указывать только одно значение за раз):

              PERF_RECORD_MISC_CPUMODE_UNKNOWN
                     Неизвестный режим ЦП.

              PERF_RECORD_MISC_KERNEL
                     Образец возник в ядре.

              PERF_RECORD_MISC_USER
                     Образец возник в пользовательском коде.

              PERF_RECORD_MISC_HYPERVISOR
                     Образец возник в гипервизоре.

              PERF_RECORD_MISC_GUEST_KERNEL (начиная с Linux 2.6.35)
                     Образец возник в гостевом ядре.

              PERF_RECORD_MISC_GUEST_USER  (начиная с Linux 2.6.35)
                     Образец возник в гостевом пользовательском коде.

              Так как следующие три состояния сгенерированы различными  типами  записей,  то  они
              указывают на один и тот же бит:

              PERF_RECORD_MISC_MMAP_DATA (начиная с Linux 3.10)
                     Устанавливается,  когда  отображение  не  выполняемое;  в  противном  случае
                     отображение выполняемое.

              PERF_RECORD_MISC_COMM_EXEC (начиная с Linux 3.16)
                     Устанавливается для записи PERF_RECORD_COMM в ядрах новее версии Linux 3.16,
                     если имя процесса изменено системным вызовом execve(2).

              PERF_RECORD_MISC_SWITCH_OUT (начиная с Linux 4.3)
                     При генерации записи PERF_RECORD_SWITCH или PERF_RECORD_SWITCH_CPU_WIDE этот
                     бит показывает, что переключение контекста происходило из текущего  процесса
                     (а не в текущий процесс).

              Также могут устанавливаться следующие биты:

              PERF_RECORD_MISC_EXACT_IP
                     Показывает,   что   содержимое   PERF_SAMPLE_IP   указывает   на  актуальную
                     инструкцию,   из-за    которой    произошло    событие.    Смотрите    также
                     perf_event_attr.precise_ip.

              PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (since Linux 4.17)
                     When   a   PERF_RECORD_SWITCH   or   PERF_RECORD_SWITCH_CPU_WIDE  record  is
                     generated, this indicates the context switch was a preemption.

              PERF_RECORD_MISC_MMAP_BUILD_ID (since Linux 5.12)
                     This indicates that the content of PERF_SAMPLE_MMAP2 contains build-ID  data
                     instead of device major and minor numbers as well as the inode number.

              PERF_RECORD_MISC_EXT_RESERVED (начиная с Linux 2.6.35)
                     Показывает, что доступны расширенные данные (пока не используется).

              PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT
                     Данный   бит   не  устанавливается  ядром.  Он  зарезервирован  для  утилиты
                     пользовательского   пространства   perf    и    показывает,    что    разбор
                     /proc/i[pid]/maps  выполнялся  слишком  долго  и  был  остановлен, и поэтому
                     записи mmap могут быть обрезанными.

       type   Значение type — одно из представленных  ниже.  Значения  в  соответствующей  записи
              (следующие за заголовком) зависят от выбранного type как описано.

              PERF_RECORD_MMAP
                  События  MMAP  записывают отображения PROT_EXEC так, чтобы можно было соотнести
                  IP пользовательского пространства с кодом. Они имеют следующую структуру:

                      struct {
                          struct perf_event_header header;
                          u32    pid, tid;
                          u64    addr;
                          u64    len;
                          u64    pgoff;
                          char   filename[];
                      };

                  pid    идентификатор процесса.

                  tid    идентификатор нити.

                  addr   адрес выделенной памяти. В len указывается длина  выделенной  памяти.  В
                         pgoff  указывается  смещение  страницы  выделенной  памяти.  В  filename
                         указывается строка, описывающая выделенную память.

              PERF_RECORD_LOST
                  Эта запись указывает на потерю событий.

                      struct {
                          struct perf_event_header header;
                          u64    id;
                          u64    lost;
                          struct sample_id sample_id;
                      };

                  id     уникальный ID события утерянных образцов.

                  lost   количество потерянных событий.

              PERF_RECORD_COMM
                  Эта запись указывает на изменение имени процесса.

                      struct {
                          struct perf_event_header header;
                          u32    pid;
                          u32    tid;
                          char   comm[];
                          struct sample_id sample_id;
                      };

                  pid    идентификатор процесса.

                  tid    идентификатор нити.

                  comm   строка, содержащая новое имя процесса.

              PERF_RECORD_EXIT
                  Эта запись указывает на событие выхода процесса.

                      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
                  Эта запись указывает на событие включения/выключения регулировки (throttle).

                      struct {
                          struct perf_event_header header;
                          u64    time;
                          u64    id;
                          u64    stream_id;
                          struct sample_id sample_id;
                      };

              PERF_RECORD_FORK
                  Эта запись указывает на событие порождения (fork) процесса.

                      struct {
                          struct perf_event_header header;
                          u32    pid, ppid;
                          u32    tid, ptid;
                          u64    time;
                          struct sample_id sample_id;
                      };

              PERF_RECORD_READ
                  Эта запись указывает на событие чтения.

                      struct {
                          struct perf_event_header header;
                          u32    pid, tid;
                          struct read_format values;
                          struct sample_id sample_id;
                      };

              PERF_RECORD_SAMPLE
                  Эта запись указывает на образец.

                      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
                      Если включён PERF_SAMPLE_IDENTIFIER, то  добавляется  уникальный  64-битный
                      идентификатор.  Это  дубль значения id при PERF_SAMPLE_ID, но добавляется в
                      начало образца, для простоты получения значения анализаторами.

                  ip  Если включён PERF_SAMPLE_IP, то добавляется значение  64-битного  указателя
                      инструкции.

                  pid, tid
                      Если   включён  PERF_SAMPLE_TID,  то  добавляется  32-битный  идентификатор
                      процесс и 32-битный идентификатор нити.

                  time
                      Если включён PERF_SAMPLE_TIME, то добавляется 64-битная метка времени.  Она
                      получается  из local_clock(), которая возвращает, если возможно, аппаратную
                      метку времени или количество мигов, если нет.

                  addr
                      Если включён PERF_SAMPLE_ADDR, то добавляется 64-битный адрес. Обычно,  это
                      адрес  точки  трассировки,  останова  или программного события; в противном
                      случае 0.

                  id  Если  включён   PERF_SAMPLE_ID,   то   добавляется   64-битный   уникальный
                      идентификатор. Если события является членом группы событий, то возвращается
                      идентификатор лидера группы.  Этот  идентификатор  одинаков  со  значением,
                      возвращаемым при PERF_FORMAT_ID.

                  stream_id
                      Если  включён  PERF_SAMPLE_STREAM_ID,  то  добавляется 64-битный уникальный
                      идентификатор.  В   отличии   от   PERF_SAMPLE_ID   возвращается   реальный
                      идентификатор,  а  не лидера группы. Этот же идентификатор возвращается при
                      PERF_FORMAT_ID.

                  cpu, res
                      Если  включён   PERF_SAMPLE_CPU,   здесь   хранится   32-битное   значение,
                      показывающее,   какой   использовался   ЦП,   а   также   зарезервированное
                      (неиспользуемое) 32-битное значение.

                  period
                      Если  включён  PERF_SAMPLE_PERIOD,  то  записывается  64-битное   значение,
                      отражающее период выборки.

                  v   Если   включён  PERF_SAMPLE_READ,  то  добавляется  структура  read_format,
                      которая содержит значения для  всех  событий  группы  событий.  Добавляемые
                      значения   зависят   от  значения  read_format,  использованного  во  время
                      perf_event_open().

                  nr, ips[nr]
                      Если  включён  PERF_SAMPLE_CALLCHAIN,  то  добавляется   64-битный   номер,
                      показывающий  сколько  далее  следует  64-битных указателей инструкций. Это
                      относится к текущей цепочке вызовов.

                  size, data[size]
                      Если  включён   PERF_SAMPLE_RAW,   то   добавляется   32-битное   значение,
                      показывающее  размер размещённого далее массива 8-битных значений. Значения
                      дополняются нулями до 64-битного.

                      Это неструктурированные записи с данными, скрытыми программным интерфейсом.
                      Не гарантируется неизменность их структуры в будущем, она может зависеть от
                      события, аппаратного обеспечения и версии ядра.

                  bnr, lbr[bnr]
                      Если включён PERF_SAMPLE_BRANCH_STACK, то добавляется  64-битное  значение,
                      показывающее    количество    записей,   следующих   за   структурами   bnr
                      perf_branch_entry, каждая из которых содержит следующие поля:

                      from   Источник инструкции (может быть не ветвление).

                      to     Цель ветвления.

                      mispred
                             Цель ветвления предсказана ошибочно.

                      predicted
                             Цель ветвления предсказана.

                      in_tx (начиная с Linux 3.11)
                             Ветвление возникло в транзакции транзакционной памяти.

                      abort (начиная с Linux 3.11)
                             Ветвление возникло в аварийной транзакции транзакционной памяти.

                      cycles (начиная с Linux 4.3)
                             Количество циклов, прошедших с предыдущего обновления стека ветви.

                      Элементы располагаются от новых к старым, таким образом,  первый  указывает
                      на самое новое ветвление.

                      Поддержка  mispred,  predicted и cycles необязательна; если отсутствует, то
                      значения будут равны 0.

                      Тип сохранённых ветвлений указывается в поле branch_sample_type.

                  abi, regs[weight(mask)]
                      Если  включён  PERF_SAMPLE_REGS_USER,   то   сохраняются   пользовательские
                      регистры ЦП.

                      Значением     поля     abi     может     быть    PERF_SAMPLE_REGS_ABI_NONE,
                      PERF_SAMPLE_REGS_ABI_32 или PERF_SAMPLE_REGS_ABI_64.

                      В regs хранится массив  регистров  ЦП,  которые  были  перечислены  в  поле
                      sample_regs_user.   Количество   значений   определяется  количеством  бит,
                      установленных в битовой маске sample_regs_user.

                  size, data[size], dyn_size
                      Если включён PERF_SAMPLE_STACK_USER, то сохраняется пользовательский  стек.
                      Он может использоваться для генерации стека обратных вызовов. Значение size
                      —   размер,   запрашиваемый   пользователем   для   sample_stack_user   или
                      максимальное    значение    записи.    Значение   data   —   данные   стека
                      (неструктурированная копия памяти, на которую указывает указатель стека  во
                      время  взятия образца). Значение dyn_size — количество данных, которые были
                      записаны (может быть меньше size). Заметим, что dyn_size пропускается, если
                      size равно 0.

                  weight
                      If  PERF_SAMPLE_WEIGHT  or  PERF_SAMPLE_WEIGHT_STRUCT  is  enabled,  then a
                      64-bit value provided by the hardware is recorded that indicates how costly
                      the  event  was.  This allows expensive events to stand out more clearly in
                      profiles.

                  data_src
                      Если  включён  PERF_SAMPLE_DATA_SRC,  то  сохраняется  64-битное  значение,
                      состоящее из следующих полей:

                      mem_op
                          Тип кода операции, битовая комбинация из следующих значений:

                          PERF_MEM_OP_NA          Недоступен
                          PERF_MEM_OP_LOAD        Инструкция загрузки
                          PERF_MEM_OP_STORE       Инструкция сохранения
                          PERF_MEM_OP_PFETCH      Предварительная выборка
                          PERF_MEM_OP_EXEC        Исполняемый код

                      mem_lvl
                          Попадание  или  промах по уровням иерархии памяти, побитовая комбинация
                          следующего, сдвинутого влево на PERF_MEM_LVL_SHIFT:

                          PERF_MEM_LVL_NA         Недоступен
                          PERF_MEM_LVL_HIT        Попадание
                          PERF_MEM_LVL_MISS       Промах
                          PERF_MEM_LVL_L1         Кэш 1 уровня
                          PERF_MEM_LVL_LFB        Построчно заполняемый буфер
                          PERF_MEM_LVL_L2         Кэш 2 уровня
                          PERF_MEM_LVL_L3         Кэш 3 уровня
                          PERF_MEM_LVL_LOC_RAM    Локальная оперативная память
                          PERF_MEM_LVL_REM_RAM1   Удалённая на 1 скачок оперативная память
                          PERF_MEM_LVL_REM_RAM2   Удалённая на 2 скачка оперативная память
                          PERF_MEM_LVL_REM_CCE1   Удалённый на 1 скачок кэш
                          PERF_MEM_LVL_REM_CCE2   Удалённый на 2 скачка кэш
                          PERF_MEM_LVL_IO         Память ввода-вывода
                          PERF_MEM_LVL_UNC        Некэшируемая память

                      mem_snoop
                          Режим подглядывания  (snoop  mode),  побитовая  комбинация  следующего,
                          сдвинутого влево на PERF_MEM_SNOOP_SHIFT:

                          PERF_MEM_SNOOP_NA       Недоступен
                          PERF_MEM_SNOOP_NONE     Нет подглядывания
                          PERF_MEM_SNOOP_HIT      Срабатывание подглядывания
                          PERF_MEM_SNOOP_MISS     Промах подглядывания
                          PERF_MEM_SNOOP_HITM     Срабатывание подглядывания изменено

                      mem_lock
                          Инструкция  блокировки,  побитовая  комбинация  следующего,  сдвинутого
                          влево на PERF_MEM_LOCK_SHIFT:

                          PERF_MEM_LOCK_NA        Недоступен
                          PERF_MEM_LOCK_LOCKED    Заблокированная транзакция

                      mem_dtlb
                          Попадание или промах доступа к TLB,  побитовая  комбинация  следующего,
                          сдвинутого влево на PERF_MEM_TLB_SHIFT:

                          PERF_MEM_TLB_NA         Недоступен
                          PERF_MEM_TLB_HIT        Попадание
                          PERF_MEM_TLB_MISS       Промах
                          PERF_MEM_TLB_L1         1 уровень TLB
                          PERF_MEM_TLB_L2         2 уровень TLB
                          PERF_MEM_TLB_WK         Обходчик оборудования
                          PERF_MEM_TLB_OS         Обработчик ошибок ОС

                  transaction
                      Если  установлен  флаг  PERF_SAMPLE_TRANSACTION,  то записывается 64-битное
                      поле, описывающее источники аварий транзакционной памяти.

                      Данное поле является побитовым объединением следующих значений:

                      PERF_TXN_ELISION
                             Авария из-за транзакции пропущенного типа (только для ЦП Intel).

                      PERF_TXN_TRANSACTION
                             Авария из-за общей транзакции.

                      PERF_TXN_SYNC
                             Синхронная авария (относится к сообщению об инструкции).

                      PERF_TXN_ASYNC
                             Асинхронная авария (не относится к сообщению об инструкции).

                      PERF_TXN_RETRY
                             Повторяемая авария (повтор транзакции  может  привести  к  успешному
                             выполнению).

                      PERF_TXN_CONFLICT
                             Авария из-за конфликта памяти между нитями.

                      PERF_TXN_CAPACITY_WRITE
                             Авария из-за переполнения объёма при записи.

                      PERF_TXN_CAPACITY_READ
                             Авария из-за переполнения объёма при чтении.

                      Также,  можно получить указанный пользователем код аварии, если сдвинуть 32
                      бита   поля   вправо   на    PERF_TXN_ABORT_SHIFT    и    наложить    маску
                      PERF_TXN_ABORT_MASK.

                  abi, regs[weight(mask)]
                      Если   включён   PERF_SAMPLE_REGS_INTR,   то  сохраняются  пользовательские
                      регистры ЦП.

                      Значением    поля     abi     может     быть     PERF_SAMPLE_REGS_ABI_NONE,
                      PERF_SAMPLE_REGS_ABI_32 или PERF_SAMPLE_REGS_ABI_64.

                      В  regs  хранится  массив  регистров  ЦП,  которые  были перечислены в поле
                      sample_regs_intr.  Количество  значений   определяется   количеством   бит,
                      установленных в битовой маске sample_regs_intr.

                  phys_addr
                      If  the PERF_SAMPLE_PHYS_ADDR flag is set, then the 64-bit physical address
                      is recorded.

                  cgroup
                      If the PERF_SAMPLE_CGROUP flag is set, then the 64-bit cgroup ID  (for  the
                      perf_event  subsystem) is recorded.  To get the pathname of the cgroup, the
                      ID should match to one in a PERF_RECORD_CGROUP.

                  data_page_size
                      If the PERF_SAMPLE_DATA_PAGE_SIZE flag is set, then the  64-bit  page  size
                      value of the data address is recorded.

                  code_page_size
                      If  the  PERF_SAMPLE_CODE_PAGE_SIZE  flag is set, then the 64-bit page size
                      value of the ip address is recorded.

                  size
                  data[size]
                      If PERF_SAMPLE_AUX is enabled, a snapshot of the aux buffer is recorded.

              PERF_RECORD_MMAP2
                  This  record  includes  extended  information  on  mmap(2)    calls   returning
                  executable  mappings.   The  format  is similar to that of the PERF_RECORD_MMAP
                  record, but includes  extra  values  that  allow  uniquely  identifying  shared
                  mappings.   Depending  on the PERF_RECORD_MISC_MMAP_BUILD_ID bit in the header,
                  the extra values have different layout and meanings.

                      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    идентификатор процесса.

                  tid    идентификатор нити.

                  addr   адрес выделенной памяти.

                  len    длина выделенной памяти.

                  pgoff  смещение на странице выделенной памяти.

                  maj    основной идентификатор подлежащего устройства.

                  min    второстепенный идентификатор подлежащего устройства.

                  ino    номер inode.

                  ino_generation
                         поколение inode.

                  build_id_size
                         is the actual size of build_id field (up to 20).

                  build_id
                         is a raw data to identify a binary.

                  prot   защитная информация.

                  flags  информация о флагах.

                  filename
                         строка, описывающая выделенную память.

              PERF_RECORD_AUX (начиная с Linux 4.1)
                  Эта запись сообщает о доступности новых данных  в  отдельной  буферной  области
                  AUX.

                      struct {
                          struct perf_event_header header;
                          u64    aux_offset;
                          u64    aux_size;
                          u64    flags;
                          struct sample_id sample_id;
                      };

                  aux_offset
                         смещение области AUX mmap, где начинаются новые данные.

                  aux_size
                         размер доступных данных.

                  flags  описывает обновление AUX.

                         PERF_AUX_FLAG_TRUNCATED
                                Если  установлен, то возвращённые данные были обрезаны до размера
                                доступного буфера.

                         PERF_AUX_FLAG_OVERWRITE
                                Если установлен, то возвращённые  данные  перезаписали  имеющиеся
                                данные.

              PERF_RECORD_ITRACE_START (начиная с Linux 4.1)
                  Эта  запись  показывает,  что  процесс  начал  событие  трассировки инструкции,
                  который позволяет инструментам правильно соотносить адреса инструкций в  буфере
                  AUX с подходящим исполняемым файлом.

                      struct {
                          struct perf_event_header header;
                          u32    pid;
                          u32    tid;
                      };

                  pid    идентификатор процесса нити, начавшей трассировку инструкций.

                  tid    идентификатор нити для нити, начавшей трассировку инструкций.

              PERF_RECORD_LOST_SAMPLES (начиная с Linux 4.2)
                  Если используются аппаратное измерение (такое как Intel PEBS), то данная запись
                  указывает, что несколько образцов могли потеряться.

                      struct {
                          struct perf_event_header header;
                          u64    lost;
                          struct sample_id sample_id;
                      };

                  lost   количество потенциально потерянных образцов.

              PERF_RECORD_SWITCH (начиная с Linux 4.3)
                  Данная   запись   указывает   на   выполнение   переключения   контекста.   Бит
                  PERF_RECORD_MISC_SWITCH_OUT  в  поле  misc  показывает направление переключение
                  контекста — из или в текущий процесс.

                      struct {
                          struct perf_event_header header;
                          struct sample_id sample_id;
                      };

              PERF_RECORD_SWITCH_CPU_WIDE (начиная с Linux 4.3)
                  Как и у PERF_RECORD_SWITCH данная запись показывает, что произошло переключение
                  контекста,   но  это  случается  только  при  измерении  в  режиме  CPU-wide  и
                  предоставляет дополнительную информацию о  направлении  переключения  контекста
                  в/из.  Бит  PERF_RECORD_MISC_SWITCH_OUT  в  поле  misc  показывает  направление
                  переключения контекста: в или из текущего процесса.

                      struct {
                          struct perf_event_header header;
                          u32 next_prev_pid;
                          u32 next_prev_tid;
                          struct sample_id sample_id;
                      };

                  next_prev_pid
                         Идентификатор процесса предыдущего (если переключается в) или следующего
                         (если переключается из) процесса ЦП.

                  next_prev_tid
                         Идентификатор нити предыдущей (если переключается в) или следующей (если
                         переключается из) нити ЦП.

              PERF_RECORD_NAMESPACES (начиная с Linux 4.11)
                  This record includes various namespace information of a process.

                      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    is the process ID

                  tid    is the thread ID

                  nr_namespace
                         is the number of namespaces in this record

                  Each namespace has dev and inode fields and is recorded in the  fixed  position
                  like below:

                  NET_NS_INDEX=0
                         Network namespace

                  UTS_NS_INDEX=1
                         Пространства имён UTS

                  IPC_NS_INDEX=2
                         IPC namespace

                  PID_NS_INDEX=3
                         PID namespace

                  USER_NS_INDEX=4
                         User namespace

                  MNT_NS_INDEX=5
                         Mount namespace

                  CGROUP_NS_INDEX=6
                         Cgroup namespace

              PERF_RECORD_KSYMBOL (начиная с Linux 5.0)
                  This record indicates kernel symbol register/unregister events.

                      struct {
                          struct perf_event_header header;
                          u64    addr;
                          u32    len;
                          u16    ksym_type;
                          u16    flags;
                          char   name[];
                          struct sample_id sample_id;
                      };

                  addr   is the address of the kernel symbol.

                  len    is the length of the kernel symbol.

                  ksym_type
                         is  the  type  of  the kernel symbol.  Currently the following types are
                         available:

                         PERF_RECORD_KSYMBOL_TYPE_BPF
                                The kernel symbol is a BPF function.

                  flags  If the PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER is set, then this  event  is
                         for unregistering the kernel symbol.

              PERF_RECORD_BPF_EVENT (начиная с Linux 5.0)
                  This record indicates BPF program is loaded or unloaded.

                      struct {
                          struct perf_event_header header;
                          u16 type;
                          u16 flags;
                          u32 id;
                          u8 tag[BPF_TAG_SIZE];
                          struct sample_id sample_id;
                      };

                  type   is one of the following values:

                         PERF_BPF_EVENT_PROG_LOAD
                                A BPF program is loaded

                         PERF_BPF_EVENT_PROG_UNLOAD
                                A BPF program is unloaded

                  id     is the ID of the BPF program.

                  tag    is the tag of the BPF program.  Currently, BPF_TAG_SIZE is defined as 8.

              PERF_RECORD_CGROUP (начиная с Linux 5.7)
                  This record indicates a new cgroup is created and activated.

                      struct {
                          struct perf_event_header header;
                          u64    id;
                          char   path[];
                          struct sample_id sample_id;
                      };

                  id     is   the   cgroup   identifier.    This   can   be   also  retrieved  by
                         name_to_handle_at(2)  on the cgroup path (as a file handle).

                  path   is the path of the cgroup from the root.

              PERF_RECORD_TEXT_POKE (начиная с Linux 5.8)
                  This record indicates a change in the kernel text.  This includes addition  and
                  removal of the text and the corresponding length is zero in this case.

                      struct {
                          struct perf_event_header header;
                          u64    addr;
                          u16    old_len;
                          u16    new_len;
                          u8     bytes[];
                          struct sample_id sample_id;
                      };

                  addr   is the address of the change

                  old_len
                         is the old length

                  new_len
                         is the new length

                  bytes  contains old bytes immediately followed by new bytes.

   Обработка переполнения
       Можно  задать  события,  которые  будут  уведомлять  о  прохождении порога, указывающие на
       переполнение. Состояние переполнения можно перехватить, проследив за файловым дескриптором
       событий  с  помощью  poll(2),  select(2)  или  epoll(7). Или же события переполнения можно
       перехватить через обработчик сигнала, включив ввод-вывод сигналов о файловом  дескрипторе;
       смотрите описание операций F_SETOWN и F_SETSIG в fcntl(2).

       Переполнения  генерируются только подсчитывающими событиями (значение sample_period должно
       быть ненулевым).

       Существует два способа генерации уведомлений о переполнении.

       Первый: задать значение wakeup_events  или  wakeup_watermark,  которые  будут  срабатывать
       после  записи  определённого  количества  образцов  или  байт кольцевой буфер mmap. В этом
       случае признаком служит POLL_IN.

       Второй: использовать ioctl PERF_EVENT_IOC_REFRESH. Данный ioctl  добавляется  к  счётчику,
       который  уменьшается  каждый  раз  при  наступлении события переполнения. Если значение не
       равно 0, то признаком служит POLL_IN, то после того, как счётчик  достигнет  0,  признаком
       становится POLL_HUP и определяющее событие отключается.

       Актуализация  лидера  группы  событий,  обновляет  всех  его  потомков,  а  актуализация с
       параметром 0 в настоящее время  включает  бесконечную  актуализацию;  такое  поведение  не
       поддерживается и на него нельзя полагаться.

       Начиная   с   Linux   3.18,  признак  POLL_HUP  учитывается,  если  отслеживаемое  событие
       присоединено к другому процессу и этот процесс существует.

   Инструкция rdpmc
       Начиная с Linux 3.4 на x86, вы можете использовать инструкцию rdpmc для выполнения  чтения
       с  низкой  задержкой  без  входа  в  ядро.  Заметим, что использование rdpmc необязательно
       быстрее других способов чтения значений события.

       Возможность использования этого можно определить  по  полю  cap_usr_rdpmc  страницы  mmap;
       документацию по вычислению событий значения можно найти в этом разделе.

       Сначала,  когда  поддержка rdpmc была только включена, любой процесс (не только с активным
       событием perf) мог использовать инструкцию rdpmc для доступа к счётчикам. Начиная с  Linux
       4.0  поддержка  rdpmc  разрешена только, если событие в данный момент включено в контексте
       процесса.   Для   возвращению   к   старому    поведению    запишите    значение    2    в
       /sys/devices/cpu/rdpmc.

   Вызовы ioctl perf_event
       К файловым дескрипторам perf_event_open() допускаются различные вызовы ioctl:

       PERF_EVENT_IOC_ENABLE
              Включает событие или группу событий, указанное в аргументе файлового дескриптора.

              Если  в  аргументе  ioctl  установлен  бит  PERF_IOC_FLAG_GROUP,  то включаются все
              события в группе,  даже  если  указанное  событие  не  лидер  группы  (но  смотрите
              ДЕФЕКТЫ).

       PERF_EVENT_IOC_DISABLE
              Отключает  определённый счётчик или группу событий, указанный в аргументе файлового
              дескриптора.

              Включение или отключение лидера группы включает или выключает всю группу;  то  есть
              пока  отключён  лидер  группы,  не  считается  ни  один из счётчиков. Включение или
              выключение члена группы (не лидера) влияет только на этот  счётчик;  выключение  не
              лидера останавливает его счётчик и не влияет на другие счётчики.

              Если  в  аргументе  ioctl  установлен  бит  PERF_IOC_FLAG_GROUP, то выключаются все
              события в группе,  даже  если  указанное  событие  не  лидер  группы  (но  смотрите
              ДЕФЕКТЫ).

       PERF_EVENT_IOC_REFRESH
              Не  унаследованные  счётчики  переполнения  могут  использовать  это  для установки
              счётчика количества переполнений, после чего он выключается  (значение  задаётся  в
              аргументе).  Последующие  вызовы этого ioctl добавляют значение аргумента в текущий
              счётчик. При каждом переполнении  будет  возникать  уведомление  о  переполнении  с
              установленным POLL_IN пока счётчик не достигнет 0; когда это произойдёт, посылается
              уведомление с установленным POLL_HUP  и  событие  выключается.  Для  значения  0  в
              аргументе поведение не определено.

       PERF_EVENT_IOC_RESET
              Сбрасывает  (в  ноль) счётчик событий, указанный в аргументе файлового дескриптора.
              Сбрасывается  только  счётчики;  невозможно  обнулить  мультиплексирующее  значение
              time_enabled или time_running.

              Если  в  аргументе  ioctl  установлен  бит PERF_IOC_FLAG_GROUP, то сбрасываются все
              события в группе,  даже  если  указанное  событие  не  лидер  группы  (но  смотрите
              ДЕФЕКТЫ).

       PERF_EVENT_IOC_PERIOD
              Обновляет период переполнения события.

              Начиная  с  Linux 3.7 (на ARM) и Linux 3.14 (на всех остальных архитектурах), новый
              период начинает действовать немедленно. В старых ядрах  новый  период  не  работает
              пока не возникнет следующее переполнение.

              Аргумент  представляет  собой  указатель на 64-битное значение, содержащее желаемый
              новый период.

              До Linux 2.6.36 данный ioctl всегда завершался с ошибкой из-за дефекта в ядре.

       PERF_EVENT_IOC_SET_OUTPUT
              Указывает ядру посылать уведомляющие события в указанный файловый дескриптор, не  в
              умолчательный. Все файловые дескрипторы должны быть на одном ЦП.

              В  аргументе  указывается  желаемый  файловый  дескриптор  или -1, если вывод нужно
              игнорировать.

       PERF_EVENT_IOC_SET_FILTER (начиная с Linux 2.6.33)
              Добавить фильтр ftrace в это событие.

              В аргументе указывается указатель на желаемый фильтр ftrace.

       PERF_EVENT_IOC_ID (начиная с Linux 3.12)
              Возвращает значение идентификатора  события  для  заданного  файлового  дескриптора
              события.

              Аргументом является указатель на 64-битное беззнаковое целое число, в которое будет
              сохранён результат.

       PERF_EVENT_IOC_SET_BPF (начиная с Linux 4.1)
              This allows attaching a Berkeley Packet Filter (BPF)  program to an existing kprobe
              tracepoint  event.   You  need  CAP_PERFMON  (since  Linux  5.8)  or  CAP_SYS_ADMIN
              privileges to use this ioctl.

              Аргументом является файловый дескриптор программы BPF,  который  был  создан  ранее
              системным вызовом bpf(2).

       PERF_EVENT_IOC_PAUSE_OUTPUT (начиная с Linux 4.7)
              Позволяет   приостанавливать  и  возобновлять  работу  кольцевого  буфера  событий.
              Приостановленный кольцевой буфер не останавливает  генерацию  измерений,  а  просто
              отбрасывает  их.  Отброшенные  измерения  считаются пропавшими и генерируется, если
              возможно,  измерение  PERF_RECORD_LOST.  Сигнал  переполнения   по-прежнему   может
              возникнуть из-за отброшенного измерения, даже при пустом кольцевом буфере.

              Аргументом    является    беззнаковое    32-битное    целое.   Ненулевое   значение
              приостанавливает кольцевой  буфер,  а  нулевое  —  возобновляет  работу  кольцевого
              буфера.

       PERF_EVENT_MODIFY_ATTRIBUTES (начиная с Linux 4.17)
              Позволяет  изменить  существующее  событие  без  накладных  расходов  на закрытие и
              повторное открытие нового события. В  настоящее  время  поддерживается  только  для
              событий точек останова (breakpoint).

              В  аргументе  содержится  указатель  на  структуру  perf_event_attr  с обновлёнными
              данными события.

       PERF_EVENT_IOC_QUERY_BPF (начиная с Linux 4.16)
              This allows querying which Berkeley Packet Filter (BPF)  programs are  attached  to
              an  existing kprobe tracepoint.  You can only attach one BPF program per event, but
              you can have multiple events attached to a tracepoint.  Querying this value on  one
              tracepoint  event  returns the ID of all BPF programs in all events attached to the
              tracepoint.  You need CAP_PERFMON (since Linux 5.8) or CAP_SYS_ADMIN privileges  to
              use this ioctl.

              В аргументе содержится указатель на структуру
                  struct perf_event_query_bpf {
                      __u32    ids_len;
                      __u32    prog_cnt;
                      __u32    ids[0];
                  };

              Значение поля ids_len показывает сколько идентификаторов могут поместиться в массив
              ids. Значение prog_cnt заполняется ядром  и  показывает  количество  присоединённых
              программ   BPF.  Массив  ids  заполняется  идентификаторами  каждой  присоединённой
              программы BPF. Если имеет больше программ, чем влезает в  массив,  то  ядро  вернёт
              ENOSPC  и  ids_len укажет количество идентификаторов программ, которые были успешно
              скопированы.

   Использование prctl(2)
       Процесс может включить или выключить все группы, в  данный  момент,  открытых  событий  (с
       помощью  операций  prctl(2) PR_TASK_PERF_EVENTS_ENABLE и PR_TASK_PERF_EVENTS_DISABLE). Это
       применимо только к событиям созданным локально вызывающим процессом. Это  не  применимо  к
       событиям,  созданным  другими  процессами,  присоединёнными  к вызывающему процессу, или к
       унаследованным от родительского процесса событиям. При  этом  включаются  или  выключаются
       только лидеры групп, а не члены групп.

   Файлы настройки perf_event
       Файлы в /proc/sys/kernel/

           /proc/sys/kernel/perf_event_paranoid
                  Файл perf_event_paranoid можно использовать для ограничения доступа к счётчикам
                  производительности.

                  2      разрешить только измерения пользовательского пространства (по  умолчанию
                         начиная с Linux 4.6).
                  1      разрешить  измерения ядра и пользовательского пространства (по умолчанию
                         начиная с Linux 4.6).
                  0      разрешить доступ к данным ЦП, но не к структурированным  образцам  точек
                         трассировки.
                  -1     без ограничений.

                  Наличие  файла  perf_event_paranoid  —  официальный метод определения поддержки
                  ядром perf_event_open().

           /proc/sys/kernel/perf_event_max_sample_rate
                  Максимальная  скорость  выборки.  Установка  слишком  большого  значения  может
                  позволить  пользователям задать выборку, которая скажется на производительности
                  машины и, возможно, заблокирует машину. Значение по умолчанию 100000 (образов в
                  секунду).

           /proc/sys/kernel/perf_event_max_stack
                  Данный  файл задаёт максимальную глубину стека кадров, выдаваемых при генерации
                  трассировки вызова.

           /proc/sys/kernel/perf_event_mlock_kb
                  Максимальное количество страниц,  которое  может  получить  непривилегированный
                  пользователь с помощью mlock(2). По умолчанию 516 (кБ).

       Файлы в /sys/bus/event_source/devices/

           Начиная  с  Linux 2.6.34, ядро поддерживает использование нескольких PMU для слежения.
           Информацию о программировании этих PMU  можно  найти  в/sys/bus/event_source/devices/.
           Каждый подкаталог соответствует одному PMU.

           /sys/bus/event_source/devices/*/type (начиная с Linux 2.6.38)
                  Содержит  целое,  которое  можно  использовать  в поле type из perf_event_attr,
                  отражает, что вы хотите использовать этот PMU.

           /sys/bus/event_source/devices/cpu/rdpmc (начиная с Linux 3.4)
                  Если в файле значение 1, то с помощью инструкции rdpmc возможен  прямой  доступ
                  из  пользовательского  пространства  к  регистрам  счётчика производительности.
                  Выключить доступ можно посредством записи 0 в этот файл.

                  В Linux 4.0 это поведение изменено, теперь 1 означает лишь доступ к процессам с
                  активными  событиями  perf,  а 2 возвращает старое поведение разрешения доступа
                  всем.

           /sys/bus/event_source/devices/*/format/ (начиная с Linux 3.4)
                  В этом подкаталоге содержится информация по  зависящим  от  архитектуры  полям,
                  доступным    для    программирования    различных    полей   config   структуры
                  perf_event_attr.

                  The content of each file is the name of the config field, followed by a  colon,
                  followed  by  a series of integer bit ranges separated by commas.  For example,
                  the file event may contain the value  config1:1,6-10,44  which  indicates  that
                  event    is   an   attribute   that   occupies   bits   1,6–10,   and   44   of
                  perf_event_attr::config1.

           /sys/bus/event_source/devices/*/events/ (начиная с Linux 3.4)
                  В данном подкаталоге содержатся поля с предопределёнными событиями.  Содержимое
                  —  строки,  описывающие  настройки  события  в виде полей упомянутых в каталоге
                  ./format/ ранее. Это не обязательно полный список всех событий,  поддерживаемых
                  PMU, но обычно это поднабор событий, считаемый полезным.

                  Содержимое  каждого  файла — список имён атрибутов через запятую. Каждая запись
                  имеет необязательное значение (десятичное или  шестнадцатеричное  число).  Если
                  значение не указано, то предполагается что это однобитовое поле со значением 1.
                  Пример: event=0x2,inv,ldlat=3.

           /sys/bus/event_source/devices/*/uevent
                  Данный файл — стандартное ядерное интерфейсное устройство для введения  событий
                  на лету.

           /sys/bus/event_source/devices/*/cpumask (начиная с Linux 3.7)
                  В  файле  cpumask  содержится  список  целых  чисел  (через  запятую),  которые
                  представляют номер ЦП для каждого сокета  (пакета)  на  материнской  плате.  Он
                  необходим  для  настройки  внеядерных  событий  или  событий  северного  моста,
                  поскольку эти PMU представляют события всего сокета.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On success, perf_event_open()  returns the new file descriptor.  On error, -1 is  returned
       and errno is set to indicate the error.

ОШИБКИ

       Ошибки,   возвращаемые   perf_event_open(),   могут  различаться  на  разных  процессорных
       архитектурах и модулях слежения за производительностью.

       E2BIG  Возвращается,  если  значение  perf_event_attr  size  слишком  мало   (меньше   чем
              PERF_ATTR_SIZE_VER0),  слишком  велико  (больше  размера  страницы)  или больше чем
              поддерживает ядро и дополнительные байты не равны нулю.  При  возврате  E2BIG  ядро
              перезаписывает поле size perf_event_attr размером структуры, который ожидался.

       EACCES Returned  when  the  requested  event  requires  CAP_PERFMON  (since  Linux 5.8) or
              CAP_SYS_ADMIN permissions (or a more permissive perf_event paranoid setting).  Some
              common cases where an unprivileged process may encounter this error: attaching to a
              process owned by a different user; monitoring all processes on a given  CPU  (i.e.,
              specifying  the  pid  argument  as  -1);  and  not  setting exclude_kernel when the
              paranoid setting requires it.

       EBADF  Возвращается, если файловый дескриптор group_fd некорректен,  или  если  установлен
              PERF_FLAG_PID_CGROUP и файловый дескриптор cgroup в pid некорректен.

       EBUSY (начиная с Linux 4.1)
              Возвращается, если другое событие уже владеет эксклюзивным доступом к PMU.

       EFAULT Возвращается, если указатель attr указывает на некорректный адрес памяти.

       EINTR  Returned when trying to mix perf and ftrace handling for a uprobe.

       EINVAL Возвращается,  если  указано  некорректное  событие. Может быть по многим причинам.
              Неполный  список:  значение  sample_freq  больше,  чем  максимальное   настроенное;
              значение  cpu  для  слежения  не  существует;  значение  read_format  вне  пределов
              диапазона; значение sample_type вне пределов диапазона; значение flags вне пределов
              диапазона;  указано  значение  exclusive  или  pinned и событие не является лидером
              группы; значения события config вне пределов диапазона или задают зарезервированные
              биты;  выбранное  общее  событие не поддерживается; не хватает места для добавления
              события.

       EMFILE Каждое открытое событие использует один файловый дескриптор. Если  открыто  большое
              количество  событий,  то  достигается процессное ограничение на количество открытых
              файловых дескрипторов и больше событий создать будет невозможно.

       ENODEV Возвращается,  когда  событие  используется  свойство,  которое  не  поддерживается
              текущим ЦП.

       ENOENT Возвращается,  если  значение  type  некорректно. Эта ошибка также возвращается для
              некоторых неподдерживаемых общих событий.

       ENOSPC До Linux 3.3, при недостаточности места для события возвращалось значение ENOSPC. В
              Linux  3.3  она была заменена на EINVAL. Значение ENOSPC всё ещё возвращается, если
              вы  попытаетесь  добавить  больше  событий  точек  прерывания,  чем  поддерживается
              аппаратно.

       ENOSYS Возвращается,   если   установлен   PERF_SAMPLE_STACK_USER   в   sample_type  и  не
              поддерживается оборудованием.

       EOPNOTSUPP
              Возвращается, если требуемое событие запрашивает специального свойства  аппаратуры,
              но  оно  отсутствует.  Возникает  при запросе низкоуровневых (low-skid) событий без
              поддержки,  трассировке  ветвления  без  поддержки,   выборки,   если   отсутствует
              прерывание PMU и стеки ветви для программных событий.

       EOVERFLOW (начиная с Linux 4.8)
              Возвращается,  если  запрошена  PERF_SAMPLE_CALLCHAIN  и  значение sample_max_stack
              больше максимального, указанного в /proc/sys/kernel/perf_event_max_stack.

       EPERM  Возвращается на многих (но не всех)  архитектурах,  если  указана  неподдерживаемая
              настройка exclude_hv, exclude_idle, exclude_user или exclude_kernel.

              It  can  also happen, as with EACCES, when the requested event requires CAP_PERFMON
              (since Linux 5.8) or CAP_SYS_ADMIN permissions (or  a  more  permissive  perf_event
              paranoid  setting).   This  includes  setting a breakpoint on a kernel address, and
              (since Linux 3.13) setting a kernel function-trace tracepoint.

       ESRCH  Возвращается при попытке присоединения к несуществующему процессу.

ВЕРСИЯ

       Системный   вызов   perf_event_open()   появился   в   Linux   2.6.31,   но    с    именем
       perf_counter_open(). Он был переименован в Linux 2.6.32.

СТАНДАРТЫ

       Данный   системный   вызов  perf_event_open()  существует  только  в  Linux  и  не  должен
       использоваться переносимых программах.

ЗАМЕЧАНИЯ

       Официальным способом наличия поддержки perf_event_open() является  проверка  существования
       файла /proc/sys/kernel/perf_event_paranoid.

       CAP_PERFMON   capability  (since  Linux  5.8)  provides  secure  approach  to  performance
       monitoring and observability operations in a system according to the  principal  of  least
       privilege (POSIX IEEE 1003.1e).  Accessing system performance monitoring and observability
       operations using CAP_PERFMON rather than the much  more  powerful  CAP_SYS_ADMIN  excludes
       chances  to  misuse credentials and makes operations more secure.  CAP_SYS_ADMIN usage for
       secure system performance monitoring and observability is  discouraged  in  favor  of  the
       CAP_PERFMON capability.

ДЕФЕКТЫ

       Значение  F_SETOWN_EX в fcntl(2) требуется для правильного получения сигналов переполнения
       в нитях. Появилось в Linux 2.6.32.

       До Linux 2.6.33 (как минимум, на x86), ядро не проверяло возможность планирования  события
       для  совместной работы до чтения. Это же происходит на всех известных ядрах при включённом
       сторожке  NMI.  Чтобы   увидеть,   работает   ли   заданный   набор   событий,   выполните
       perf_event_open(),  запуск,  затем  выполните  чтения,  зная  наверняка, что ещё не можете
       получить корректные измерения.

       До Linux 2.6.34 ограничения на события не  соблюдались  ядром.  В  этом  случае  некоторые
       события просто возвращали «0», если ядро планировало их в неподходящий слот счётчика.

       До  Linux  2.6.34  существовала  ошибка в мультиплексировании, при котором могли вернуться
       некорректные результаты.

       Ядра с Linux 2.6.35 по Linux 2.6.39 могли быстро упасть, если  включено  «наследование»  и
       запускалось много нитей.

       До Linux 2.6.35 функция PERF_FORMAT_GROUP не работает с присоединёнными процессами.

       Существует ошибка в коде ядра с Linux 2.6.36 по Linux 3.0, из-за которой игнорируется поле
       «watermark» и ядро работает, как если бы было выбрано wakeup_event, если объединение в нём
       не равно нулю.

       С  Linux  2.6.31  по  Linux  3.4 аргумент ioctl PERF_IOC_FLAG_GROUP работает неправильно и
       постоянно применяется к указанному событию, а не ко всем одноуровневым событиям в группе.

       С Linux 3.4 по Linux 3.11, биты mmap cap_usr_rdpmc и  cap_usr_time  отображаются  на  одно
       расположение.  Использующий их код нужно переписать, использовав новые поля cap_user_rdpmc
       и cap_user_time.

       Всегда дважды проверяйте результаты! Различные обобщённые  события  содержат  некорректные
       результаты.  Например,  прошедшие  ветви  измеряются  неправильно на машинах сAMD до Linux
       2.6.35.

ПРИМЕРЫ

       Следующий короткий  пример  показывает  как  подсчитать  количество  инструкций  в  вызове
       printf(3).

       #include <linux/perf_event.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/ioctl.h>
       #include <sys/syscall.h>
       #include <unistd.h>

       static long
       perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                       int cpu, int group_fd, unsigned long flags)
       {
           int ret;

           ret = syscall(SYS_perf_event_open, hw_event, pid, cpu,
                         group_fd, flags);
           return ret;
       }

       int
       main(void)
       {
           int                     fd;
           long long               count;
           struct perf_event_attr  pe;

           memset(&pe, 0, sizeof(pe));
           pe.type = PERF_TYPE_HARDWARE;
           pe.size = sizeof(pe);
           pe.config = PERF_COUNT_HW_INSTRUCTIONS;
           pe.disabled = 1;
           pe.exclude_kernel = 1;
           pe.exclude_hv = 1;

           fd = perf_event_open(&pe, 0, -1, -1, 0);
           if (fd == -1) {
              fprintf(stderr, "Ошибка открытия лидера %llx\n", pe.config);
              exit(EXIT_FAILURE);
           }

           ioctl(fd, PERF_EVENT_IOC_RESET, 0);
           ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

           printf("Измерение счётчика количества инструкций для этого printf\n");

           ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
           read(fd, &count, sizeof(count));

           printf("Использовано %lld инструкций\n", count);

           close(fd);
       }

СМ. ТАКЖЕ

       perf(1), fcntl(2), mmap(2), open(2), prctl(2), read(2)

       Documentation/admin-guide/perf-security.rst in the kernel source tree

ПЕРЕВОД

       Русский   перевод   этой   страницы   руководства   был  сделан  Alexey,  Azamat  Hackimov
       <azamat.hackimov@gmail.com>,  kogamatranslator49  <r.podarov@yandex.ru>,  Kogan,  Max   Is
       <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы  обнаружите  ошибки  в  переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.