98 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2021 Facebook */3#include <test_progs.h>4#include "timer.skel.h"5#include "timer_failure.skel.h"6 7#define NUM_THR 88 9static void *spin_lock_thread(void *arg)10{11 int i, err, prog_fd = *(int *)arg;12 LIBBPF_OPTS(bpf_test_run_opts, topts);13 14 for (i = 0; i < 10000; i++) {15 err = bpf_prog_test_run_opts(prog_fd, &topts);16 if (!ASSERT_OK(err, "test_run_opts err") ||17 !ASSERT_OK(topts.retval, "test_run_opts retval"))18 break;19 }20 21 pthread_exit(arg);22}23 24static int timer(struct timer *timer_skel)25{26 int i, err, prog_fd;27 LIBBPF_OPTS(bpf_test_run_opts, topts);28 pthread_t thread_id[NUM_THR];29 void *ret;30 31 err = timer__attach(timer_skel);32 if (!ASSERT_OK(err, "timer_attach"))33 return err;34 35 ASSERT_EQ(timer_skel->data->callback_check, 52, "callback_check1");36 ASSERT_EQ(timer_skel->data->callback2_check, 52, "callback2_check1");37 ASSERT_EQ(timer_skel->bss->pinned_callback_check, 0, "pinned_callback_check1");38 39 prog_fd = bpf_program__fd(timer_skel->progs.test1);40 err = bpf_prog_test_run_opts(prog_fd, &topts);41 ASSERT_OK(err, "test_run");42 ASSERT_EQ(topts.retval, 0, "test_run");43 timer__detach(timer_skel);44 45 usleep(50); /* 10 usecs should be enough, but give it extra */46 /* check that timer_cb1() was executed 10+10 times */47 ASSERT_EQ(timer_skel->data->callback_check, 42, "callback_check2");48 ASSERT_EQ(timer_skel->data->callback2_check, 42, "callback2_check2");49 50 /* check that timer_cb2() was executed twice */51 ASSERT_EQ(timer_skel->bss->bss_data, 10, "bss_data");52 53 /* check that timer_cb3() was executed twice */54 ASSERT_EQ(timer_skel->bss->abs_data, 12, "abs_data");55 56 /* check that timer_cb_pinned() was executed twice */57 ASSERT_EQ(timer_skel->bss->pinned_callback_check, 2, "pinned_callback_check");58 59 /* check that there were no errors in timer execution */60 ASSERT_EQ(timer_skel->bss->err, 0, "err");61 62 /* check that code paths completed */63 ASSERT_EQ(timer_skel->bss->ok, 1 | 2 | 4, "ok");64 65 prog_fd = bpf_program__fd(timer_skel->progs.race);66 for (i = 0; i < NUM_THR; i++) {67 err = pthread_create(&thread_id[i], NULL,68 &spin_lock_thread, &prog_fd);69 if (!ASSERT_OK(err, "pthread_create"))70 break;71 }72 73 while (i) {74 err = pthread_join(thread_id[--i], &ret);75 if (ASSERT_OK(err, "pthread_join"))76 ASSERT_EQ(ret, (void *)&prog_fd, "pthread_join");77 }78 79 return 0;80}81 82/* TODO: use pid filtering */83void serial_test_timer(void)84{85 struct timer *timer_skel = NULL;86 int err;87 88 timer_skel = timer__open_and_load();89 if (!ASSERT_OK_PTR(timer_skel, "timer_skel_load"))90 return;91 92 err = timer(timer_skel);93 ASSERT_OK(err, "timer");94 timer__destroy(timer_skel);95 96 RUN_TESTS(timer_failure);97}98