0001
0002
0003 #include "bench.h"
0004 #include "trigger_bench.skel.h"
0005 #include "trace_helpers.h"
0006
0007
0008 static struct trigger_ctx {
0009 struct trigger_bench *skel;
0010 } ctx;
0011
0012 static struct counter base_hits;
0013
0014 static void trigger_validate(void)
0015 {
0016 if (env.consumer_cnt != 1) {
0017 fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
0018 exit(1);
0019 }
0020 }
0021
0022 static void *trigger_base_producer(void *input)
0023 {
0024 while (true) {
0025 (void)syscall(__NR_getpgid);
0026 atomic_inc(&base_hits.value);
0027 }
0028 return NULL;
0029 }
0030
0031 static void trigger_base_measure(struct bench_res *res)
0032 {
0033 res->hits = atomic_swap(&base_hits.value, 0);
0034 }
0035
0036 static void *trigger_producer(void *input)
0037 {
0038 while (true)
0039 (void)syscall(__NR_getpgid);
0040 return NULL;
0041 }
0042
0043 static void trigger_measure(struct bench_res *res)
0044 {
0045 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
0046 }
0047
0048 static void setup_ctx(void)
0049 {
0050 setup_libbpf();
0051
0052 ctx.skel = trigger_bench__open_and_load();
0053 if (!ctx.skel) {
0054 fprintf(stderr, "failed to open skeleton\n");
0055 exit(1);
0056 }
0057 }
0058
0059 static void attach_bpf(struct bpf_program *prog)
0060 {
0061 struct bpf_link *link;
0062
0063 link = bpf_program__attach(prog);
0064 if (!link) {
0065 fprintf(stderr, "failed to attach program!\n");
0066 exit(1);
0067 }
0068 }
0069
0070 static void trigger_tp_setup(void)
0071 {
0072 setup_ctx();
0073 attach_bpf(ctx.skel->progs.bench_trigger_tp);
0074 }
0075
0076 static void trigger_rawtp_setup(void)
0077 {
0078 setup_ctx();
0079 attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);
0080 }
0081
0082 static void trigger_kprobe_setup(void)
0083 {
0084 setup_ctx();
0085 attach_bpf(ctx.skel->progs.bench_trigger_kprobe);
0086 }
0087
0088 static void trigger_fentry_setup(void)
0089 {
0090 setup_ctx();
0091 attach_bpf(ctx.skel->progs.bench_trigger_fentry);
0092 }
0093
0094 static void trigger_fentry_sleep_setup(void)
0095 {
0096 setup_ctx();
0097 attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);
0098 }
0099
0100 static void trigger_fmodret_setup(void)
0101 {
0102 setup_ctx();
0103 attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
0104 }
0105
0106 static void *trigger_consumer(void *input)
0107 {
0108 return NULL;
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 __weak void uprobe_target_with_nop(void)
0122 {
0123 asm volatile ("nop");
0124 }
0125
0126 __weak void uprobe_target_without_nop(void)
0127 {
0128 asm volatile ("");
0129 }
0130
0131 static void *uprobe_base_producer(void *input)
0132 {
0133 while (true) {
0134 uprobe_target_with_nop();
0135 atomic_inc(&base_hits.value);
0136 }
0137 return NULL;
0138 }
0139
0140 static void *uprobe_producer_with_nop(void *input)
0141 {
0142 while (true)
0143 uprobe_target_with_nop();
0144 return NULL;
0145 }
0146
0147 static void *uprobe_producer_without_nop(void *input)
0148 {
0149 while (true)
0150 uprobe_target_without_nop();
0151 return NULL;
0152 }
0153
0154 static void usetup(bool use_retprobe, bool use_nop)
0155 {
0156 size_t uprobe_offset;
0157 struct bpf_link *link;
0158
0159 setup_libbpf();
0160
0161 ctx.skel = trigger_bench__open_and_load();
0162 if (!ctx.skel) {
0163 fprintf(stderr, "failed to open skeleton\n");
0164 exit(1);
0165 }
0166
0167 if (use_nop)
0168 uprobe_offset = get_uprobe_offset(&uprobe_target_with_nop);
0169 else
0170 uprobe_offset = get_uprobe_offset(&uprobe_target_without_nop);
0171
0172 link = bpf_program__attach_uprobe(ctx.skel->progs.bench_trigger_uprobe,
0173 use_retprobe,
0174 -1 ,
0175 "/proc/self/exe",
0176 uprobe_offset);
0177 if (!link) {
0178 fprintf(stderr, "failed to attach uprobe!\n");
0179 exit(1);
0180 }
0181 ctx.skel->links.bench_trigger_uprobe = link;
0182 }
0183
0184 static void uprobe_setup_with_nop(void)
0185 {
0186 usetup(false, true);
0187 }
0188
0189 static void uretprobe_setup_with_nop(void)
0190 {
0191 usetup(true, true);
0192 }
0193
0194 static void uprobe_setup_without_nop(void)
0195 {
0196 usetup(false, false);
0197 }
0198
0199 static void uretprobe_setup_without_nop(void)
0200 {
0201 usetup(true, false);
0202 }
0203
0204 const struct bench bench_trig_base = {
0205 .name = "trig-base",
0206 .validate = trigger_validate,
0207 .producer_thread = trigger_base_producer,
0208 .consumer_thread = trigger_consumer,
0209 .measure = trigger_base_measure,
0210 .report_progress = hits_drops_report_progress,
0211 .report_final = hits_drops_report_final,
0212 };
0213
0214 const struct bench bench_trig_tp = {
0215 .name = "trig-tp",
0216 .validate = trigger_validate,
0217 .setup = trigger_tp_setup,
0218 .producer_thread = trigger_producer,
0219 .consumer_thread = trigger_consumer,
0220 .measure = trigger_measure,
0221 .report_progress = hits_drops_report_progress,
0222 .report_final = hits_drops_report_final,
0223 };
0224
0225 const struct bench bench_trig_rawtp = {
0226 .name = "trig-rawtp",
0227 .validate = trigger_validate,
0228 .setup = trigger_rawtp_setup,
0229 .producer_thread = trigger_producer,
0230 .consumer_thread = trigger_consumer,
0231 .measure = trigger_measure,
0232 .report_progress = hits_drops_report_progress,
0233 .report_final = hits_drops_report_final,
0234 };
0235
0236 const struct bench bench_trig_kprobe = {
0237 .name = "trig-kprobe",
0238 .validate = trigger_validate,
0239 .setup = trigger_kprobe_setup,
0240 .producer_thread = trigger_producer,
0241 .consumer_thread = trigger_consumer,
0242 .measure = trigger_measure,
0243 .report_progress = hits_drops_report_progress,
0244 .report_final = hits_drops_report_final,
0245 };
0246
0247 const struct bench bench_trig_fentry = {
0248 .name = "trig-fentry",
0249 .validate = trigger_validate,
0250 .setup = trigger_fentry_setup,
0251 .producer_thread = trigger_producer,
0252 .consumer_thread = trigger_consumer,
0253 .measure = trigger_measure,
0254 .report_progress = hits_drops_report_progress,
0255 .report_final = hits_drops_report_final,
0256 };
0257
0258 const struct bench bench_trig_fentry_sleep = {
0259 .name = "trig-fentry-sleep",
0260 .validate = trigger_validate,
0261 .setup = trigger_fentry_sleep_setup,
0262 .producer_thread = trigger_producer,
0263 .consumer_thread = trigger_consumer,
0264 .measure = trigger_measure,
0265 .report_progress = hits_drops_report_progress,
0266 .report_final = hits_drops_report_final,
0267 };
0268
0269 const struct bench bench_trig_fmodret = {
0270 .name = "trig-fmodret",
0271 .validate = trigger_validate,
0272 .setup = trigger_fmodret_setup,
0273 .producer_thread = trigger_producer,
0274 .consumer_thread = trigger_consumer,
0275 .measure = trigger_measure,
0276 .report_progress = hits_drops_report_progress,
0277 .report_final = hits_drops_report_final,
0278 };
0279
0280 const struct bench bench_trig_uprobe_base = {
0281 .name = "trig-uprobe-base",
0282 .setup = NULL,
0283 .producer_thread = uprobe_base_producer,
0284 .consumer_thread = trigger_consumer,
0285 .measure = trigger_base_measure,
0286 .report_progress = hits_drops_report_progress,
0287 .report_final = hits_drops_report_final,
0288 };
0289
0290 const struct bench bench_trig_uprobe_with_nop = {
0291 .name = "trig-uprobe-with-nop",
0292 .setup = uprobe_setup_with_nop,
0293 .producer_thread = uprobe_producer_with_nop,
0294 .consumer_thread = trigger_consumer,
0295 .measure = trigger_measure,
0296 .report_progress = hits_drops_report_progress,
0297 .report_final = hits_drops_report_final,
0298 };
0299
0300 const struct bench bench_trig_uretprobe_with_nop = {
0301 .name = "trig-uretprobe-with-nop",
0302 .setup = uretprobe_setup_with_nop,
0303 .producer_thread = uprobe_producer_with_nop,
0304 .consumer_thread = trigger_consumer,
0305 .measure = trigger_measure,
0306 .report_progress = hits_drops_report_progress,
0307 .report_final = hits_drops_report_final,
0308 };
0309
0310 const struct bench bench_trig_uprobe_without_nop = {
0311 .name = "trig-uprobe-without-nop",
0312 .setup = uprobe_setup_without_nop,
0313 .producer_thread = uprobe_producer_without_nop,
0314 .consumer_thread = trigger_consumer,
0315 .measure = trigger_measure,
0316 .report_progress = hits_drops_report_progress,
0317 .report_final = hits_drops_report_final,
0318 };
0319
0320 const struct bench bench_trig_uretprobe_without_nop = {
0321 .name = "trig-uretprobe-without-nop",
0322 .setup = uretprobe_setup_without_nop,
0323 .producer_thread = uprobe_producer_without_nop,
0324 .consumer_thread = trigger_consumer,
0325 .measure = trigger_measure,
0326 .report_progress = hits_drops_report_progress,
0327 .report_final = hits_drops_report_final,
0328 };