1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 4 #include <argp.h> 5 #include "bench.h" 6 #include "crypto_bench.skel.h" 7 8 #define MAX_CIPHER_LEN 32 9 static char *input; 10 static struct crypto_ctx { 11 struct crypto_bench *skel; 12 int pfd; 13 } ctx; 14 15 static struct crypto_args { 16 u32 crypto_len; 17 char *crypto_cipher; 18 } args = { 19 .crypto_len = 16, 20 .crypto_cipher = "ecb(aes)", 21 }; 22 23 enum { 24 ARG_CRYPTO_LEN = 5000, 25 ARG_CRYPTO_CIPHER = 5001, 26 }; 27 28 static const struct argp_option opts[] = { 29 { "crypto-len", ARG_CRYPTO_LEN, "CRYPTO_LEN", 0, 30 "Set the length of crypto buffer" }, 31 { "crypto-cipher", ARG_CRYPTO_CIPHER, "CRYPTO_CIPHER", 0, 32 "Set the cipher to use (default:ecb(aes))" }, 33 {}, 34 }; 35 36 static error_t crypto_parse_arg(int key, char *arg, struct argp_state *state) 37 { 38 switch (key) { 39 case ARG_CRYPTO_LEN: 40 args.crypto_len = strtoul(arg, NULL, 10); 41 if (!args.crypto_len || 42 args.crypto_len > sizeof(ctx.skel->bss->dst)) { 43 fprintf(stderr, "Invalid crypto buffer len (limit %zu)\n", 44 sizeof(ctx.skel->bss->dst)); 45 argp_usage(state); 46 } 47 break; 48 case ARG_CRYPTO_CIPHER: 49 args.crypto_cipher = strdup(arg); 50 if (!strlen(args.crypto_cipher) || 51 strlen(args.crypto_cipher) > MAX_CIPHER_LEN) { 52 fprintf(stderr, "Invalid crypto cipher len (limit %d)\n", 53 MAX_CIPHER_LEN); 54 argp_usage(state); 55 } 56 break; 57 default: 58 return ARGP_ERR_UNKNOWN; 59 } 60 61 return 0; 62 } 63 64 const struct argp bench_crypto_argp = { 65 .options = opts, 66 .parser = crypto_parse_arg, 67 }; 68 69 static void crypto_validate(void) 70 { 71 if (env.consumer_cnt != 0) { 72 fprintf(stderr, "bpf crypto benchmark doesn't support consumer!\n"); 73 exit(1); 74 } 75 } 76 77 static void crypto_setup(void) 78 { 79 LIBBPF_OPTS(bpf_test_run_opts, opts); 80 81 int err, pfd; 82 size_t i, sz; 83 84 sz = args.crypto_len; 85 if (!sz || sz > sizeof(ctx.skel->bss->dst)) { 86 fprintf(stderr, "invalid encrypt buffer size (source %zu, target %zu)\n", 87 sz, sizeof(ctx.skel->bss->dst)); 88 exit(1); 89 } 90 91 setup_libbpf(); 92 93 ctx.skel = crypto_bench__open(); 94 if (!ctx.skel) { 95 fprintf(stderr, "failed to open skeleton\n"); 96 exit(1); 97 } 98 99 snprintf(ctx.skel->bss->cipher, 128, "%s", args.crypto_cipher); 100 memcpy(ctx.skel->bss->key, "12345678testtest", 16); 101 ctx.skel->bss->key_len = 16; 102 ctx.skel->bss->authsize = 0; 103 104 srandom(time(NULL)); 105 input = malloc(sz); 106 for (i = 0; i < sz - 1; i++) 107 input[i] = '1' + random() % 9; 108 input[sz - 1] = '\0'; 109 110 ctx.skel->rodata->len = args.crypto_len; 111 112 err = crypto_bench__load(ctx.skel); 113 if (err) { 114 fprintf(stderr, "failed to load skeleton\n"); 115 crypto_bench__destroy(ctx.skel); 116 exit(1); 117 } 118 119 pfd = bpf_program__fd(ctx.skel->progs.crypto_setup); 120 if (pfd < 0) { 121 fprintf(stderr, "failed to get fd for setup prog\n"); 122 crypto_bench__destroy(ctx.skel); 123 exit(1); 124 } 125 126 err = bpf_prog_test_run_opts(pfd, &opts); 127 if (err || ctx.skel->bss->status) { 128 fprintf(stderr, "failed to run setup prog: err %d, status %d\n", 129 err, ctx.skel->bss->status); 130 crypto_bench__destroy(ctx.skel); 131 exit(1); 132 } 133 } 134 135 static void crypto_encrypt_setup(void) 136 { 137 crypto_setup(); 138 ctx.pfd = bpf_program__fd(ctx.skel->progs.crypto_encrypt); 139 } 140 141 static void crypto_decrypt_setup(void) 142 { 143 crypto_setup(); 144 ctx.pfd = bpf_program__fd(ctx.skel->progs.crypto_decrypt); 145 } 146 147 static void crypto_measure(struct bench_res *res) 148 { 149 res->hits = atomic_swap(&ctx.skel->bss->hits, 0); 150 } 151 152 static void *crypto_producer(void *unused) 153 { 154 LIBBPF_OPTS(bpf_test_run_opts, opts, 155 .repeat = 64, 156 .data_in = input, 157 .data_size_in = args.crypto_len, 158 ); 159 160 while (true) 161 (void)bpf_prog_test_run_opts(ctx.pfd, &opts); 162 return NULL; 163 } 164 165 const struct bench bench_crypto_encrypt = { 166 .name = "crypto-encrypt", 167 .argp = &bench_crypto_argp, 168 .validate = crypto_validate, 169 .setup = crypto_encrypt_setup, 170 .producer_thread = crypto_producer, 171 .measure = crypto_measure, 172 .report_progress = hits_drops_report_progress, 173 .report_final = hits_drops_report_final, 174 }; 175 176 const struct bench bench_crypto_decrypt = { 177 .name = "crypto-decrypt", 178 .argp = &bench_crypto_argp, 179 .validate = crypto_validate, 180 .setup = crypto_decrypt_setup, 181 .producer_thread = crypto_producer, 182 .measure = crypto_measure, 183 .report_progress = hits_drops_report_progress, 184 .report_final = hits_drops_report_final, 185 }; 186