brintos

brintos / linux-shallow public Read only

0
0
Text · 3.9 KiB · c7828b1 Raw
133 lines · c
1// SPDX-License-Identifier: GPL-2.02 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_READ12#define MADV_POPULATE_READ 2213#endif14 15int __attribute__((weak)) uprobe(void)16{17	return 0;18}19 20#define __PASTE(a, b) a##b21#define PASTE(a, b) __PASTE(a, b)22 23#define NAME(name, idx) PASTE(name, idx)24 25#define DEF(name, idx) int __attribute__((weak)) NAME(name, idx)(void) { return 0; }26#define CALL(name, idx) NAME(name, idx)();27 28#define F(body, name, idx) body(name, idx)29 30#define F10(body, name, idx) \31	F(body, PASTE(name, idx), 0) F(body, PASTE(name, idx), 1) F(body, PASTE(name, idx), 2) \32	F(body, PASTE(name, idx), 3) F(body, PASTE(name, idx), 4) F(body, PASTE(name, idx), 5) \33	F(body, PASTE(name, idx), 6) F(body, PASTE(name, idx), 7) F(body, PASTE(name, idx), 8) \34	F(body, PASTE(name, idx), 9)35 36#define F100(body, name, idx) \37	F10(body, PASTE(name, idx), 0) F10(body, PASTE(name, idx), 1) F10(body, PASTE(name, idx), 2) \38	F10(body, PASTE(name, idx), 3) F10(body, PASTE(name, idx), 4) F10(body, PASTE(name, idx), 5) \39	F10(body, PASTE(name, idx), 6) F10(body, PASTE(name, idx), 7) F10(body, PASTE(name, idx), 8) \40	F10(body, PASTE(name, idx), 9)41 42#define F1000(body, name, idx) \43	F100(body, PASTE(name, idx), 0) F100(body, PASTE(name, idx), 1) F100(body, PASTE(name, idx), 2) \44	F100(body, PASTE(name, idx), 3) F100(body, PASTE(name, idx), 4) F100(body, PASTE(name, idx), 5) \45	F100(body, PASTE(name, idx), 6) F100(body, PASTE(name, idx), 7) F100(body, PASTE(name, idx), 8) \46	F100(body, PASTE(name, idx), 9)47 48#define F10000(body, name, idx) \49	F1000(body, PASTE(name, idx), 0) F1000(body, PASTE(name, idx), 1) F1000(body, PASTE(name, idx), 2) \50	F1000(body, PASTE(name, idx), 3) F1000(body, PASTE(name, idx), 4) F1000(body, PASTE(name, idx), 5) \51	F1000(body, PASTE(name, idx), 6) F1000(body, PASTE(name, idx), 7) F1000(body, PASTE(name, idx), 8) \52	F1000(body, PASTE(name, idx), 9)53 54F10000(DEF, uprobe_multi_func_, 0)55F10000(DEF, uprobe_multi_func_, 1)56F10000(DEF, uprobe_multi_func_, 2)57F10000(DEF, uprobe_multi_func_, 3)58F10000(DEF, uprobe_multi_func_, 4)59 60static int bench(void)61{62	F10000(CALL, uprobe_multi_func_, 0)63	F10000(CALL, uprobe_multi_func_, 1)64	F10000(CALL, uprobe_multi_func_, 2)65	F10000(CALL, uprobe_multi_func_, 3)66	F10000(CALL, uprobe_multi_func_, 4)67	return 0;68}69 70#define PROBE STAP_PROBE(test, usdt);71 72#define PROBE10    PROBE PROBE PROBE PROBE PROBE \73		   PROBE PROBE PROBE PROBE PROBE74#define PROBE100   PROBE10 PROBE10 PROBE10 PROBE10 PROBE10 \75		   PROBE10 PROBE10 PROBE10 PROBE10 PROBE1076#define PROBE1000  PROBE100 PROBE100 PROBE100 PROBE100 PROBE100 \77		   PROBE100 PROBE100 PROBE100 PROBE100 PROBE10078#define PROBE10000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 \79		   PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE100080 81static int usdt(void)82{83	PROBE1000084	PROBE1000085	PROBE1000086	PROBE1000087	PROBE1000088	return 0;89}90 91extern char build_id_start[];92extern char build_id_end[];93 94int __attribute__((weak)) trigger_uprobe(bool build_id_resident)95{96	int page_sz = sysconf(_SC_PAGESIZE);97	void *addr;98 99	/* page-align build ID start */100	addr = (void *)((uintptr_t)&build_id_start & ~(page_sz - 1));101 102	/* to guarantee MADV_PAGEOUT work reliably, we need to ensure that103	 * memory range is mapped into current process, so we unconditionally104	 * do MADV_POPULATE_READ, and then MADV_PAGEOUT, if necessary105	 */106	madvise(addr, page_sz, MADV_POPULATE_READ);107	if (!build_id_resident)108		madvise(addr, page_sz, MADV_PAGEOUT);109 110	(void)uprobe();111 112	return 0;113}114 115int main(int argc, char **argv)116{117	if (argc != 2)118		goto error;119 120	if (!strcmp("bench", argv[1]))121		return bench();122	if (!strcmp("usdt", argv[1]))123		return usdt();124	if (!strcmp("uprobe-paged-out", argv[1]))125		return trigger_uprobe(false /* page-out build ID */);126	if (!strcmp("uprobe-paged-in", argv[1]))127		return trigger_uprobe(true /* page-in build ID */);128 129error:130	fprintf(stderr, "usage: %s <bench|usdt>\n", argv[0]);131	return -1;132}133