linux/tools/testing/selftests/bpf/map_tests/sk_storage_map.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2019 Facebook  */
   3#include <linux/compiler.h>
   4#include <linux/err.h>
   5
   6#include <sys/resource.h>
   7#include <sys/socket.h>
   8#include <sys/types.h>
   9#include <linux/btf.h>
  10#include <unistd.h>
  11#include <signal.h>
  12#include <errno.h>
  13#include <string.h>
  14#include <pthread.h>
  15
  16#include <bpf/bpf.h>
  17#include <bpf/libbpf.h>
  18
  19#include <test_btf.h>
  20#include <test_maps.h>
  21
  22static struct bpf_create_map_attr xattr = {
  23        .name = "sk_storage_map",
  24        .map_type = BPF_MAP_TYPE_SK_STORAGE,
  25        .map_flags = BPF_F_NO_PREALLOC,
  26        .max_entries = 0,
  27        .key_size = 4,
  28        .value_size = 8,
  29        .btf_key_type_id = 1,
  30        .btf_value_type_id = 3,
  31        .btf_fd = -1,
  32};
  33
  34static unsigned int nr_sk_threads_done;
  35static unsigned int nr_sk_threads_err;
  36static unsigned int nr_sk_per_thread = 4096;
  37static unsigned int nr_sk_threads = 4;
  38static int sk_storage_map = -1;
  39static unsigned int stop;
  40static int runtime_s = 5;
  41
  42static bool is_stopped(void)
  43{
  44        return READ_ONCE(stop);
  45}
  46
  47static unsigned int threads_err(void)
  48{
  49        return READ_ONCE(nr_sk_threads_err);
  50}
  51
  52static void notify_thread_err(void)
  53{
  54        __sync_add_and_fetch(&nr_sk_threads_err, 1);
  55}
  56
  57static bool wait_for_threads_err(void)
  58{
  59        while (!is_stopped() && !threads_err())
  60                usleep(500);
  61
  62        return !is_stopped();
  63}
  64
  65static unsigned int threads_done(void)
  66{
  67        return READ_ONCE(nr_sk_threads_done);
  68}
  69
  70static void notify_thread_done(void)
  71{
  72        __sync_add_and_fetch(&nr_sk_threads_done, 1);
  73}
  74
  75static void notify_thread_redo(void)
  76{
  77        __sync_sub_and_fetch(&nr_sk_threads_done, 1);
  78}
  79
  80static bool wait_for_threads_done(void)
  81{
  82        while (threads_done() != nr_sk_threads && !is_stopped() &&
  83               !threads_err())
  84                usleep(50);
  85
  86        return !is_stopped() && !threads_err();
  87}
  88
  89static bool wait_for_threads_redo(void)
  90{
  91        while (threads_done() && !is_stopped() && !threads_err())
  92                usleep(50);
  93
  94        return !is_stopped() && !threads_err();
  95}
  96
  97static bool wait_for_map(void)
  98{
  99        while (READ_ONCE(sk_storage_map) == -1 && !is_stopped())
 100                usleep(50);
 101
 102        return !is_stopped();
 103}
 104
 105static bool wait_for_map_close(void)
 106{
 107        while (READ_ONCE(sk_storage_map) != -1 && !is_stopped())
 108                ;
 109
 110        return !is_stopped();
 111}
 112
 113static int load_btf(void)
 114{
 115        const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l";
 116        __u32 btf_raw_types[] = {
 117                /* int */
 118                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
 119                /* struct bpf_spin_lock */                      /* [2] */
 120                BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),
 121                BTF_MEMBER_ENC(15, 1, 0), /* int val; */
 122                /* struct val */                                /* [3] */
 123                BTF_TYPE_ENC(15, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
 124                BTF_MEMBER_ENC(19, 1, 0), /* int cnt; */
 125                BTF_MEMBER_ENC(23, 2, 32),/* struct bpf_spin_lock l; */
 126        };
 127        struct btf_header btf_hdr = {
 128                .magic = BTF_MAGIC,
 129                .version = BTF_VERSION,
 130                .hdr_len = sizeof(struct btf_header),
 131                .type_len = sizeof(btf_raw_types),
 132                .str_off = sizeof(btf_raw_types),
 133                .str_len = sizeof(btf_str_sec),
 134        };
 135        __u8 raw_btf[sizeof(struct btf_header) + sizeof(btf_raw_types) +
 136                     sizeof(btf_str_sec)];
 137
 138        memcpy(raw_btf, &btf_hdr, sizeof(btf_hdr));
 139        memcpy(raw_btf + sizeof(btf_hdr), btf_raw_types, sizeof(btf_raw_types));
 140        memcpy(raw_btf + sizeof(btf_hdr) + sizeof(btf_raw_types),
 141               btf_str_sec, sizeof(btf_str_sec));
 142
 143        return bpf_load_btf(raw_btf, sizeof(raw_btf), 0, 0, 0);
 144}
 145
 146static int create_sk_storage_map(void)
 147{
 148        int btf_fd, map_fd;
 149
 150        btf_fd = load_btf();
 151        CHECK(btf_fd == -1, "bpf_load_btf", "btf_fd:%d errno:%d\n",
 152              btf_fd, errno);
 153        xattr.btf_fd = btf_fd;
 154
 155        map_fd = bpf_create_map_xattr(&xattr);
 156        xattr.btf_fd = -1;
 157        close(btf_fd);
 158        CHECK(map_fd == -1,
 159              "bpf_create_map_xattr()", "errno:%d\n", errno);
 160
 161        return map_fd;
 162}
 163
 164static void *insert_close_thread(void *arg)
 165{
 166        struct {
 167                int cnt;
 168                int lock;
 169        } value = { .cnt = 0xeB9F, .lock = 0, };
 170        int i, map_fd, err, *sk_fds;
 171
 172        sk_fds = malloc(sizeof(*sk_fds) * nr_sk_per_thread);
 173        if (!sk_fds) {
 174                notify_thread_err();
 175                return ERR_PTR(-ENOMEM);
 176        }
 177
 178        for (i = 0; i < nr_sk_per_thread; i++)
 179                sk_fds[i] = -1;
 180
 181        while (!is_stopped()) {
 182                if (!wait_for_map())
 183                        goto close_all;
 184
 185                map_fd = READ_ONCE(sk_storage_map);
 186                for (i = 0; i < nr_sk_per_thread && !is_stopped(); i++) {
 187                        sk_fds[i] = socket(AF_INET6, SOCK_STREAM, 0);
 188                        if (sk_fds[i] == -1) {
 189                                err = -errno;
 190                                fprintf(stderr, "socket(): errno:%d\n", errno);
 191                                goto errout;
 192                        }
 193                        err = bpf_map_update_elem(map_fd, &sk_fds[i], &value,
 194                                                  BPF_NOEXIST);
 195                        if (err) {
 196                                err = -errno;
 197                                fprintf(stderr,
 198                                        "bpf_map_update_elem(): errno:%d\n",
 199                                        errno);
 200                                goto errout;
 201                        }
 202                }
 203
 204                notify_thread_done();
 205                wait_for_map_close();
 206
 207close_all:
 208                for (i = 0; i < nr_sk_per_thread; i++) {
 209                        close(sk_fds[i]);
 210                        sk_fds[i] = -1;
 211                }
 212
 213                notify_thread_redo();
 214        }
 215
 216        free(sk_fds);
 217        return NULL;
 218
 219errout:
 220        for (i = 0; i < nr_sk_per_thread && sk_fds[i] != -1; i++)
 221                close(sk_fds[i]);
 222        free(sk_fds);
 223        notify_thread_err();
 224        return ERR_PTR(err);
 225}
 226
 227static int do_sk_storage_map_stress_free(void)
 228{
 229        int i, map_fd = -1, err = 0, nr_threads_created = 0;
 230        pthread_t *sk_thread_ids;
 231        void *thread_ret;
 232
 233        sk_thread_ids = malloc(sizeof(pthread_t) * nr_sk_threads);
 234        if (!sk_thread_ids) {
 235                fprintf(stderr, "malloc(sk_threads): NULL\n");
 236                return -ENOMEM;
 237        }
 238
 239        for (i = 0; i < nr_sk_threads; i++) {
 240                err = pthread_create(&sk_thread_ids[i], NULL,
 241                                     insert_close_thread, NULL);
 242                if (err) {
 243                        err = -errno;
 244                        goto done;
 245                }
 246                nr_threads_created++;
 247        }
 248
 249        while (!is_stopped()) {
 250                map_fd = create_sk_storage_map();
 251                WRITE_ONCE(sk_storage_map, map_fd);
 252
 253                if (!wait_for_threads_done())
 254                        break;
 255
 256                WRITE_ONCE(sk_storage_map, -1);
 257                close(map_fd);
 258                map_fd = -1;
 259
 260                if (!wait_for_threads_redo())
 261                        break;
 262        }
 263
 264done:
 265        WRITE_ONCE(stop, 1);
 266        for (i = 0; i < nr_threads_created; i++) {
 267                pthread_join(sk_thread_ids[i], &thread_ret);
 268                if (IS_ERR(thread_ret) && !err) {
 269                        err = PTR_ERR(thread_ret);
 270                        fprintf(stderr, "threads#%u: err:%d\n", i, err);
 271                }
 272        }
 273        free(sk_thread_ids);
 274
 275        if (map_fd != -1)
 276                close(map_fd);
 277
 278        return err;
 279}
 280
 281static void *update_thread(void *arg)
 282{
 283        struct {
 284                int cnt;
 285                int lock;
 286        } value = { .cnt = 0xeB9F, .lock = 0, };
 287        int map_fd = READ_ONCE(sk_storage_map);
 288        int sk_fd = *(int *)arg;
 289        int err = 0; /* Suppress compiler false alarm */
 290
 291        while (!is_stopped()) {
 292                err = bpf_map_update_elem(map_fd, &sk_fd, &value, 0);
 293                if (err && errno != EAGAIN) {
 294                        err = -errno;
 295                        fprintf(stderr, "bpf_map_update_elem: %d %d\n",
 296                                err, errno);
 297                        break;
 298                }
 299        }
 300
 301        if (!is_stopped()) {
 302                notify_thread_err();
 303                return ERR_PTR(err);
 304        }
 305
 306        return NULL;
 307}
 308
 309static void *delete_thread(void *arg)
 310{
 311        int map_fd = READ_ONCE(sk_storage_map);
 312        int sk_fd = *(int *)arg;
 313        int err = 0; /* Suppress compiler false alarm */
 314
 315        while (!is_stopped()) {
 316                err = bpf_map_delete_elem(map_fd, &sk_fd);
 317                if (err && errno != ENOENT) {
 318                        err = -errno;
 319                        fprintf(stderr, "bpf_map_delete_elem: %d %d\n",
 320                                err, errno);
 321                        break;
 322                }
 323        }
 324
 325        if (!is_stopped()) {
 326                notify_thread_err();
 327                return ERR_PTR(err);
 328        }
 329
 330        return NULL;
 331}
 332
 333static int do_sk_storage_map_stress_change(void)
 334{
 335        int i, sk_fd, map_fd = -1, err = 0, nr_threads_created = 0;
 336        pthread_t *sk_thread_ids;
 337        void *thread_ret;
 338
 339        sk_thread_ids = malloc(sizeof(pthread_t) * nr_sk_threads);
 340        if (!sk_thread_ids) {
 341                fprintf(stderr, "malloc(sk_threads): NULL\n");
 342                return -ENOMEM;
 343        }
 344
 345        sk_fd = socket(AF_INET6, SOCK_STREAM, 0);
 346        if (sk_fd == -1) {
 347                err = -errno;
 348                goto done;
 349        }
 350
 351        map_fd = create_sk_storage_map();
 352        WRITE_ONCE(sk_storage_map, map_fd);
 353
 354        for (i = 0; i < nr_sk_threads; i++) {
 355                if (i & 0x1)
 356                        err = pthread_create(&sk_thread_ids[i], NULL,
 357                                             update_thread, &sk_fd);
 358                else
 359                        err = pthread_create(&sk_thread_ids[i], NULL,
 360                                             delete_thread, &sk_fd);
 361                if (err) {
 362                        err = -errno;
 363                        goto done;
 364                }
 365                nr_threads_created++;
 366        }
 367
 368        wait_for_threads_err();
 369
 370done:
 371        WRITE_ONCE(stop, 1);
 372        for (i = 0; i < nr_threads_created; i++) {
 373                pthread_join(sk_thread_ids[i], &thread_ret);
 374                if (IS_ERR(thread_ret) && !err) {
 375                        err = PTR_ERR(thread_ret);
 376                        fprintf(stderr, "threads#%u: err:%d\n", i, err);
 377                }
 378        }
 379        free(sk_thread_ids);
 380
 381        if (sk_fd != -1)
 382                close(sk_fd);
 383        close(map_fd);
 384
 385        return err;
 386}
 387
 388static void stop_handler(int signum)
 389{
 390        if (signum != SIGALRM)
 391                printf("stopping...\n");
 392        WRITE_ONCE(stop, 1);
 393}
 394
 395#define BPF_SK_STORAGE_MAP_TEST_NR_THREADS "BPF_SK_STORAGE_MAP_TEST_NR_THREADS"
 396#define BPF_SK_STORAGE_MAP_TEST_SK_PER_THREAD "BPF_SK_STORAGE_MAP_TEST_SK_PER_THREAD"
 397#define BPF_SK_STORAGE_MAP_TEST_RUNTIME_S "BPF_SK_STORAGE_MAP_TEST_RUNTIME_S"
 398#define BPF_SK_STORAGE_MAP_TEST_NAME "BPF_SK_STORAGE_MAP_TEST_NAME"
 399
 400static void test_sk_storage_map_stress_free(void)
 401{
 402        struct rlimit rlim_old, rlim_new = {};
 403        int err;
 404
 405        getrlimit(RLIMIT_NOFILE, &rlim_old);
 406
 407        signal(SIGTERM, stop_handler);
 408        signal(SIGINT, stop_handler);
 409        if (runtime_s > 0) {
 410                signal(SIGALRM, stop_handler);
 411                alarm(runtime_s);
 412        }
 413
 414        if (rlim_old.rlim_cur < nr_sk_threads * nr_sk_per_thread) {
 415                rlim_new.rlim_cur = nr_sk_threads * nr_sk_per_thread + 128;
 416                rlim_new.rlim_max = rlim_new.rlim_cur + 128;
 417                err = setrlimit(RLIMIT_NOFILE, &rlim_new);
 418                CHECK(err, "setrlimit(RLIMIT_NOFILE)", "rlim_new:%lu errno:%d",
 419                      rlim_new.rlim_cur, errno);
 420        }
 421
 422        err = do_sk_storage_map_stress_free();
 423
 424        signal(SIGTERM, SIG_DFL);
 425        signal(SIGINT, SIG_DFL);
 426        if (runtime_s > 0) {
 427                signal(SIGALRM, SIG_DFL);
 428                alarm(0);
 429        }
 430
 431        if (rlim_new.rlim_cur)
 432                setrlimit(RLIMIT_NOFILE, &rlim_old);
 433
 434        CHECK(err, "test_sk_storage_map_stress_free", "err:%d\n", err);
 435}
 436
 437static void test_sk_storage_map_stress_change(void)
 438{
 439        int err;
 440
 441        signal(SIGTERM, stop_handler);
 442        signal(SIGINT, stop_handler);
 443        if (runtime_s > 0) {
 444                signal(SIGALRM, stop_handler);
 445                alarm(runtime_s);
 446        }
 447
 448        err = do_sk_storage_map_stress_change();
 449
 450        signal(SIGTERM, SIG_DFL);
 451        signal(SIGINT, SIG_DFL);
 452        if (runtime_s > 0) {
 453                signal(SIGALRM, SIG_DFL);
 454                alarm(0);
 455        }
 456
 457        CHECK(err, "test_sk_storage_map_stress_change", "err:%d\n", err);
 458}
 459
 460static void test_sk_storage_map_basic(void)
 461{
 462        struct {
 463                int cnt;
 464                int lock;
 465        } value = { .cnt = 0xeB9f, .lock = 0, }, lookup_value;
 466        struct bpf_create_map_attr bad_xattr;
 467        int btf_fd, map_fd, sk_fd, err;
 468
 469        btf_fd = load_btf();
 470        CHECK(btf_fd == -1, "bpf_load_btf", "btf_fd:%d errno:%d\n",
 471              btf_fd, errno);
 472        xattr.btf_fd = btf_fd;
 473
 474        sk_fd = socket(AF_INET6, SOCK_STREAM, 0);
 475        CHECK(sk_fd == -1, "socket()", "sk_fd:%d errno:%d\n",
 476              sk_fd, errno);
 477
 478        map_fd = bpf_create_map_xattr(&xattr);
 479        CHECK(map_fd == -1, "bpf_create_map_xattr(good_xattr)",
 480              "map_fd:%d errno:%d\n", map_fd, errno);
 481
 482        /* Add new elem */
 483        memcpy(&lookup_value, &value, sizeof(value));
 484        err = bpf_map_update_elem(map_fd, &sk_fd, &value,
 485                                  BPF_NOEXIST | BPF_F_LOCK);
 486        CHECK(err, "bpf_map_update_elem(BPF_NOEXIST|BPF_F_LOCK)",
 487              "err:%d errno:%d\n", err, errno);
 488        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 489                                        BPF_F_LOCK);
 490        CHECK(err || lookup_value.cnt != value.cnt,
 491              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 492              "err:%d errno:%d cnt:%x(%x)\n",
 493              err, errno, lookup_value.cnt, value.cnt);
 494
 495        /* Bump the cnt and update with BPF_EXIST | BPF_F_LOCK */
 496        value.cnt += 1;
 497        err = bpf_map_update_elem(map_fd, &sk_fd, &value,
 498                                  BPF_EXIST | BPF_F_LOCK);
 499        CHECK(err, "bpf_map_update_elem(BPF_EXIST|BPF_F_LOCK)",
 500              "err:%d errno:%d\n", err, errno);
 501        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 502                                        BPF_F_LOCK);
 503        CHECK(err || lookup_value.cnt != value.cnt,
 504              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 505              "err:%d errno:%d cnt:%x(%x)\n",
 506              err, errno, lookup_value.cnt, value.cnt);
 507
 508        /* Bump the cnt and update with BPF_EXIST */
 509        value.cnt += 1;
 510        err = bpf_map_update_elem(map_fd, &sk_fd, &value, BPF_EXIST);
 511        CHECK(err, "bpf_map_update_elem(BPF_EXIST)",
 512              "err:%d errno:%d\n", err, errno);
 513        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 514                                        BPF_F_LOCK);
 515        CHECK(err || lookup_value.cnt != value.cnt,
 516              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 517              "err:%d errno:%d cnt:%x(%x)\n",
 518              err, errno, lookup_value.cnt, value.cnt);
 519
 520        /* Update with BPF_NOEXIST */
 521        value.cnt += 1;
 522        err = bpf_map_update_elem(map_fd, &sk_fd, &value,
 523                                  BPF_NOEXIST | BPF_F_LOCK);
 524        CHECK(!err || errno != EEXIST,
 525              "bpf_map_update_elem(BPF_NOEXIST|BPF_F_LOCK)",
 526              "err:%d errno:%d\n", err, errno);
 527        err = bpf_map_update_elem(map_fd, &sk_fd, &value, BPF_NOEXIST);
 528        CHECK(!err || errno != EEXIST, "bpf_map_update_elem(BPF_NOEXIST)",
 529              "err:%d errno:%d\n", err, errno);
 530        value.cnt -= 1;
 531        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 532                                        BPF_F_LOCK);
 533        CHECK(err || lookup_value.cnt != value.cnt,
 534              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 535              "err:%d errno:%d cnt:%x(%x)\n",
 536              err, errno, lookup_value.cnt, value.cnt);
 537
 538        /* Bump the cnt again and update with map_flags == 0 */
 539        value.cnt += 1;
 540        err = bpf_map_update_elem(map_fd, &sk_fd, &value, 0);
 541        CHECK(err, "bpf_map_update_elem()", "err:%d errno:%d\n",
 542              err, errno);
 543        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 544                                        BPF_F_LOCK);
 545        CHECK(err || lookup_value.cnt != value.cnt,
 546              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 547              "err:%d errno:%d cnt:%x(%x)\n",
 548              err, errno, lookup_value.cnt, value.cnt);
 549
 550        /* Test delete elem */
 551        err = bpf_map_delete_elem(map_fd, &sk_fd);
 552        CHECK(err, "bpf_map_delete_elem()", "err:%d errno:%d\n",
 553              err, errno);
 554        err = bpf_map_lookup_elem_flags(map_fd, &sk_fd, &lookup_value,
 555                                        BPF_F_LOCK);
 556        CHECK(!err || errno != ENOENT,
 557              "bpf_map_lookup_elem_flags(BPF_F_LOCK)",
 558              "err:%d errno:%d\n", err, errno);
 559        err = bpf_map_delete_elem(map_fd, &sk_fd);
 560        CHECK(!err || errno != ENOENT, "bpf_map_delete_elem()",
 561              "err:%d errno:%d\n", err, errno);
 562
 563        memcpy(&bad_xattr, &xattr, sizeof(xattr));
 564        bad_xattr.btf_key_type_id = 0;
 565        err = bpf_create_map_xattr(&bad_xattr);
 566        CHECK(!err || errno != EINVAL, "bap_create_map_xattr(bad_xattr)",
 567              "err:%d errno:%d\n", err, errno);
 568
 569        memcpy(&bad_xattr, &xattr, sizeof(xattr));
 570        bad_xattr.btf_key_type_id = 3;
 571        err = bpf_create_map_xattr(&bad_xattr);
 572        CHECK(!err || errno != EINVAL, "bap_create_map_xattr(bad_xattr)",
 573              "err:%d errno:%d\n", err, errno);
 574
 575        memcpy(&bad_xattr, &xattr, sizeof(xattr));
 576        bad_xattr.max_entries = 1;
 577        err = bpf_create_map_xattr(&bad_xattr);
 578        CHECK(!err || errno != EINVAL, "bap_create_map_xattr(bad_xattr)",
 579              "err:%d errno:%d\n", err, errno);
 580
 581        memcpy(&bad_xattr, &xattr, sizeof(xattr));
 582        bad_xattr.map_flags = 0;
 583        err = bpf_create_map_xattr(&bad_xattr);
 584        CHECK(!err || errno != EINVAL, "bap_create_map_xattr(bad_xattr)",
 585              "err:%d errno:%d\n", err, errno);
 586
 587        xattr.btf_fd = -1;
 588        close(btf_fd);
 589        close(map_fd);
 590        close(sk_fd);
 591}
 592
 593void test_sk_storage_map(void)
 594{
 595        const char *test_name, *env_opt;
 596        bool test_ran = false;
 597
 598        test_name = getenv(BPF_SK_STORAGE_MAP_TEST_NAME);
 599
 600        env_opt = getenv(BPF_SK_STORAGE_MAP_TEST_NR_THREADS);
 601        if (env_opt)
 602                nr_sk_threads = atoi(env_opt);
 603
 604        env_opt = getenv(BPF_SK_STORAGE_MAP_TEST_SK_PER_THREAD);
 605        if (env_opt)
 606                nr_sk_per_thread = atoi(env_opt);
 607
 608        env_opt = getenv(BPF_SK_STORAGE_MAP_TEST_RUNTIME_S);
 609        if (env_opt)
 610                runtime_s = atoi(env_opt);
 611
 612        if (!test_name || !strcmp(test_name, "basic")) {
 613                test_sk_storage_map_basic();
 614                test_ran = true;
 615        }
 616        if (!test_name || !strcmp(test_name, "stress_free")) {
 617                test_sk_storage_map_stress_free();
 618                test_ran = true;
 619        }
 620        if (!test_name || !strcmp(test_name, "stress_change")) {
 621                test_sk_storage_map_stress_change();
 622                test_ran = true;
 623        }
 624
 625        if (test_ran)
 626                printf("%s:PASS\n", __func__);
 627        else
 628                CHECK(1, "Invalid test_name", "%s\n", test_name);
 629}
 630