brintos

brintos / linux-shallow public Read only

0
0
Text · 4.5 KiB · dbd86f7 Raw
226 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2016 Facebook3 */4#define _GNU_SOURCE5#include <sched.h>6#include <errno.h>7#include <stdio.h>8#include <sys/types.h>9#include <asm/unistd.h>10#include <fcntl.h>11#include <unistd.h>12#include <assert.h>13#include <sys/wait.h>14#include <sys/socket.h>15#include <arpa/inet.h>16#include <stdlib.h>17#include <signal.h>18#include <linux/bpf.h>19#include <string.h>20#include <time.h>21#include <bpf/bpf.h>22#include <bpf/libbpf.h>23 24#define MAX_CNT 100000025#define DUMMY_IP "127.0.0.1"26#define DUMMY_PORT 8027 28static struct bpf_link *links[2];29static struct bpf_object *obj;30static int cnt;31 32static __u64 time_get_ns(void)33{34	struct timespec ts;35 36	clock_gettime(CLOCK_MONOTONIC, &ts);37	return ts.tv_sec * 1000000000ull + ts.tv_nsec;38}39 40static void test_task_rename(int cpu)41{42	char buf[] = "test\n";43	__u64 start_time;44	int i, fd;45 46	fd = open("/proc/self/comm", O_WRONLY|O_TRUNC);47	if (fd < 0) {48		printf("couldn't open /proc\n");49		exit(1);50	}51	start_time = time_get_ns();52	for (i = 0; i < MAX_CNT; i++) {53		if (write(fd, buf, sizeof(buf)) < 0) {54			printf("task rename failed: %s\n", strerror(errno));55			close(fd);56			return;57		}58	}59	printf("task_rename:%d: %lld events per sec\n",60	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));61	close(fd);62}63 64static void test_fib_table_lookup(int cpu)65{66	struct sockaddr_in addr;67	char buf[] = "test\n";68	__u64 start_time;69	int i, fd;70 71	fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);72	if (fd < 0) {73		printf("couldn't open socket\n");74		exit(1);75	}76	memset((char *)&addr, 0, sizeof(addr));77	addr.sin_addr.s_addr = inet_addr(DUMMY_IP);78	addr.sin_port = htons(DUMMY_PORT);79	addr.sin_family = AF_INET;80	start_time = time_get_ns();81	for (i = 0; i < MAX_CNT; i++) {82		if (sendto(fd, buf, strlen(buf), 0,83			   (struct sockaddr *)&addr, sizeof(addr)) < 0) {84			printf("failed to start ping: %s\n", strerror(errno));85			close(fd);86			return;87		}88	}89	printf("fib_table_lookup:%d: %lld events per sec\n",90	       cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));91	close(fd);92}93 94static void loop(int cpu, int flags)95{96	cpu_set_t cpuset;97 98	CPU_ZERO(&cpuset);99	CPU_SET(cpu, &cpuset);100	sched_setaffinity(0, sizeof(cpuset), &cpuset);101 102	if (flags & 1)103		test_task_rename(cpu);104	if (flags & 2)105		test_fib_table_lookup(cpu);106}107 108static void run_perf_test(int tasks, int flags)109{110	pid_t pid[tasks];111	int i;112 113	for (i = 0; i < tasks; i++) {114		pid[i] = fork();115		if (pid[i] == 0) {116			loop(i, flags);117			exit(0);118		} else if (pid[i] == -1) {119			printf("couldn't spawn #%d process\n", i);120			exit(1);121		}122	}123	for (i = 0; i < tasks; i++) {124		int status;125 126		assert(waitpid(pid[i], &status, 0) == pid[i]);127		assert(status == 0);128	}129}130 131static int load_progs(char *filename)132{133	struct bpf_program *prog;134	int err = 0;135 136	obj = bpf_object__open_file(filename, NULL);137	err = libbpf_get_error(obj);138	if (err < 0) {139		fprintf(stderr, "ERROR: opening BPF object file failed\n");140		return err;141	}142 143	/* load BPF program */144	err = bpf_object__load(obj);145	if (err < 0) {146		fprintf(stderr, "ERROR: loading BPF object file failed\n");147		return err;148	}149 150	bpf_object__for_each_program(prog, obj) {151		links[cnt] = bpf_program__attach(prog);152		err = libbpf_get_error(links[cnt]);153		if (err < 0) {154			fprintf(stderr, "ERROR: bpf_program__attach failed\n");155			links[cnt] = NULL;156			return err;157		}158		cnt++;159	}160 161	return err;162}163 164static void unload_progs(void)165{166	while (cnt)167		bpf_link__destroy(links[--cnt]);168 169	bpf_object__close(obj);170}171 172int main(int argc, char **argv)173{174	int num_cpu = sysconf(_SC_NPROCESSORS_ONLN);175	int test_flags = ~0;176	char filename[256];177	int err = 0;178 179 180	if (argc > 1)181		test_flags = atoi(argv[1]) ? : test_flags;182	if (argc > 2)183		num_cpu = atoi(argv[2]) ? : num_cpu;184 185	if (test_flags & 0x3) {186		printf("BASE\n");187		run_perf_test(num_cpu, test_flags);188	}189 190	if (test_flags & 0xC) {191		snprintf(filename, sizeof(filename),192			 "%s_kprobe.bpf.o", argv[0]);193 194		printf("w/KPROBE\n");195		err = load_progs(filename);196		if (!err)197			run_perf_test(num_cpu, test_flags >> 2);198 199		unload_progs();200	}201 202	if (test_flags & 0x30) {203		snprintf(filename, sizeof(filename),204			 "%s_tp.bpf.o", argv[0]);205		printf("w/TRACEPOINT\n");206		err = load_progs(filename);207		if (!err)208			run_perf_test(num_cpu, test_flags >> 4);209 210		unload_progs();211	}212 213	if (test_flags & 0xC0) {214		snprintf(filename, sizeof(filename),215			 "%s_raw_tp.bpf.o", argv[0]);216		printf("w/RAW_TRACEPOINT\n");217		err = load_progs(filename);218		if (!err)219			run_perf_test(num_cpu, test_flags >> 6);220 221		unload_progs();222	}223 224	return err;225}226