^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <ftw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <pthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <internal/lib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "bench.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "util/data.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "util/stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "util/event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "util/symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "util/session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "util/build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "util/synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MMAP_DEV_MAJOR 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DSO_MMAP_RATIO 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static unsigned int iterations = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static unsigned int nr_mmaps = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static unsigned int nr_samples = 100; /* samples per mmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static u64 bench_sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static u16 bench_id_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct bench_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int input_pipe[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int output_pipe[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) pthread_t th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct bench_dso {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int nr_dsos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct bench_dso *dsos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) extern int cmd_inject(int argc, const char *argv[]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static const struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) OPT_UINTEGER('i', "iterations", &iterations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "Number of iterations used to compute average (default: 100)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) OPT_UINTEGER('m', "nr-mmaps", &nr_mmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "Number of mmap events for each iteration (default: 100)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) OPT_UINTEGER('n', "nr-samples", &nr_samples,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "Number of sample events per mmap event (default: 100)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "be more verbose (show iteration count, DSO name, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const char *const bench_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "perf bench internals inject-build-id <options>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Helper for collect_dso that adds the given file as a dso to dso_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * if it contains a build-id. Stops after collecting 4 times more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * we need (for MMAP2 events).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int add_dso(const char *fpath, const struct stat *sb __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int typeflag, struct FTW *ftwbuf __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct bench_dso *dso = &dsos[nr_dsos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct build_id bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (typeflag == FTW_D || typeflag == FTW_SL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (filename__read_build_id(fpath, &bid) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dso->name = realpath(fpath, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (dso->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dso->ino = nr_dsos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_debug2(" Adding DSO: %s\n", fpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* stop if we collected enough DSOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if ((unsigned int)nr_dsos == DSO_MMAP_RATIO * nr_mmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void collect_dso(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dsos = calloc(nr_mmaps * DSO_MMAP_RATIO, sizeof(*dsos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (dsos == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) printf(" Memory allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (nftw("/usr/lib/", add_dso, 10, FTW_PHYS) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pr_debug(" Collected %d DSOs\n", nr_dsos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void release_dso(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0; i < nr_dsos; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct bench_dso *dso = &dsos[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) free(dso->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) free(dsos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Fake address used by mmap and sample events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static u64 dso_map_addr(struct bench_dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 0x400000ULL + dso->ino * 8192ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static ssize_t synthesize_attr(struct bench_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) union perf_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) memset(&event, 0, sizeof(event.attr) + sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) event.header.type = PERF_RECORD_HEADER_ATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) event.header.size = sizeof(event.attr) + sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) event.attr.attr.type = PERF_TYPE_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) event.attr.attr.config = PERF_COUNT_SW_TASK_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) event.attr.attr.exclude_kernel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) event.attr.attr.sample_id_all = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) event.attr.attr.sample_type = bench_sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return writen(data->input_pipe[1], &event, event.header.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static ssize_t synthesize_fork(struct bench_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) union perf_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) memset(&event, 0, sizeof(event.fork) + bench_id_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) event.header.type = PERF_RECORD_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) event.header.misc = PERF_RECORD_MISC_FORK_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) event.header.size = sizeof(event.fork) + bench_id_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) event.fork.ppid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) event.fork.ptid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) event.fork.pid = data->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) event.fork.tid = data->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return writen(data->input_pipe[1], &event, event.header.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static ssize_t synthesize_mmap(struct bench_data *data, struct bench_dso *dso, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) union perf_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) size_t len = offsetof(struct perf_record_mmap2, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u64 *id_hdr_ptr = (void *)&event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int ts_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) len += roundup(strlen(dso->name) + 1, 8) + bench_id_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) memset(&event, 0, min(len, sizeof(event.mmap2)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) event.header.type = PERF_RECORD_MMAP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) event.header.misc = PERF_RECORD_MISC_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) event.header.size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) event.mmap2.pid = data->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) event.mmap2.tid = data->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) event.mmap2.maj = MMAP_DEV_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) event.mmap2.ino = dso->ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) strcpy(event.mmap2.filename, dso->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) event.mmap2.start = dso_map_addr(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) event.mmap2.len = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) event.mmap2.prot = PROT_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (len > sizeof(event.mmap2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* write mmap2 event first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (writen(data->input_pipe[1], &event, len - bench_id_hdr_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* zero-fill sample id header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) memset(id_hdr_ptr, 0, bench_id_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* put timestamp in the right position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ts_idx = (bench_id_hdr_size / sizeof(u64)) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) id_hdr_ptr[ts_idx] = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (writen(data->input_pipe[1], id_hdr_ptr, bench_id_hdr_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ts_idx = (len / sizeof(u64)) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) id_hdr_ptr[ts_idx] = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return writen(data->input_pipe[1], &event, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static ssize_t synthesize_sample(struct bench_data *data, struct bench_dso *dso, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) union perf_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct perf_sample sample = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .tid = data->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .pid = data->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .ip = dso_map_addr(dso),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .time = timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) event.header.type = PERF_RECORD_SAMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) event.header.misc = PERF_RECORD_MISC_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) event.header.size = perf_event__sample_event_size(&sample, bench_sample_type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) perf_event__synthesize_sample(&event, bench_sample_type, 0, &sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return writen(data->input_pipe[1], &event, event.header.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static ssize_t synthesize_flush(struct bench_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct perf_event_header header = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .size = sizeof(header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .type = PERF_RECORD_FINISHED_ROUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return writen(data->input_pipe[1], &header, header.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void *data_reader(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct bench_data *data = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) char buf[8192];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) flag = fcntl(data->output_pipe[0], F_GETFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) fcntl(data->output_pipe[0], F_SETFL, flag | O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* read out data from child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) n = read(data->output_pipe[0], buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (errno != EINTR && errno != EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) usleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) close(data->output_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int setup_injection(struct bench_data *data, bool build_id_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int ready_pipe[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int dev_null_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) char buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (pipe(ready_pipe) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (pipe(data->input_pipe) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (pipe(data->output_pipe) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) data->pid = fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (data->pid < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (data->pid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) const char **inject_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int inject_argc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) close(data->input_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) close(data->output_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) close(ready_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dup2(data->input_pipe[0], STDIN_FILENO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) close(data->input_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dup2(data->output_pipe[1], STDOUT_FILENO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) close(data->output_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dev_null_fd = open("/dev/null", O_WRONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (dev_null_fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dup2(dev_null_fd, STDERR_FILENO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (build_id_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) inject_argc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) inject_argv = calloc(inject_argc + 1, sizeof(*inject_argv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (inject_argv == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) inject_argv[0] = strdup("inject");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) inject_argv[1] = strdup("-b");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (build_id_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) inject_argv[2] = strdup("--buildid-all");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* signal that we're ready to go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) close(ready_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) cmd_inject(inject_argc, inject_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) pthread_create(&data->th, NULL, data_reader, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) close(ready_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) close(data->input_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) close(data->output_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* wait for child ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (read(ready_pipe[0], &buf, 1) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) close(ready_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int inject_build_id(struct bench_data *data, u64 *max_rss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct rusage rusage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* this makes the child to run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (perf_header__write_pipe(data->input_pipe[1]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (synthesize_attr(data) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (synthesize_fork(data) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) for (i = 0; i < nr_mmaps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int idx = rand() % (nr_dsos - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct bench_dso *dso = &dsos[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u64 timestamp = rand() % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pr_debug2(" [%d] injecting: %s\n", i+1, dso->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (synthesize_mmap(data, dso, timestamp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) for (k = 0; k < nr_samples; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (synthesize_sample(data, dso, timestamp + k * 1000) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if ((i + 1) % 10 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (synthesize_flush(data) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* tihs makes the child to finish */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) close(data->input_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) wait4(data->pid, &status, 0, &rusage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) *max_rss = rusage.ru_maxrss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pr_debug(" Child %d exited with %d\n", data->pid, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void do_inject_loop(struct bench_data *data, bool build_id_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct stats time_stats, mem_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) double time_average, time_stddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) double mem_average, mem_stddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) init_stats(&time_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) init_stats(&mem_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pr_debug(" Build-id%s injection benchmark\n", build_id_all ? "-all" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) for (i = 0; i < iterations; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct timeval start, end, diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u64 runtime_us, max_rss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_debug(" Iteration #%d\n", i+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (setup_injection(data, build_id_all) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) printf(" Build-id injection setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) gettimeofday(&start, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (inject_build_id(data, &max_rss) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) printf(" Build-id injection failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) gettimeofday(&end, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) timersub(&end, &start, &diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) update_stats(&time_stats, runtime_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) update_stats(&mem_stats, max_rss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pthread_join(data->th, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) time_average = avg_stats(&time_stats) / USEC_PER_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) time_stddev = stddev_stats(&time_stats) / USEC_PER_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) printf(" Average build-id%s injection took: %.3f msec (+- %.3f msec)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) build_id_all ? "-all" : "", time_average, time_stddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* each iteration, it processes MMAP2 + BUILD_ID + nr_samples * SAMPLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) time_average = avg_stats(&time_stats) / (nr_mmaps * (nr_samples + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) time_stddev = stddev_stats(&time_stats) / (nr_mmaps * (nr_samples + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) printf(" Average time per event: %.3f usec (+- %.3f usec)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) time_average, time_stddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) mem_average = avg_stats(&mem_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mem_stddev = stddev_stats(&mem_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) printf(" Average memory usage: %.0f KB (+- %.0f KB)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) mem_average, mem_stddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int do_inject_loops(struct bench_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) srand(time(NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) symbol__init(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) bench_sample_type = PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) bench_sample_type |= PERF_SAMPLE_TID | PERF_SAMPLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) bench_id_hdr_size = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) collect_dso();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (nr_dsos == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) printf(" Cannot collect DSOs for injection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) do_inject_loop(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) do_inject_loop(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) release_dso();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int bench_inject_build_id(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct bench_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) argc = parse_options(argc, argv, options, bench_usage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) usage_with_options(bench_usage, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return do_inject_loops(&data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)