Blame view

samples/bpf/offwaketime_user.c 3.33 KB
25763b3c8   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
2
  /* Copyright (c) 2016 Facebook
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
3
4
5
6
7
   */
  #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <signal.h>
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
8
9
  #include <linux/perf_event.h>
  #include <errno.h>
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
10
11
  #include <stdbool.h>
  #include <sys/resource.h>
7cf245a37   Toke Høiland-Jørgensen   samples/bpf: Use ...
12
  #include <bpf/libbpf.h>
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
13
  #include <bpf/bpf.h>
28dbf861d   Yonghong Song   samples/bpf: move...
14
  #include "trace_helpers.h"
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
15

a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
16
  #define PRINT_RAW_ADDR 0
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
17
18
  /* counts, stackmap */
  static int map_fd[2];
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
19
20
21
22
23
24
  static void print_ksym(__u64 addr)
  {
  	struct ksym *sym;
  
  	if (!addr)
  		return;
3622e7e49   Alexei Starovoitov   samples/bpf: move...
25
  	sym = ksym_search(addr);
e67b2c715   Daniel T. Lee   samples, selftest...
26
27
28
29
30
  	if (!sym) {
  		printf("ksym not found. Is kallsyms loaded?
  ");
  		return;
  	}
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  	if (PRINT_RAW_ADDR)
  		printf("%s/%llx;", sym->name, addr);
  	else
  		printf("%s;", sym->name);
  }
  
  #define TASK_COMM_LEN 16
  
  struct key_t {
  	char waker[TASK_COMM_LEN];
  	char target[TASK_COMM_LEN];
  	__u32 wret;
  	__u32 tret;
  };
  
  static void print_stack(struct key_t *key, __u64 count)
  {
  	__u64 ip[PERF_MAX_STACK_DEPTH] = {};
  	static bool warned;
  	int i;
  
  	printf("%s;", key->target);
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
53
  	if (bpf_map_lookup_elem(map_fd[1], &key->tret, ip) != 0) {
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
54
55
56
57
58
59
  		printf("---;");
  	} else {
  		for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--)
  			print_ksym(ip[i]);
  	}
  	printf("-;");
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
60
  	if (bpf_map_lookup_elem(map_fd[1], &key->wret, ip) != 0) {
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  		printf("---;");
  	} else {
  		for (i = 0; i < PERF_MAX_STACK_DEPTH; i++)
  			print_ksym(ip[i]);
  	}
  	printf(";%s %lld
  ", key->waker, count);
  
  	if ((key->tret == -EEXIST || key->wret == -EEXIST) && !warned) {
  		printf("stackmap collisions seen. Consider increasing size
  ");
  		warned = true;
  	} else if (((int)(key->tret) < 0 || (int)(key->wret) < 0)) {
  		printf("err stackid %d %d
  ", key->tret, key->wret);
  	}
  }
  
  static void print_stacks(int fd)
  {
  	struct key_t key = {}, next_key;
  	__u64 value;
d40fc181e   Joe Stringer   samples/bpf: Make...
83
84
  	while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
  		bpf_map_lookup_elem(fd, &next_key, &value);
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  		print_stack(&next_key, value);
  		key = next_key;
  	}
  }
  
  static void int_exit(int sig)
  {
  	print_stacks(map_fd[0]);
  	exit(0);
  }
  
  int main(int argc, char **argv)
  {
  	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
99
100
101
102
  	struct bpf_object *obj = NULL;
  	struct bpf_link *links[2];
  	struct bpf_program *prog;
  	int delay = 1, i = 0;
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
103
  	char filename[256];
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
104

f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
105
106
107
108
  	if (setrlimit(RLIMIT_MEMLOCK, &r)) {
  		perror("setrlimit(RLIMIT_MEMLOCK)");
  		return 1;
  	}
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
109
110
111
112
113
114
  
  	if (load_kallsyms()) {
  		printf("failed to process /proc/kallsyms
  ");
  		return 2;
  	}
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
  	obj = bpf_object__open_file(filename, NULL);
  	if (libbpf_get_error(obj)) {
  		fprintf(stderr, "ERROR: opening BPF object file failed
  ");
  		obj = NULL;
  		goto cleanup;
  	}
  
  	/* load BPF program */
  	if (bpf_object__load(obj)) {
  		fprintf(stderr, "ERROR: loading BPF object file failed
  ");
  		goto cleanup;
  	}
  
  	map_fd[0] = bpf_object__find_map_fd_by_name(obj, "counts");
  	map_fd[1] = bpf_object__find_map_fd_by_name(obj, "stackmap");
  	if (map_fd[0] < 0 || map_fd[1] < 0) {
  		fprintf(stderr, "ERROR: finding a map in obj file failed
  ");
  		goto cleanup;
  	}
  
  	signal(SIGINT, int_exit);
  	signal(SIGTERM, int_exit);
  
  	bpf_object__for_each_program(prog, obj) {
  		links[i] = bpf_program__attach(prog);
  		if (libbpf_get_error(links[i])) {
  			fprintf(stderr, "ERROR: bpf_program__attach failed
  ");
  			links[i] = NULL;
  			goto cleanup;
  		}
  		i++;
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
151
152
153
154
155
156
  	}
  
  	if (argc > 1)
  		delay = atoi(argv[1]);
  	sleep(delay);
  	print_stacks(map_fd[0]);
f0c328f8a   Daniel T. Lee   samples: bpf: Ref...
157
158
159
160
161
  cleanup:
  	for (i--; i >= 0; i--)
  		bpf_link__destroy(links[i]);
  
  	bpf_object__close(obj);
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
162
163
  	return 0;
  }