Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ #include <argp.h> #include "bench.h" #include "strncmp_bench.skel.h" static struct strncmp_ctx { struct strncmp_bench *skel; } ctx; static struct strncmp_args { u32 cmp_str_len; } args = { .cmp_str_len = 32, }; enum { ARG_CMP_STR_LEN = 5000, }; static const struct argp_option opts[] = { { "cmp-str-len", ARG_CMP_STR_LEN, "CMP_STR_LEN", 0, "Set the length of compared string" }, {}, }; static error_t strncmp_parse_arg(int key, char *arg, struct argp_state *state) { switch (key) { case ARG_CMP_STR_LEN: args.cmp_str_len = strtoul(arg, NULL, 10); if (!args.cmp_str_len || args.cmp_str_len >= sizeof(ctx.skel->bss->str)) { fprintf(stderr, "Invalid cmp str len (limit %zu)\n", sizeof(ctx.skel->bss->str)); argp_usage(state); } break; default: return ARGP_ERR_UNKNOWN; } return 0; } const struct argp bench_strncmp_argp = { .options = opts, .parser = strncmp_parse_arg, }; static void strncmp_validate(void) { if (env.consumer_cnt != 1) { fprintf(stderr, "strncmp benchmark doesn't support multi-consumer!\n"); exit(1); } } static void strncmp_setup(void) { int err; char *target; size_t i, sz; sz = sizeof(ctx.skel->rodata->target); if (!sz || sz < sizeof(ctx.skel->bss->str)) { fprintf(stderr, "invalid string size (target %zu, src %zu)\n", sz, sizeof(ctx.skel->bss->str)); exit(1); } setup_libbpf(); ctx.skel = strncmp_bench__open(); if (!ctx.skel) { fprintf(stderr, "failed to open skeleton\n"); exit(1); } srandom(time(NULL)); target = ctx.skel->rodata->target; for (i = 0; i < sz - 1; i++) target[i] = '1' + random() % 9; target[sz - 1] = '\0'; ctx.skel->rodata->cmp_str_len = args.cmp_str_len; memcpy(ctx.skel->bss->str, target, args.cmp_str_len); ctx.skel->bss->str[args.cmp_str_len] = '\0'; /* Make bss->str < rodata->target */ ctx.skel->bss->str[args.cmp_str_len - 1] -= 1; err = strncmp_bench__load(ctx.skel); if (err) { fprintf(stderr, "failed to load skeleton\n"); strncmp_bench__destroy(ctx.skel); exit(1); } } static void strncmp_attach_prog(struct bpf_program *prog) { struct bpf_link *link; link = bpf_program__attach(prog); if (!link) { fprintf(stderr, "failed to attach program!\n"); exit(1); } } static void strncmp_no_helper_setup(void) { strncmp_setup(); strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper); } static void strncmp_helper_setup(void) { strncmp_setup(); strncmp_attach_prog(ctx.skel->progs.strncmp_helper); } static void *strncmp_producer(void *ctx) { while (true) (void)syscall(__NR_getpgid); return NULL; } static void *strncmp_consumer(void *ctx) { return NULL; } static void strncmp_measure(struct bench_res *res) { res->hits = atomic_swap(&ctx.skel->bss->hits, 0); } const struct bench bench_strncmp_no_helper = { .name = "strncmp-no-helper", .validate = strncmp_validate, .setup = strncmp_no_helper_setup, .producer_thread = strncmp_producer, .consumer_thread = strncmp_consumer, .measure = strncmp_measure, .report_progress = hits_drops_report_progress, .report_final = hits_drops_report_final, }; const struct bench bench_strncmp_helper = { .name = "strncmp-helper", .validate = strncmp_validate, .setup = strncmp_helper_setup, .producer_thread = strncmp_producer, .consumer_thread = strncmp_consumer, .measure = strncmp_measure, .report_progress = hits_drops_report_progress, .report_final = hits_drops_report_final, }; |