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