1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 #include <sched.h> 5 #include <test_progs.h> 6 #include <pthread.h> 7 #include <network_helpers.h> 8 9 #include "timer_lockup.skel.h" 10 11 static long cpu; 12 static int *timer1_err; 13 static int *timer2_err; 14 static bool skip; 15 16 volatile int k = 0; 17 18 static void *timer_lockup_thread(void *arg) 19 { 20 LIBBPF_OPTS(bpf_test_run_opts, opts, 21 .data_in = &pkt_v4, 22 .data_size_in = sizeof(pkt_v4), 23 .repeat = 1000, 24 ); 25 int i, prog_fd = *(int *)arg; 26 cpu_set_t cpuset; 27 28 CPU_ZERO(&cpuset); 29 CPU_SET(__sync_fetch_and_add(&cpu, 1), &cpuset); 30 ASSERT_OK(pthread_setaffinity_np(pthread_self(), sizeof(cpuset), 31 &cpuset), 32 "cpu affinity"); 33 34 for (i = 0; !READ_ONCE(*timer1_err) && !READ_ONCE(*timer2_err); i++) { 35 bpf_prog_test_run_opts(prog_fd, &opts); 36 /* Skip the test if we can't reproduce the race in a reasonable 37 * amount of time. 38 */ 39 if (i > 50) { 40 WRITE_ONCE(skip, true); 41 break; 42 } 43 } 44 45 return NULL; 46 } 47 48 void test_timer_lockup(void) 49 { 50 int timer1_prog, timer2_prog; 51 struct timer_lockup *skel; 52 pthread_t thrds[2]; 53 void *ret; 54 55 skel = timer_lockup__open_and_load(); 56 if (!ASSERT_OK_PTR(skel, "timer_lockup__open_and_load")) 57 return; 58 59 timer1_prog = bpf_program__fd(skel->progs.timer1_prog); 60 timer2_prog = bpf_program__fd(skel->progs.timer2_prog); 61 62 timer1_err = &skel->bss->timer1_err; 63 timer2_err = &skel->bss->timer2_err; 64 65 if (!ASSERT_OK(pthread_create(&thrds[0], NULL, timer_lockup_thread, 66 &timer1_prog), 67 "pthread_create thread1")) 68 goto out; 69 if (!ASSERT_OK(pthread_create(&thrds[1], NULL, timer_lockup_thread, 70 &timer2_prog), 71 "pthread_create thread2")) { 72 pthread_exit(&thrds[0]); 73 goto out; 74 } 75 76 pthread_join(thrds[1], &ret); 77 pthread_join(thrds[0], &ret); 78 79 if (skip) { 80 test__skip(); 81 goto out; 82 } 83 84 if (*timer1_err != -EDEADLK && *timer1_err != 0) 85 ASSERT_FAIL("timer1_err bad value"); 86 if (*timer2_err != -EDEADLK && *timer2_err != 0) 87 ASSERT_FAIL("timer2_err bad value"); 88 out: 89 timer_lockup__destroy(skel); 90 return; 91 } 92