@@ -1057,6 +1057,8 @@ __bpf_kfunc int bpf_kfunc_st_ops_inc10(struct st_ops_args *args)
10571057 return args -> a ;
10581058}
10591059
1060+ __bpf_kfunc int bpf_kfunc_multi_st_ops_test_1 (struct st_ops_args * args , u32 id );
1061+
10601062BTF_KFUNCS_START (bpf_testmod_check_kfunc_ids )
10611063BTF_ID_FLAGS (func , bpf_testmod_test_mod_kfunc )
10621064BTF_ID_FLAGS (func , bpf_kfunc_call_test1 )
@@ -1097,6 +1099,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_st_ops_test_prologue, KF_TRUSTED_ARGS | KF_SLEEPABL
10971099BTF_ID_FLAGS (func , bpf_kfunc_st_ops_test_epilogue , KF_TRUSTED_ARGS | KF_SLEEPABLE )
10981100BTF_ID_FLAGS (func , bpf_kfunc_st_ops_test_pro_epilogue , KF_TRUSTED_ARGS | KF_SLEEPABLE )
10991101BTF_ID_FLAGS (func , bpf_kfunc_st_ops_inc10 , KF_TRUSTED_ARGS )
1102+ BTF_ID_FLAGS (func , bpf_kfunc_multi_st_ops_test_1 , KF_TRUSTED_ARGS )
11001103BTF_KFUNCS_END (bpf_testmod_check_kfunc_ids )
11011104
11021105static int bpf_testmod_ops_init (struct btf * btf )
@@ -1528,6 +1531,114 @@ static struct bpf_struct_ops testmod_st_ops = {
15281531 .owner = THIS_MODULE ,
15291532};
15301533
1534+ struct hlist_head multi_st_ops_list ;
1535+ static DEFINE_SPINLOCK (multi_st_ops_lock );
1536+
1537+ static int multi_st_ops_init (struct btf * btf )
1538+ {
1539+ spin_lock_init (& multi_st_ops_lock );
1540+ INIT_HLIST_HEAD (& multi_st_ops_list );
1541+
1542+ return 0 ;
1543+ }
1544+
1545+ static int multi_st_ops_init_member (const struct btf_type * t ,
1546+ const struct btf_member * member ,
1547+ void * kdata , const void * udata )
1548+ {
1549+ return 0 ;
1550+ }
1551+
1552+ static struct bpf_testmod_multi_st_ops * multi_st_ops_find_nolock (u32 id )
1553+ {
1554+ struct bpf_testmod_multi_st_ops * st_ops ;
1555+
1556+ hlist_for_each_entry (st_ops , & multi_st_ops_list , node ) {
1557+ if (st_ops -> id == id )
1558+ return st_ops ;
1559+ }
1560+
1561+ return NULL ;
1562+ }
1563+
1564+ int bpf_kfunc_multi_st_ops_test_1 (struct st_ops_args * args , u32 id )
1565+ {
1566+ struct bpf_testmod_multi_st_ops * st_ops ;
1567+ unsigned long flags ;
1568+ int ret = -1 ;
1569+
1570+ spin_lock_irqsave (& multi_st_ops_lock , flags );
1571+ st_ops = multi_st_ops_find_nolock (id );
1572+ if (st_ops )
1573+ ret = st_ops -> test_1 (args );
1574+ spin_unlock_irqrestore (& multi_st_ops_lock , flags );
1575+
1576+ return ret ;
1577+ }
1578+
1579+ static int multi_st_ops_reg (void * kdata , struct bpf_link * link )
1580+ {
1581+ struct bpf_testmod_multi_st_ops * st_ops =
1582+ (struct bpf_testmod_multi_st_ops * )kdata ;
1583+ unsigned long flags ;
1584+ int err = 0 ;
1585+ u32 id ;
1586+
1587+ if (!st_ops -> test_1 )
1588+ return - EINVAL ;
1589+
1590+ id = bpf_struct_ops_id (kdata );
1591+
1592+ spin_lock_irqsave (& multi_st_ops_lock , flags );
1593+ if (multi_st_ops_find_nolock (id )) {
1594+ pr_err ("multi_st_ops(id:%d) has already been registered\n" , id );
1595+ err = - EEXIST ;
1596+ goto unlock ;
1597+ }
1598+
1599+ st_ops -> id = id ;
1600+ hlist_add_head (& st_ops -> node , & multi_st_ops_list );
1601+ unlock :
1602+ spin_unlock_irqrestore (& multi_st_ops_lock , flags );
1603+
1604+ return err ;
1605+ }
1606+
1607+ static void multi_st_ops_unreg (void * kdata , struct bpf_link * link )
1608+ {
1609+ struct bpf_testmod_multi_st_ops * st_ops ;
1610+ unsigned long flags ;
1611+ u32 id ;
1612+
1613+ id = bpf_struct_ops_id (kdata );
1614+
1615+ spin_lock_irqsave (& multi_st_ops_lock , flags );
1616+ st_ops = multi_st_ops_find_nolock (id );
1617+ if (st_ops )
1618+ hlist_del (& st_ops -> node );
1619+ spin_unlock_irqrestore (& multi_st_ops_lock , flags );
1620+ }
1621+
1622+ static int bpf_testmod_multi_st_ops__test_1 (struct st_ops_args * args )
1623+ {
1624+ return 0 ;
1625+ }
1626+
1627+ static struct bpf_testmod_multi_st_ops multi_st_ops_cfi_stubs = {
1628+ .test_1 = bpf_testmod_multi_st_ops__test_1 ,
1629+ };
1630+
1631+ struct bpf_struct_ops testmod_multi_st_ops = {
1632+ .verifier_ops = & bpf_testmod_verifier_ops ,
1633+ .init = multi_st_ops_init ,
1634+ .init_member = multi_st_ops_init_member ,
1635+ .reg = multi_st_ops_reg ,
1636+ .unreg = multi_st_ops_unreg ,
1637+ .cfi_stubs = & multi_st_ops_cfi_stubs ,
1638+ .name = "bpf_testmod_multi_st_ops" ,
1639+ .owner = THIS_MODULE ,
1640+ };
1641+
15311642extern int bpf_fentry_test1 (int a );
15321643
15331644static int bpf_testmod_init (void )
@@ -1550,6 +1661,7 @@ static int bpf_testmod_init(void)
15501661 ret = ret ?: register_bpf_struct_ops (& bpf_testmod_ops2 , bpf_testmod_ops2 );
15511662 ret = ret ?: register_bpf_struct_ops (& bpf_testmod_ops3 , bpf_testmod_ops3 );
15521663 ret = ret ?: register_bpf_struct_ops (& testmod_st_ops , bpf_testmod_st_ops );
1664+ ret = ret ?: register_bpf_struct_ops (& testmod_multi_st_ops , bpf_testmod_multi_st_ops );
15531665 ret = ret ?: register_btf_id_dtor_kfuncs (bpf_testmod_dtors ,
15541666 ARRAY_SIZE (bpf_testmod_dtors ),
15551667 THIS_MODULE );
0 commit comments