bench_bpf_crypto.c 4.1 KB

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