oom: make oom_reaper freezable
[linux-2.6-block.git] / samples / bpf / map_perf_test_user.c
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 <unistd.h>
13 #include <assert.h>
14 #include <sys/wait.h>
15 #include <stdlib.h>
16 #include <signal.h>
17 #include <linux/bpf.h>
18 #include <string.h>
19 #include <time.h>
20 #include "libbpf.h"
21 #include "bpf_load.h"
22
23 #define MAX_CNT 1000000
24
25 static __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
33 #define HASH_PREALLOC           (1 << 0)
34 #define PERCPU_HASH_PREALLOC    (1 << 1)
35 #define HASH_KMALLOC            (1 << 2)
36 #define PERCPU_HASH_KMALLOC     (1 << 3)
37
38 static int test_flags = ~0;
39
40 static void test_hash_prealloc(int cpu)
41 {
42         __u64 start_time;
43         int i;
44
45         start_time = time_get_ns();
46         for (i = 0; i < MAX_CNT; i++)
47                 syscall(__NR_getuid);
48         printf("%d:hash_map_perf pre-alloc %lld events per sec\n",
49                cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
50 }
51
52 static void test_percpu_hash_prealloc(int cpu)
53 {
54         __u64 start_time;
55         int i;
56
57         start_time = time_get_ns();
58         for (i = 0; i < MAX_CNT; i++)
59                 syscall(__NR_geteuid);
60         printf("%d:percpu_hash_map_perf pre-alloc %lld events per sec\n",
61                cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
62 }
63
64 static void test_hash_kmalloc(int cpu)
65 {
66         __u64 start_time;
67         int i;
68
69         start_time = time_get_ns();
70         for (i = 0; i < MAX_CNT; i++)
71                 syscall(__NR_getgid);
72         printf("%d:hash_map_perf kmalloc %lld events per sec\n",
73                cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
74 }
75
76 static void test_percpu_hash_kmalloc(int cpu)
77 {
78         __u64 start_time;
79         int i;
80
81         start_time = time_get_ns();
82         for (i = 0; i < MAX_CNT; i++)
83                 syscall(__NR_getegid);
84         printf("%d:percpu_hash_map_perf kmalloc %lld events per sec\n",
85                cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
86 }
87
88 static void loop(int cpu)
89 {
90         cpu_set_t cpuset;
91
92         CPU_ZERO(&cpuset);
93         CPU_SET(cpu, &cpuset);
94         sched_setaffinity(0, sizeof(cpuset), &cpuset);
95
96         if (test_flags & HASH_PREALLOC)
97                 test_hash_prealloc(cpu);
98
99         if (test_flags & PERCPU_HASH_PREALLOC)
100                 test_percpu_hash_prealloc(cpu);
101
102         if (test_flags & HASH_KMALLOC)
103                 test_hash_kmalloc(cpu);
104
105         if (test_flags & PERCPU_HASH_KMALLOC)
106                 test_percpu_hash_kmalloc(cpu);
107 }
108
109 static void run_perf_test(int tasks)
110 {
111         pid_t pid[tasks];
112         int i;
113
114         for (i = 0; i < tasks; i++) {
115                 pid[i] = fork();
116                 if (pid[i] == 0) {
117                         loop(i);
118                         exit(0);
119                 } else if (pid[i] == -1) {
120                         printf("couldn't spawn #%d process\n", i);
121                         exit(1);
122                 }
123         }
124         for (i = 0; i < tasks; i++) {
125                 int status;
126
127                 assert(waitpid(pid[i], &status, 0) == pid[i]);
128                 assert(status == 0);
129         }
130 }
131
132 int main(int argc, char **argv)
133 {
134         struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
135         char filename[256];
136         int num_cpu = 8;
137
138         snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
139         setrlimit(RLIMIT_MEMLOCK, &r);
140
141         if (argc > 1)
142                 test_flags = atoi(argv[1]) ? : test_flags;
143
144         if (argc > 2)
145                 num_cpu = atoi(argv[2]) ? : num_cpu;
146
147         if (load_bpf_file(filename)) {
148                 printf("%s", bpf_log_buf);
149                 return 1;
150         }
151
152         run_perf_test(num_cpu);
153
154         return 0;
155 }