2019-03-01 19:42:18 -08:00
// SPDX-License-Identifier: GPL-2.0
# include <test_progs.h>
2020-05-08 10:46:09 -07:00
# include <network_helpers.h>
static void * spin_lock_thread ( void * arg )
{
int err , prog_fd = * ( u32 * ) arg ;
2022-02-02 15:54:20 -08:00
LIBBPF_OPTS ( bpf_test_run_opts , topts ,
. data_in = & pkt_v4 ,
. data_size_in = sizeof ( pkt_v4 ) ,
. repeat = 10000 ,
) ;
err = bpf_prog_test_run_opts ( prog_fd , & topts ) ;
ASSERT_OK ( err , " test_run_opts err " ) ;
ASSERT_OK ( topts . retval , " test_run_opts retval " ) ;
2020-05-08 10:46:09 -07:00
pthread_exit ( arg ) ;
}
2019-03-01 19:42:18 -08:00
static void * parallel_map_access ( void * arg )
{
int err , map_fd = * ( u32 * ) arg ;
int vars [ 17 ] , i , j , rnd , key = 0 ;
for ( i = 0 ; i < 10000 ; i + + ) {
err = bpf_map_lookup_elem_flags ( map_fd , & key , vars , BPF_F_LOCK ) ;
2019-08-21 16:44:25 -07:00
if ( CHECK_FAIL ( err ) ) {
2019-03-01 19:42:18 -08:00
printf ( " lookup failed \n " ) ;
goto out ;
}
2019-08-21 16:44:25 -07:00
if ( CHECK_FAIL ( vars [ 0 ] ! = 0 ) ) {
2019-03-01 19:42:18 -08:00
printf ( " lookup #%d var[0]=%d \n " , i , vars [ 0 ] ) ;
goto out ;
}
rnd = vars [ 1 ] ;
for ( j = 2 ; j < 17 ; j + + ) {
if ( vars [ j ] = = rnd )
continue ;
printf ( " lookup #%d var[1]=%d var[%d]=%d \n " ,
i , rnd , j , vars [ j ] ) ;
2019-08-21 16:44:25 -07:00
CHECK_FAIL ( vars [ j ] ! = rnd ) ;
2019-03-01 19:42:18 -08:00
goto out ;
}
}
out :
pthread_exit ( arg ) ;
}
void test_map_lock ( void )
{
2022-09-01 22:22:53 +00:00
const char * file = " ./test_map_lock.bpf.o " ;
2019-03-01 19:42:18 -08:00
int prog_fd , map_fd [ 2 ] , vars [ 17 ] = { } ;
pthread_t thread_id [ 6 ] ;
2019-03-11 22:21:09 -07:00
struct bpf_object * obj = NULL ;
2019-03-01 19:42:18 -08:00
int err = 0 , key = 0 , i ;
void * ret ;
2021-11-03 15:08:44 -07:00
err = bpf_prog_test_load ( file , BPF_PROG_TYPE_CGROUP_SKB , & obj , & prog_fd ) ;
2019-08-21 16:44:25 -07:00
if ( CHECK_FAIL ( err ) ) {
2021-11-03 15:08:44 -07:00
printf ( " test_map_lock:bpf_prog_test_load errno %d \n " , errno ) ;
2019-03-01 19:42:18 -08:00
goto close_prog ;
}
map_fd [ 0 ] = bpf_find_map ( __func__ , obj , " hash_map " ) ;
2019-08-21 16:44:25 -07:00
if ( CHECK_FAIL ( map_fd [ 0 ] < 0 ) )
2019-03-01 19:42:18 -08:00
goto close_prog ;
map_fd [ 1 ] = bpf_find_map ( __func__ , obj , " array_map " ) ;
2019-08-21 16:44:25 -07:00
if ( CHECK_FAIL ( map_fd [ 1 ] < 0 ) )
2019-03-01 19:42:18 -08:00
goto close_prog ;
bpf_map_update_elem ( map_fd [ 0 ] , & key , vars , BPF_F_LOCK ) ;
for ( i = 0 ; i < 4 ; i + + )
2019-08-21 16:44:26 -07:00
if ( CHECK_FAIL ( pthread_create ( & thread_id [ i ] , NULL ,
& spin_lock_thread , & prog_fd ) ) )
goto close_prog ;
2019-03-01 19:42:18 -08:00
for ( i = 4 ; i < 6 ; i + + )
2019-08-21 16:44:26 -07:00
if ( CHECK_FAIL ( pthread_create ( & thread_id [ i ] , NULL ,
& parallel_map_access ,
& map_fd [ i - 4 ] ) ) )
goto close_prog ;
2019-03-01 19:42:18 -08:00
for ( i = 0 ; i < 4 ; i + + )
2019-08-21 16:44:26 -07:00
if ( CHECK_FAIL ( pthread_join ( thread_id [ i ] , & ret ) | |
ret ! = ( void * ) & prog_fd ) )
goto close_prog ;
2019-03-01 19:42:18 -08:00
for ( i = 4 ; i < 6 ; i + + )
2019-08-21 16:44:26 -07:00
if ( CHECK_FAIL ( pthread_join ( thread_id [ i ] , & ret ) | |
ret ! = ( void * ) & map_fd [ i - 4 ] ) )
goto close_prog ;
2019-03-01 19:42:18 -08:00
close_prog :
bpf_object__close ( obj ) ;
}