1 /* Copyright (c) 2016 Facebook
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.
10 #include <sys/types.h>
11 #include <asm/unistd.h>
17 #include <linux/bpf.h>
20 #include <sys/resource.h>
24 #define MAX_CNT 1000000
26 static __u64
time_get_ns(void)
30 clock_gettime(CLOCK_MONOTONIC
, &ts
);
31 return ts
.tv_sec
* 1000000000ull + ts
.tv_nsec
;
34 #define HASH_PREALLOC (1 << 0)
35 #define PERCPU_HASH_PREALLOC (1 << 1)
36 #define HASH_KMALLOC (1 << 2)
37 #define PERCPU_HASH_KMALLOC (1 << 3)
38 #define LRU_HASH_PREALLOC (1 << 4)
39 #define PERCPU_LRU_HASH_PREALLOC (1 << 5)
40 #define LPM_KMALLOC (1 << 6)
42 static int test_flags
= ~0;
44 static void test_hash_prealloc(int cpu
)
49 start_time
= time_get_ns();
50 for (i
= 0; i
< MAX_CNT
; i
++)
52 printf("%d:hash_map_perf pre-alloc %lld events per sec\n",
53 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
56 static void test_lru_hash_prealloc(int cpu
)
61 start_time
= time_get_ns();
62 for (i
= 0; i
< MAX_CNT
; i
++)
64 printf("%d:lru_hash_map_perf pre-alloc %lld events per sec\n",
65 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
68 static void test_percpu_lru_hash_prealloc(int cpu
)
73 start_time
= time_get_ns();
74 for (i
= 0; i
< MAX_CNT
; i
++)
75 syscall(__NR_getppid
);
76 printf("%d:lru_hash_map_perf pre-alloc %lld events per sec\n",
77 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
80 static void test_percpu_hash_prealloc(int cpu
)
85 start_time
= time_get_ns();
86 for (i
= 0; i
< MAX_CNT
; i
++)
87 syscall(__NR_geteuid
);
88 printf("%d:percpu_hash_map_perf pre-alloc %lld events per sec\n",
89 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
92 static void test_hash_kmalloc(int cpu
)
97 start_time
= time_get_ns();
98 for (i
= 0; i
< MAX_CNT
; i
++)
100 printf("%d:hash_map_perf kmalloc %lld events per sec\n",
101 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
104 static void test_percpu_hash_kmalloc(int cpu
)
109 start_time
= time_get_ns();
110 for (i
= 0; i
< MAX_CNT
; i
++)
111 syscall(__NR_getegid
);
112 printf("%d:percpu_hash_map_perf kmalloc %lld events per sec\n",
113 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
116 static void test_lpm_kmalloc(int cpu
)
121 start_time
= time_get_ns();
122 for (i
= 0; i
< MAX_CNT
; i
++)
123 syscall(__NR_gettid
);
124 printf("%d:lpm_perf kmalloc %lld events per sec\n",
125 cpu
, MAX_CNT
* 1000000000ll / (time_get_ns() - start_time
));
128 static void loop(int cpu
)
133 CPU_SET(cpu
, &cpuset
);
134 sched_setaffinity(0, sizeof(cpuset
), &cpuset
);
136 if (test_flags
& HASH_PREALLOC
)
137 test_hash_prealloc(cpu
);
139 if (test_flags
& PERCPU_HASH_PREALLOC
)
140 test_percpu_hash_prealloc(cpu
);
142 if (test_flags
& HASH_KMALLOC
)
143 test_hash_kmalloc(cpu
);
145 if (test_flags
& PERCPU_HASH_KMALLOC
)
146 test_percpu_hash_kmalloc(cpu
);
148 if (test_flags
& LRU_HASH_PREALLOC
)
149 test_lru_hash_prealloc(cpu
);
151 if (test_flags
& PERCPU_LRU_HASH_PREALLOC
)
152 test_percpu_lru_hash_prealloc(cpu
);
154 if (test_flags
& LPM_KMALLOC
)
155 test_lpm_kmalloc(cpu
);
158 static void run_perf_test(int tasks
)
163 for (i
= 0; i
< tasks
; i
++) {
168 } else if (pid
[i
] == -1) {
169 printf("couldn't spawn #%d process\n", i
);
173 for (i
= 0; i
< tasks
; i
++) {
176 assert(waitpid(pid
[i
], &status
, 0) == pid
[i
]);
181 static void fill_lpm_trie(void)
183 struct bpf_lpm_trie_key
*key
;
184 unsigned long value
= 0;
188 key
= alloca(sizeof(*key
) + 4);
191 for (i
= 0; i
< 512; ++i
) {
192 key
->prefixlen
= rand() % 33;
193 key
->data
[0] = rand() & 0xff;
194 key
->data
[1] = rand() & 0xff;
195 key
->data
[2] = rand() & 0xff;
196 key
->data
[3] = rand() & 0xff;
197 r
= bpf_map_update_elem(map_fd
[6], key
, &value
, 0);
208 r
= bpf_map_update_elem(map_fd
[6], key
, &value
, 0);
212 int main(int argc
, char **argv
)
214 struct rlimit r
= {RLIM_INFINITY
, RLIM_INFINITY
};
218 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
219 setrlimit(RLIMIT_MEMLOCK
, &r
);
222 test_flags
= atoi(argv
[1]) ? : test_flags
;
225 num_cpu
= atoi(argv
[2]) ? : num_cpu
;
227 if (load_bpf_file(filename
)) {
228 printf("%s", bpf_log_buf
);
234 run_perf_test(num_cpu
);