linux/samples/bpf/test_overhead_user.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Copyright (c) 2016 Facebook
   3 */
   4#define _GNU_SOURCE
   5#include <sched.h>
   6#include <errno.h>
   7#include <stdio.h>
   8#include <sys/types.h>
   9#include <asm/unistd.h>
  10#include <fcntl.h>
  11#include <unistd.h>
  12#include <assert.h>
  13#include <sys/wait.h>
  14#include <stdlib.h>
  15#include <signal.h>
  16#include <linux/bpf.h>
  17#include <string.h>
  18#include <time.h>
  19#include <sys/resource.h>
  20#include <bpf/bpf.h>
  21#include "bpf_load.h"
  22
  23#define MAX_CNT 1000000
  24
  25static __u64 time_get_ns(void)
  26{
  27        struct timespec ts;
  28
  29        clock_gettime(CLOCK_MONOTONIC, &ts);
  30        return ts.tv_sec * 1000000000ull + ts.tv_nsec;
  31}
  32
  33static void test_task_rename(int cpu)
  34{
  35        __u64 start_time;
  36        char buf[] = "test\n";
  37        int i, fd;
  38
  39        fd = open("/proc/self/comm", O_WRONLY|O_TRUNC);
  40        if (fd < 0) {
  41                printf("couldn't open /proc\n");
  42                exit(1);
  43        }
  44        start_time = time_get_ns();
  45        for (i = 0; i < MAX_CNT; i++) {
  46                if (write(fd, buf, sizeof(buf)) < 0) {
  47                        printf("task rename failed: %s\n", strerror(errno));
  48                        close(fd);
  49                        return;
  50                }
  51        }
  52        printf("task_rename:%d: %lld events per sec\n",
  53               cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
  54        close(fd);
  55}
  56
  57static void test_urandom_read(int cpu)
  58{
  59        __u64 start_time;
  60        char buf[4];
  61        int i, fd;
  62
  63        fd = open("/dev/urandom", O_RDONLY);
  64        if (fd < 0) {
  65                printf("couldn't open /dev/urandom\n");
  66                exit(1);
  67        }
  68        start_time = time_get_ns();
  69        for (i = 0; i < MAX_CNT; i++) {
  70                if (read(fd, buf, sizeof(buf)) < 0) {
  71                        printf("failed to read from /dev/urandom: %s\n", strerror(errno));
  72                        close(fd);
  73                        return;
  74                }
  75        }
  76        printf("urandom_read:%d: %lld events per sec\n",
  77               cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
  78        close(fd);
  79}
  80
  81static void loop(int cpu, int flags)
  82{
  83        cpu_set_t cpuset;
  84
  85        CPU_ZERO(&cpuset);
  86        CPU_SET(cpu, &cpuset);
  87        sched_setaffinity(0, sizeof(cpuset), &cpuset);
  88
  89        if (flags & 1)
  90                test_task_rename(cpu);
  91        if (flags & 2)
  92                test_urandom_read(cpu);
  93}
  94
  95static void run_perf_test(int tasks, int flags)
  96{
  97        pid_t pid[tasks];
  98        int i;
  99
 100        for (i = 0; i < tasks; i++) {
 101                pid[i] = fork();
 102                if (pid[i] == 0) {
 103                        loop(i, flags);
 104                        exit(0);
 105                } else if (pid[i] == -1) {
 106                        printf("couldn't spawn #%d process\n", i);
 107                        exit(1);
 108                }
 109        }
 110        for (i = 0; i < tasks; i++) {
 111                int status;
 112
 113                assert(waitpid(pid[i], &status, 0) == pid[i]);
 114                assert(status == 0);
 115        }
 116}
 117
 118static void unload_progs(void)
 119{
 120        close(prog_fd[0]);
 121        close(prog_fd[1]);
 122        close(event_fd[0]);
 123        close(event_fd[1]);
 124}
 125
 126int main(int argc, char **argv)
 127{
 128        struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
 129        char filename[256];
 130        int num_cpu = 8;
 131        int test_flags = ~0;
 132
 133        setrlimit(RLIMIT_MEMLOCK, &r);
 134
 135        if (argc > 1)
 136                test_flags = atoi(argv[1]) ? : test_flags;
 137        if (argc > 2)
 138                num_cpu = atoi(argv[2]) ? : num_cpu;
 139
 140        if (test_flags & 0x3) {
 141                printf("BASE\n");
 142                run_perf_test(num_cpu, test_flags);
 143        }
 144
 145        if (test_flags & 0xC) {
 146                snprintf(filename, sizeof(filename),
 147                         "%s_kprobe_kern.o", argv[0]);
 148                if (load_bpf_file(filename)) {
 149                        printf("%s", bpf_log_buf);
 150                        return 1;
 151                }
 152                printf("w/KPROBE\n");
 153                run_perf_test(num_cpu, test_flags >> 2);
 154                unload_progs();
 155        }
 156
 157        if (test_flags & 0x30) {
 158                snprintf(filename, sizeof(filename),
 159                         "%s_tp_kern.o", argv[0]);
 160                if (load_bpf_file(filename)) {
 161                        printf("%s", bpf_log_buf);
 162                        return 1;
 163                }
 164                printf("w/TRACEPOINT\n");
 165                run_perf_test(num_cpu, test_flags >> 4);
 166                unload_progs();
 167        }
 168
 169        if (test_flags & 0xC0) {
 170                snprintf(filename, sizeof(filename),
 171                         "%s_raw_tp_kern.o", argv[0]);
 172                if (load_bpf_file(filename)) {
 173                        printf("%s", bpf_log_buf);
 174                        return 1;
 175                }
 176                printf("w/RAW_TRACEPOINT\n");
 177                run_perf_test(num_cpu, test_flags >> 6);
 178                unload_progs();
 179        }
 180
 181        return 0;
 182}
 183