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