Loading...
1// SPDX-License-Identifier: GPL-2.0
2
3#include <stdio.h>
4#include <string.h>
5#include <stdbool.h>
6#include <stdint.h>
7#include <sys/mman.h>
8#include <unistd.h>
9#include <sdt.h>
10
11#ifndef MADV_POPULATE_READ
12#define MADV_POPULATE_READ 22
13#endif
14
15#ifndef MADV_PAGEOUT
16#define MADV_PAGEOUT 21
17#endif
18
19int __attribute__((weak)) uprobe(void)
20{
21 return 0;
22}
23
24#define __PASTE(a, b) a##b
25#define PASTE(a, b) __PASTE(a, b)
26
27#define NAME(name, idx) PASTE(name, idx)
28
29#define DEF(name, idx) int __attribute__((weak)) NAME(name, idx)(void) { return 0; }
30#define CALL(name, idx) NAME(name, idx)();
31
32#define F(body, name, idx) body(name, idx)
33
34#define F10(body, name, idx) \
35 F(body, PASTE(name, idx), 0) F(body, PASTE(name, idx), 1) F(body, PASTE(name, idx), 2) \
36 F(body, PASTE(name, idx), 3) F(body, PASTE(name, idx), 4) F(body, PASTE(name, idx), 5) \
37 F(body, PASTE(name, idx), 6) F(body, PASTE(name, idx), 7) F(body, PASTE(name, idx), 8) \
38 F(body, PASTE(name, idx), 9)
39
40#define F100(body, name, idx) \
41 F10(body, PASTE(name, idx), 0) F10(body, PASTE(name, idx), 1) F10(body, PASTE(name, idx), 2) \
42 F10(body, PASTE(name, idx), 3) F10(body, PASTE(name, idx), 4) F10(body, PASTE(name, idx), 5) \
43 F10(body, PASTE(name, idx), 6) F10(body, PASTE(name, idx), 7) F10(body, PASTE(name, idx), 8) \
44 F10(body, PASTE(name, idx), 9)
45
46#define F1000(body, name, idx) \
47 F100(body, PASTE(name, idx), 0) F100(body, PASTE(name, idx), 1) F100(body, PASTE(name, idx), 2) \
48 F100(body, PASTE(name, idx), 3) F100(body, PASTE(name, idx), 4) F100(body, PASTE(name, idx), 5) \
49 F100(body, PASTE(name, idx), 6) F100(body, PASTE(name, idx), 7) F100(body, PASTE(name, idx), 8) \
50 F100(body, PASTE(name, idx), 9)
51
52#define F10000(body, name, idx) \
53 F1000(body, PASTE(name, idx), 0) F1000(body, PASTE(name, idx), 1) F1000(body, PASTE(name, idx), 2) \
54 F1000(body, PASTE(name, idx), 3) F1000(body, PASTE(name, idx), 4) F1000(body, PASTE(name, idx), 5) \
55 F1000(body, PASTE(name, idx), 6) F1000(body, PASTE(name, idx), 7) F1000(body, PASTE(name, idx), 8) \
56 F1000(body, PASTE(name, idx), 9)
57
58F10000(DEF, uprobe_multi_func_, 0)
59F10000(DEF, uprobe_multi_func_, 1)
60F10000(DEF, uprobe_multi_func_, 2)
61F10000(DEF, uprobe_multi_func_, 3)
62F10000(DEF, uprobe_multi_func_, 4)
63
64static int bench(void)
65{
66 F10000(CALL, uprobe_multi_func_, 0)
67 F10000(CALL, uprobe_multi_func_, 1)
68 F10000(CALL, uprobe_multi_func_, 2)
69 F10000(CALL, uprobe_multi_func_, 3)
70 F10000(CALL, uprobe_multi_func_, 4)
71 return 0;
72}
73
74#define PROBE STAP_PROBE(test, usdt);
75
76#define PROBE10 PROBE PROBE PROBE PROBE PROBE \
77 PROBE PROBE PROBE PROBE PROBE
78#define PROBE100 PROBE10 PROBE10 PROBE10 PROBE10 PROBE10 \
79 PROBE10 PROBE10 PROBE10 PROBE10 PROBE10
80#define PROBE1000 PROBE100 PROBE100 PROBE100 PROBE100 PROBE100 \
81 PROBE100 PROBE100 PROBE100 PROBE100 PROBE100
82#define PROBE10000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 \
83 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000
84
85static int usdt(void)
86{
87 PROBE10000
88 PROBE10000
89 PROBE10000
90 PROBE10000
91 PROBE10000
92 return 0;
93}
94
95extern char build_id_start[];
96extern char build_id_end[];
97
98int __attribute__((weak)) trigger_uprobe(bool build_id_resident)
99{
100 int page_sz = sysconf(_SC_PAGESIZE);
101 void *addr;
102
103 /* page-align build ID start */
104 addr = (void *)((uintptr_t)&build_id_start & ~(page_sz - 1));
105
106 /* to guarantee MADV_PAGEOUT work reliably, we need to ensure that
107 * memory range is mapped into current process, so we unconditionally
108 * do MADV_POPULATE_READ, and then MADV_PAGEOUT, if necessary
109 */
110 madvise(addr, page_sz, MADV_POPULATE_READ);
111 if (!build_id_resident)
112 madvise(addr, page_sz, MADV_PAGEOUT);
113
114 (void)uprobe();
115
116 return 0;
117}
118
119int main(int argc, char **argv)
120{
121 if (argc != 2)
122 goto error;
123
124 if (!strcmp("bench", argv[1]))
125 return bench();
126 if (!strcmp("usdt", argv[1]))
127 return usdt();
128 if (!strcmp("uprobe-paged-out", argv[1]))
129 return trigger_uprobe(false /* page-out build ID */);
130 if (!strcmp("uprobe-paged-in", argv[1]))
131 return trigger_uprobe(true /* page-in build ID */);
132
133error:
134 fprintf(stderr, "usage: %s <bench|usdt>\n", argv[0]);
135 return -1;
136}
1// SPDX-License-Identifier: GPL-2.0
2
3#include <stdio.h>
4#include <string.h>
5#include <sdt.h>
6
7#define __PASTE(a, b) a##b
8#define PASTE(a, b) __PASTE(a, b)
9
10#define NAME(name, idx) PASTE(name, idx)
11
12#define DEF(name, idx) int NAME(name, idx)(void) { return 0; }
13#define CALL(name, idx) NAME(name, idx)();
14
15#define F(body, name, idx) body(name, idx)
16
17#define F10(body, name, idx) \
18 F(body, PASTE(name, idx), 0) F(body, PASTE(name, idx), 1) F(body, PASTE(name, idx), 2) \
19 F(body, PASTE(name, idx), 3) F(body, PASTE(name, idx), 4) F(body, PASTE(name, idx), 5) \
20 F(body, PASTE(name, idx), 6) F(body, PASTE(name, idx), 7) F(body, PASTE(name, idx), 8) \
21 F(body, PASTE(name, idx), 9)
22
23#define F100(body, name, idx) \
24 F10(body, PASTE(name, idx), 0) F10(body, PASTE(name, idx), 1) F10(body, PASTE(name, idx), 2) \
25 F10(body, PASTE(name, idx), 3) F10(body, PASTE(name, idx), 4) F10(body, PASTE(name, idx), 5) \
26 F10(body, PASTE(name, idx), 6) F10(body, PASTE(name, idx), 7) F10(body, PASTE(name, idx), 8) \
27 F10(body, PASTE(name, idx), 9)
28
29#define F1000(body, name, idx) \
30 F100(body, PASTE(name, idx), 0) F100(body, PASTE(name, idx), 1) F100(body, PASTE(name, idx), 2) \
31 F100(body, PASTE(name, idx), 3) F100(body, PASTE(name, idx), 4) F100(body, PASTE(name, idx), 5) \
32 F100(body, PASTE(name, idx), 6) F100(body, PASTE(name, idx), 7) F100(body, PASTE(name, idx), 8) \
33 F100(body, PASTE(name, idx), 9)
34
35#define F10000(body, name, idx) \
36 F1000(body, PASTE(name, idx), 0) F1000(body, PASTE(name, idx), 1) F1000(body, PASTE(name, idx), 2) \
37 F1000(body, PASTE(name, idx), 3) F1000(body, PASTE(name, idx), 4) F1000(body, PASTE(name, idx), 5) \
38 F1000(body, PASTE(name, idx), 6) F1000(body, PASTE(name, idx), 7) F1000(body, PASTE(name, idx), 8) \
39 F1000(body, PASTE(name, idx), 9)
40
41F10000(DEF, uprobe_multi_func_, 0)
42F10000(DEF, uprobe_multi_func_, 1)
43F10000(DEF, uprobe_multi_func_, 2)
44F10000(DEF, uprobe_multi_func_, 3)
45F10000(DEF, uprobe_multi_func_, 4)
46
47static int bench(void)
48{
49 F10000(CALL, uprobe_multi_func_, 0)
50 F10000(CALL, uprobe_multi_func_, 1)
51 F10000(CALL, uprobe_multi_func_, 2)
52 F10000(CALL, uprobe_multi_func_, 3)
53 F10000(CALL, uprobe_multi_func_, 4)
54 return 0;
55}
56
57#define PROBE STAP_PROBE(test, usdt);
58
59#define PROBE10 PROBE PROBE PROBE PROBE PROBE \
60 PROBE PROBE PROBE PROBE PROBE
61#define PROBE100 PROBE10 PROBE10 PROBE10 PROBE10 PROBE10 \
62 PROBE10 PROBE10 PROBE10 PROBE10 PROBE10
63#define PROBE1000 PROBE100 PROBE100 PROBE100 PROBE100 PROBE100 \
64 PROBE100 PROBE100 PROBE100 PROBE100 PROBE100
65#define PROBE10000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 \
66 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000
67
68static int usdt(void)
69{
70 PROBE10000
71 PROBE10000
72 PROBE10000
73 PROBE10000
74 PROBE10000
75 return 0;
76}
77
78int main(int argc, char **argv)
79{
80 if (argc != 2)
81 goto error;
82
83 if (!strcmp("bench", argv[1]))
84 return bench();
85 if (!strcmp("usdt", argv[1]))
86 return usdt();
87
88error:
89 fprintf(stderr, "usage: %s <bench|usdt>\n", argv[0]);
90 return -1;
91}