hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/tools/testing/selftests/bpf/trace_helpers.c
....@@ -4,11 +4,14 @@
44 #include <string.h>
55 #include <assert.h>
66 #include <errno.h>
7
+#include <fcntl.h>
78 #include <poll.h>
89 #include <unistd.h>
910 #include <linux/perf_event.h>
1011 #include <sys/mman.h>
1112 #include "trace_helpers.h"
13
+
14
+#define DEBUGFS "/sys/kernel/debug/tracing/"
1215
1316 #define MAX_SYMS 300000
1417 static struct ksym syms[MAX_SYMS];
....@@ -30,9 +33,7 @@
3033 if (!f)
3134 return -ENOENT;
3235
33
- while (!feof(f)) {
34
- if (!fgets(buf, sizeof(buf), f))
35
- break;
36
+ while (fgets(buf, sizeof(buf), f)) {
3637 if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3)
3738 break;
3839 if (!addr)
....@@ -89,126 +90,49 @@
8990 return 0;
9091 }
9192
92
-static int page_size;
93
-static int page_cnt = 8;
94
-static struct perf_event_mmap_page *header;
95
-
96
-int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header)
93
+/* open kallsyms and read symbol addresses on the fly. Without caching all symbols,
94
+ * this is faster than load + find.
95
+ */
96
+int kallsyms_find(const char *sym, unsigned long long *addr)
9797 {
98
- void *base;
99
- int mmap_size;
98
+ char type, name[500];
99
+ unsigned long long value;
100
+ int err = 0;
101
+ FILE *f;
100102
101
- page_size = getpagesize();
102
- mmap_size = page_size * (page_cnt + 1);
103
+ f = fopen("/proc/kallsyms", "r");
104
+ if (!f)
105
+ return -EINVAL;
103106
104
- base = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
105
- if (base == MAP_FAILED) {
106
- printf("mmap err\n");
107
- return -1;
108
- }
109
-
110
- *header = base;
111
- return 0;
112
-}
113
-
114
-int perf_event_mmap(int fd)
115
-{
116
- return perf_event_mmap_header(fd, &header);
117
-}
118
-
119
-static int perf_event_poll(int fd)
120
-{
121
- struct pollfd pfd = { .fd = fd, .events = POLLIN };
122
-
123
- return poll(&pfd, 1, 1000);
124
-}
125
-
126
-struct perf_event_sample {
127
- struct perf_event_header header;
128
- __u32 size;
129
- char data[];
130
-};
131
-
132
-static enum bpf_perf_event_ret bpf_perf_event_print(void *event, void *priv)
133
-{
134
- struct perf_event_sample *e = event;
135
- perf_event_print_fn fn = priv;
136
- int ret;
137
-
138
- if (e->header.type == PERF_RECORD_SAMPLE) {
139
- ret = fn(e->data, e->size);
140
- if (ret != LIBBPF_PERF_EVENT_CONT)
141
- return ret;
142
- } else if (e->header.type == PERF_RECORD_LOST) {
143
- struct {
144
- struct perf_event_header header;
145
- __u64 id;
146
- __u64 lost;
147
- } *lost = (void *) e;
148
- printf("lost %lld events\n", lost->lost);
149
- } else {
150
- printf("unknown event type=%d size=%d\n",
151
- e->header.type, e->header.size);
152
- }
153
-
154
- return LIBBPF_PERF_EVENT_CONT;
155
-}
156
-
157
-int perf_event_poller(int fd, perf_event_print_fn output_fn)
158
-{
159
- enum bpf_perf_event_ret ret;
160
- void *buf = NULL;
161
- size_t len = 0;
162
-
163
- for (;;) {
164
- perf_event_poll(fd);
165
- ret = bpf_perf_event_read_simple(header, page_cnt * page_size,
166
- page_size, &buf, &len,
167
- bpf_perf_event_print,
168
- output_fn);
169
- if (ret != LIBBPF_PERF_EVENT_CONT)
170
- break;
171
- }
172
- free(buf);
173
-
174
- return ret;
175
-}
176
-
177
-int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers,
178
- int num_fds, perf_event_print_fn output_fn)
179
-{
180
- enum bpf_perf_event_ret ret;
181
- struct pollfd *pfds;
182
- void *buf = NULL;
183
- size_t len = 0;
184
- int i;
185
-
186
- pfds = calloc(num_fds, sizeof(*pfds));
187
- if (!pfds)
188
- return LIBBPF_PERF_EVENT_ERROR;
189
-
190
- for (i = 0; i < num_fds; i++) {
191
- pfds[i].fd = fds[i];
192
- pfds[i].events = POLLIN;
193
- }
194
-
195
- for (;;) {
196
- poll(pfds, num_fds, 1000);
197
- for (i = 0; i < num_fds; i++) {
198
- if (!pfds[i].revents)
199
- continue;
200
-
201
- ret = bpf_perf_event_read_simple(headers[i],
202
- page_cnt * page_size,
203
- page_size, &buf, &len,
204
- bpf_perf_event_print,
205
- output_fn);
206
- if (ret != LIBBPF_PERF_EVENT_CONT)
207
- break;
107
+ while (fscanf(f, "%llx %c %499s%*[^\n]\n", &value, &type, name) > 0) {
108
+ if (strcmp(name, sym) == 0) {
109
+ *addr = value;
110
+ goto out;
208111 }
209112 }
210
- free(buf);
211
- free(pfds);
113
+ err = -ENOENT;
212114
213
- return ret;
115
+out:
116
+ fclose(f);
117
+ return err;
118
+}
119
+
120
+void read_trace_pipe(void)
121
+{
122
+ int trace_fd;
123
+
124
+ trace_fd = open(DEBUGFS "trace_pipe", O_RDONLY, 0);
125
+ if (trace_fd < 0)
126
+ return;
127
+
128
+ while (1) {
129
+ static char buf[4096];
130
+ ssize_t sz;
131
+
132
+ sz = read(trace_fd, buf, sizeof(buf) - 1);
133
+ if (sz > 0) {
134
+ buf[sz] = 0;
135
+ puts(buf);
136
+ }
137
+ }
214138 }