at v4.6-rc1 155 lines 3.3 kB view raw
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 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 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 38static int test_flags = ~0; 39 40static 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 52static 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 64static 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 76static 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 88static 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 109static 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 132int 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}