@@ -92,7 +92,8 @@ static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_
9292 DEVLINK_PORT_FN_STATE_ACTIVE ),
9393};
9494
95- static LIST_HEAD (devlink_list );
95+ static DEFINE_XARRAY_FLAGS (devlinks , XA_FLAGS_ALLOC ) ;
96+ #define DEVLINK_REGISTERED XA_MARK_1
9697
9798/* devlink_mutex
9899 *
@@ -123,6 +124,7 @@ static struct devlink *devlink_get_from_attrs(struct net *net,
123124 struct nlattr * * attrs )
124125{
125126 struct devlink * devlink ;
127+ unsigned long index ;
126128 bool found = false;
127129 char * busname ;
128130 char * devname ;
@@ -135,7 +137,7 @@ static struct devlink *devlink_get_from_attrs(struct net *net,
135137
136138 lockdep_assert_held (& devlink_mutex );
137139
138- list_for_each_entry ( devlink , & devlink_list , list ) {
140+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
139141 if (strcmp (devlink -> dev -> bus -> name , busname ) == 0 &&
140142 strcmp (dev_name (devlink -> dev ), devname ) == 0 &&
141143 net_eq (devlink_net (devlink ), net )) {
@@ -1087,11 +1089,12 @@ static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
10871089 struct devlink_rate * devlink_rate ;
10881090 struct devlink * devlink ;
10891091 int start = cb -> args [0 ];
1092+ unsigned long index ;
10901093 int idx = 0 ;
10911094 int err = 0 ;
10921095
10931096 mutex_lock (& devlink_mutex );
1094- list_for_each_entry ( devlink , & devlink_list , list ) {
1097+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
10951098 if (!devlink_try_get (devlink ))
10961099 continue ;
10971100
@@ -1189,11 +1192,12 @@ static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
11891192{
11901193 struct devlink * devlink ;
11911194 int start = cb -> args [0 ];
1195+ unsigned long index ;
11921196 int idx = 0 ;
11931197 int err ;
11941198
11951199 mutex_lock (& devlink_mutex );
1196- list_for_each_entry ( devlink , & devlink_list , list ) {
1200+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
11971201 if (!devlink_try_get (devlink ))
11981202 continue ;
11991203
@@ -1251,11 +1255,12 @@ static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
12511255 struct devlink * devlink ;
12521256 struct devlink_port * devlink_port ;
12531257 int start = cb -> args [0 ];
1258+ unsigned long index ;
12541259 int idx = 0 ;
12551260 int err ;
12561261
12571262 mutex_lock (& devlink_mutex );
1258- list_for_each_entry ( devlink , & devlink_list , list ) {
1263+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
12591264 if (!devlink_try_get (devlink ))
12601265 continue ;
12611266
@@ -1916,11 +1921,12 @@ static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
19161921 struct devlink * devlink ;
19171922 struct devlink_sb * devlink_sb ;
19181923 int start = cb -> args [0 ];
1924+ unsigned long index ;
19191925 int idx = 0 ;
19201926 int err ;
19211927
19221928 mutex_lock (& devlink_mutex );
1923- list_for_each_entry ( devlink , & devlink_list , list ) {
1929+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
19241930 if (!devlink_try_get (devlink ))
19251931 continue ;
19261932
@@ -2067,11 +2073,12 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
20672073 struct devlink * devlink ;
20682074 struct devlink_sb * devlink_sb ;
20692075 int start = cb -> args [0 ];
2076+ unsigned long index ;
20702077 int idx = 0 ;
20712078 int err = 0 ;
20722079
20732080 mutex_lock (& devlink_mutex );
2074- list_for_each_entry ( devlink , & devlink_list , list ) {
2081+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
20752082 if (!devlink_try_get (devlink ))
20762083 continue ;
20772084
@@ -2287,11 +2294,12 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
22872294 struct devlink * devlink ;
22882295 struct devlink_sb * devlink_sb ;
22892296 int start = cb -> args [0 ];
2297+ unsigned long index ;
22902298 int idx = 0 ;
22912299 int err = 0 ;
22922300
22932301 mutex_lock (& devlink_mutex );
2294- list_for_each_entry ( devlink , & devlink_list , list ) {
2302+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
22952303 if (!devlink_try_get (devlink ))
22962304 continue ;
22972305
@@ -2535,11 +2543,12 @@ devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
25352543 struct devlink * devlink ;
25362544 struct devlink_sb * devlink_sb ;
25372545 int start = cb -> args [0 ];
2546+ unsigned long index ;
25382547 int idx = 0 ;
25392548 int err = 0 ;
25402549
25412550 mutex_lock (& devlink_mutex );
2542- list_for_each_entry ( devlink , & devlink_list , list ) {
2551+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
25432552 if (!devlink_try_get (devlink ))
25442553 continue ;
25452554
@@ -4611,11 +4620,12 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
46114620 struct devlink_param_item * param_item ;
46124621 struct devlink * devlink ;
46134622 int start = cb -> args [0 ];
4623+ unsigned long index ;
46144624 int idx = 0 ;
46154625 int err = 0 ;
46164626
46174627 mutex_lock (& devlink_mutex );
4618- list_for_each_entry ( devlink , & devlink_list , list ) {
4628+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
46194629 if (!devlink_try_get (devlink ))
46204630 continue ;
46214631
@@ -4886,11 +4896,12 @@ static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
48864896 struct devlink_port * devlink_port ;
48874897 struct devlink * devlink ;
48884898 int start = cb -> args [0 ];
4899+ unsigned long index ;
48894900 int idx = 0 ;
48904901 int err = 0 ;
48914902
48924903 mutex_lock (& devlink_mutex );
4893- list_for_each_entry ( devlink , & devlink_list , list ) {
4904+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
48944905 if (!devlink_try_get (devlink ))
48954906 continue ;
48964907
@@ -5462,11 +5473,12 @@ static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
54625473{
54635474 struct devlink * devlink ;
54645475 int start = cb -> args [0 ];
5476+ unsigned long index ;
54655477 int idx = 0 ;
54665478 int err = 0 ;
54675479
54685480 mutex_lock (& devlink_mutex );
5469- list_for_each_entry ( devlink , & devlink_list , list ) {
5481+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
54705482 if (!devlink_try_get (devlink ))
54715483 continue ;
54725484
@@ -5995,11 +6007,12 @@ static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
59956007{
59966008 struct devlink * devlink ;
59976009 int start = cb -> args [0 ];
6010+ unsigned long index ;
59986011 int idx = 0 ;
59996012 int err = 0 ;
60006013
60016014 mutex_lock (& devlink_mutex );
6002- list_for_each_entry ( devlink , & devlink_list , list ) {
6015+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
60036016 if (!devlink_try_get (devlink ))
60046017 continue ;
60056018
@@ -7176,11 +7189,12 @@ devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
71767189 struct devlink_port * port ;
71777190 struct devlink * devlink ;
71787191 int start = cb -> args [0 ];
7192+ unsigned long index ;
71797193 int idx = 0 ;
71807194 int err ;
71817195
71827196 mutex_lock (& devlink_mutex );
7183- list_for_each_entry ( devlink , & devlink_list , list ) {
7197+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
71847198 if (!devlink_try_get (devlink ))
71857199 continue ;
71867200
@@ -7210,7 +7224,7 @@ devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
72107224 devlink_put (devlink );
72117225 }
72127226
7213- list_for_each_entry ( devlink , & devlink_list , list ) {
7227+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
72147228 if (!devlink_try_get (devlink ))
72157229 continue ;
72167230
@@ -7771,11 +7785,12 @@ static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
77717785 struct devlink_trap_item * trap_item ;
77727786 struct devlink * devlink ;
77737787 int start = cb -> args [0 ];
7788+ unsigned long index ;
77747789 int idx = 0 ;
77757790 int err ;
77767791
77777792 mutex_lock (& devlink_mutex );
7778- list_for_each_entry ( devlink , & devlink_list , list ) {
7793+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
77797794 if (!devlink_try_get (devlink ))
77807795 continue ;
77817796
@@ -7997,11 +8012,12 @@ static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
79978012 u32 portid = NETLINK_CB (cb -> skb ).portid ;
79988013 struct devlink * devlink ;
79998014 int start = cb -> args [0 ];
8015+ unsigned long index ;
80008016 int idx = 0 ;
80018017 int err ;
80028018
80038019 mutex_lock (& devlink_mutex );
8004- list_for_each_entry ( devlink , & devlink_list , list ) {
8020+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
80058021 if (!devlink_try_get (devlink ))
80068022 continue ;
80078023
@@ -8310,11 +8326,12 @@ static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
83108326 u32 portid = NETLINK_CB (cb -> skb ).portid ;
83118327 struct devlink * devlink ;
83128328 int start = cb -> args [0 ];
8329+ unsigned long index ;
83138330 int idx = 0 ;
83148331 int err ;
83158332
83168333 mutex_lock (& devlink_mutex );
8317- list_for_each_entry ( devlink , & devlink_list , list ) {
8334+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
83188335 if (!devlink_try_get (devlink ))
83198336 continue ;
83208337
@@ -8899,6 +8916,8 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
88998916 struct device * dev )
89008917{
89018918 struct devlink * devlink ;
8919+ static u32 last_id ;
8920+ int ret ;
89028921
89038922 WARN_ON (!ops || !dev );
89048923 if (!devlink_reload_actions_valid (ops ))
@@ -8908,6 +8927,13 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
89088927 if (!devlink )
89098928 return NULL ;
89108929
8930+ ret = xa_alloc_cyclic (& devlinks , & devlink -> index , devlink , xa_limit_31b ,
8931+ & last_id , GFP_KERNEL );
8932+ if (ret < 0 ) {
8933+ kfree (devlink );
8934+ return NULL ;
8935+ }
8936+
89118937 devlink -> dev = dev ;
89128938 devlink -> ops = ops ;
89138939 xa_init_flags (& devlink -> snapshot_ids , XA_FLAGS_ALLOC );
@@ -8940,7 +8966,7 @@ EXPORT_SYMBOL_GPL(devlink_alloc_ns);
89408966int devlink_register (struct devlink * devlink )
89418967{
89428968 mutex_lock (& devlink_mutex );
8943- list_add_tail ( & devlink -> list , & devlink_list );
8969+ xa_set_mark ( & devlinks , devlink -> index , DEVLINK_REGISTERED );
89448970 devlink_notify (devlink , DEVLINK_CMD_NEW );
89458971 mutex_unlock (& devlink_mutex );
89468972 return 0 ;
@@ -8961,7 +8987,7 @@ void devlink_unregister(struct devlink *devlink)
89618987 WARN_ON (devlink_reload_supported (devlink -> ops ) &&
89628988 devlink -> reload_enabled );
89638989 devlink_notify (devlink , DEVLINK_CMD_DEL );
8964- list_del ( & devlink -> list );
8990+ xa_clear_mark ( & devlinks , devlink -> index , DEVLINK_REGISTERED );
89658991 mutex_unlock (& devlink_mutex );
89668992}
89678993EXPORT_SYMBOL_GPL (devlink_unregister );
@@ -9023,6 +9049,7 @@ void devlink_free(struct devlink *devlink)
90239049 WARN_ON (!list_empty (& devlink -> port_list ));
90249050
90259051 xa_destroy (& devlink -> snapshot_ids );
9052+ xa_erase (& devlinks , devlink -> index );
90269053
90279054 kfree (devlink );
90289055}
@@ -11497,13 +11524,14 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
1149711524{
1149811525 struct devlink * devlink ;
1149911526 u32 actions_performed ;
11527+ unsigned long index ;
1150011528 int err ;
1150111529
1150211530 /* In case network namespace is getting destroyed, reload
1150311531 * all devlink instances from this namespace into init_net.
1150411532 */
1150511533 mutex_lock (& devlink_mutex );
11506- list_for_each_entry ( devlink , & devlink_list , list ) {
11534+ xa_for_each_marked ( & devlinks , index , devlink , DEVLINK_REGISTERED ) {
1150711535 if (!devlink_try_get (devlink ))
1150811536 continue ;
1150911537
0 commit comments