1 // SPDX-License-Identifier: GPL-2.0
11 #ifndef MADV_POPULATE_READ
12 #define MADV_POPULATE_READ 22
16 #define MADV_PAGEOUT 21
19 int __attribute__((weak
)) uprobe(void)
24 #define __PASTE(a, b) a##b
25 #define PASTE(a, b) __PASTE(a, b)
27 #define NAME(name, idx) PASTE(name, idx)
29 #define DEF(name, idx) int __attribute__((weak)) NAME(name, idx)(void) { return 0; }
30 #define CALL(name, idx) NAME(name, idx)();
32 #define F(body, name, idx) body(name, idx)
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)
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)
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)
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)
58 F10000(DEF
, uprobe_multi_func_
, 0)
59 F10000(DEF
, uprobe_multi_func_
, 1)
60 F10000(DEF
, uprobe_multi_func_
, 2)
61 F10000(DEF
, uprobe_multi_func_
, 3)
62 F10000(DEF
, uprobe_multi_func_
, 4)
64 static int bench(void)
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)
74 #define PROBE STAP_PROBE(test, usdt);
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
95 extern char build_id_start
[];
96 extern char build_id_end
[];
98 int __attribute__((weak
)) trigger_uprobe(bool build_id_resident
)
100 int page_sz
= sysconf(_SC_PAGESIZE
);
103 /* page-align build ID start */
104 addr
= (void *)((uintptr_t)&build_id_start
& ~(page_sz
- 1));
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
110 madvise(addr
, page_sz
, MADV_POPULATE_READ
);
111 if (!build_id_resident
)
112 madvise(addr
, page_sz
, MADV_PAGEOUT
);
119 int main(int argc
, char **argv
)
124 if (!strcmp("bench", argv
[1]))
126 if (!strcmp("usdt", argv
[1]))
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 */);
134 fprintf(stderr
, "usage: %s <bench|usdt>\n", argv
[0]);