Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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 <sys/resource.h>
 21#include "libbpf.h"
 22#include "bpf_load.h"
 23
 24#define MAX_CNT 1000000
 25
 26static __u64 time_get_ns(void)
 27{
 28	struct timespec ts;
 29
 30	clock_gettime(CLOCK_MONOTONIC, &ts);
 31	return ts.tv_sec * 1000000000ull + ts.tv_nsec;
 32}
 33
 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
 41static int test_flags = ~0;
 42
 43static void test_hash_prealloc(int cpu)
 44{
 45	__u64 start_time;
 46	int i;
 47
 48	start_time = time_get_ns();
 49	for (i = 0; i < MAX_CNT; i++)
 50		syscall(__NR_getuid);
 51	printf("%d:hash_map_perf pre-alloc %lld events per sec\n",
 52	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
 53}
 54
 55static void test_lru_hash_prealloc(int cpu)
 56{
 57	__u64 start_time;
 58	int i;
 59
 60	start_time = time_get_ns();
 61	for (i = 0; i < MAX_CNT; i++)
 62		syscall(__NR_getpid);
 63	printf("%d:lru_hash_map_perf pre-alloc %lld events per sec\n",
 64	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
 65}
 66
 67static void test_percpu_lru_hash_prealloc(int cpu)
 68{
 69	__u64 start_time;
 70	int i;
 71
 72	start_time = time_get_ns();
 73	for (i = 0; i < MAX_CNT; i++)
 74		syscall(__NR_getppid);
 75	printf("%d:lru_hash_map_perf pre-alloc %lld events per sec\n",
 76	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
 77}
 78
 79static void test_percpu_hash_prealloc(int cpu)
 80{
 81	__u64 start_time;
 82	int i;
 83
 84	start_time = time_get_ns();
 85	for (i = 0; i < MAX_CNT; i++)
 86		syscall(__NR_geteuid);
 87	printf("%d:percpu_hash_map_perf pre-alloc %lld events per sec\n",
 88	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
 89}
 90
 91static void test_hash_kmalloc(int cpu)
 92{
 93	__u64 start_time;
 94	int i;
 95
 96	start_time = time_get_ns();
 97	for (i = 0; i < MAX_CNT; i++)
 98		syscall(__NR_getgid);
 99	printf("%d:hash_map_perf kmalloc %lld events per sec\n",
100	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
101}
102
103static void test_percpu_hash_kmalloc(int cpu)
104{
105	__u64 start_time;
106	int i;
107
108	start_time = time_get_ns();
109	for (i = 0; i < MAX_CNT; i++)
110		syscall(__NR_getegid);
111	printf("%d:percpu_hash_map_perf kmalloc %lld events per sec\n",
112	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
113}
114
115static void loop(int cpu)
116{
117	cpu_set_t cpuset;
118
119	CPU_ZERO(&cpuset);
120	CPU_SET(cpu, &cpuset);
121	sched_setaffinity(0, sizeof(cpuset), &cpuset);
122
123	if (test_flags & HASH_PREALLOC)
124		test_hash_prealloc(cpu);
125
126	if (test_flags & PERCPU_HASH_PREALLOC)
127		test_percpu_hash_prealloc(cpu);
128
129	if (test_flags & HASH_KMALLOC)
130		test_hash_kmalloc(cpu);
131
132	if (test_flags & PERCPU_HASH_KMALLOC)
133		test_percpu_hash_kmalloc(cpu);
134
135	if (test_flags & LRU_HASH_PREALLOC)
136		test_lru_hash_prealloc(cpu);
137
138	if (test_flags & PERCPU_LRU_HASH_PREALLOC)
139		test_percpu_lru_hash_prealloc(cpu);
140}
141
142static void run_perf_test(int tasks)
143{
144	pid_t pid[tasks];
145	int i;
146
147	for (i = 0; i < tasks; i++) {
148		pid[i] = fork();
149		if (pid[i] == 0) {
150			loop(i);
151			exit(0);
152		} else if (pid[i] == -1) {
153			printf("couldn't spawn #%d process\n", i);
154			exit(1);
155		}
156	}
157	for (i = 0; i < tasks; i++) {
158		int status;
159
160		assert(waitpid(pid[i], &status, 0) == pid[i]);
161		assert(status == 0);
162	}
163}
164
165int main(int argc, char **argv)
166{
167	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
168	char filename[256];
169	int num_cpu = 8;
170
171	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
172	setrlimit(RLIMIT_MEMLOCK, &r);
173
174	if (argc > 1)
175		test_flags = atoi(argv[1]) ? : test_flags;
176
177	if (argc > 2)
178		num_cpu = atoi(argv[2]) ? : num_cpu;
179
180	if (load_bpf_file(filename)) {
181		printf("%s", bpf_log_buf);
182		return 1;
183	}
184
185	run_perf_test(num_cpu);
186
187	return 0;
188}