Blame view

samples/bpf/offwaketime_user.c 2.46 KB
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /* Copyright (c) 2016 Facebook
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of version 2 of the GNU General Public
   * License as published by the Free Software Foundation.
   */
  #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <signal.h>
  #include <linux/bpf.h>
  #include <string.h>
  #include <linux/perf_event.h>
  #include <errno.h>
  #include <assert.h>
  #include <stdbool.h>
  #include <sys/resource.h>
  #include "libbpf.h"
  #include "bpf_load.h"
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
20
  #define PRINT_RAW_ADDR 0
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
21
22
23
24
25
26
  static void print_ksym(__u64 addr)
  {
  	struct ksym *sym;
  
  	if (!addr)
  		return;
3622e7e49   Alexei Starovoitov   samples/bpf: move...
27
  	sym = ksym_search(addr);
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  	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);
d40fc181e   Joe Stringer   samples/bpf: Make...
50
  	if (bpf_map_lookup_elem(map_fd[3], &key->tret, ip) != 0) {
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
51
52
53
54
55
56
  		printf("---;");
  	} else {
  		for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--)
  			print_ksym(ip[i]);
  	}
  	printf("-;");
d40fc181e   Joe Stringer   samples/bpf: Make...
57
  	if (bpf_map_lookup_elem(map_fd[3], &key->wret, ip) != 0) {
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  		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...
80
81
  	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...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  		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};
  	char filename[256];
  	int delay = 1;
  
  	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
  	setrlimit(RLIMIT_MEMLOCK, &r);
  
  	signal(SIGINT, int_exit);
ad990dbe6   Andy Gospodarek   samples/bpf: run ...
103
  	signal(SIGTERM, int_exit);
a6ffe7b9d   Alexei Starovoitov   samples/bpf: offw...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  
  	if (load_kallsyms()) {
  		printf("failed to process /proc/kallsyms
  ");
  		return 2;
  	}
  
  	if (load_bpf_file(filename)) {
  		printf("%s", bpf_log_buf);
  		return 1;
  	}
  
  	if (argc > 1)
  		delay = atoi(argv[1]);
  	sleep(delay);
  	print_stacks(map_fd[0]);
  
  	return 0;
  }