@@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd)
228
228
#endif
229
229
}
230
230
231
+ static struct netdev_name_node * netdev_name_node_alloc (struct net_device * dev ,
232
+ const char * name )
233
+ {
234
+ struct netdev_name_node * name_node ;
235
+
236
+ name_node = kmalloc (sizeof (* name_node ), GFP_KERNEL );
237
+ if (!name_node )
238
+ return NULL ;
239
+ INIT_HLIST_NODE (& name_node -> hlist );
240
+ name_node -> dev = dev ;
241
+ name_node -> name = name ;
242
+ return name_node ;
243
+ }
244
+
245
+ static struct netdev_name_node *
246
+ netdev_name_node_head_alloc (struct net_device * dev )
247
+ {
248
+ return netdev_name_node_alloc (dev , dev -> name );
249
+ }
250
+
251
+ static void netdev_name_node_free (struct netdev_name_node * name_node )
252
+ {
253
+ kfree (name_node );
254
+ }
255
+
256
+ static void netdev_name_node_add (struct net * net ,
257
+ struct netdev_name_node * name_node )
258
+ {
259
+ hlist_add_head_rcu (& name_node -> hlist ,
260
+ dev_name_hash (net , name_node -> name ));
261
+ }
262
+
263
+ static void netdev_name_node_del (struct netdev_name_node * name_node )
264
+ {
265
+ hlist_del_rcu (& name_node -> hlist );
266
+ }
267
+
268
+ static struct netdev_name_node * netdev_name_node_lookup (struct net * net ,
269
+ const char * name )
270
+ {
271
+ struct hlist_head * head = dev_name_hash (net , name );
272
+ struct netdev_name_node * name_node ;
273
+
274
+ hlist_for_each_entry (name_node , head , hlist )
275
+ if (!strcmp (name_node -> name , name ))
276
+ return name_node ;
277
+ return NULL ;
278
+ }
279
+
280
+ static struct netdev_name_node * netdev_name_node_lookup_rcu (struct net * net ,
281
+ const char * name )
282
+ {
283
+ struct hlist_head * head = dev_name_hash (net , name );
284
+ struct netdev_name_node * name_node ;
285
+
286
+ hlist_for_each_entry_rcu (name_node , head , hlist )
287
+ if (!strcmp (name_node -> name , name ))
288
+ return name_node ;
289
+ return NULL ;
290
+ }
291
+
231
292
/* Device list insertion */
232
293
static void list_netdevice (struct net_device * dev )
233
294
{
@@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev)
237
298
238
299
write_lock_bh (& dev_base_lock );
239
300
list_add_tail_rcu (& dev -> dev_list , & net -> dev_base_head );
240
- hlist_add_head_rcu ( & dev -> name_hlist , dev_name_hash ( net , dev -> name ) );
301
+ netdev_name_node_add ( net , dev -> name_node );
241
302
hlist_add_head_rcu (& dev -> index_hlist ,
242
303
dev_index_hash (net , dev -> ifindex ));
243
304
write_unlock_bh (& dev_base_lock );
@@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev)
255
316
/* Unlink dev from the device chain */
256
317
write_lock_bh (& dev_base_lock );
257
318
list_del_rcu (& dev -> dev_list );
258
- hlist_del_rcu ( & dev -> name_hlist );
319
+ netdev_name_node_del ( dev -> name_node );
259
320
hlist_del_rcu (& dev -> index_hlist );
260
321
write_unlock_bh (& dev_base_lock );
261
322
@@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
733
794
734
795
struct net_device * __dev_get_by_name (struct net * net , const char * name )
735
796
{
736
- struct net_device * dev ;
737
- struct hlist_head * head = dev_name_hash (net , name );
797
+ struct netdev_name_node * node_name ;
738
798
739
- hlist_for_each_entry (dev , head , name_hlist )
740
- if (!strncmp (dev -> name , name , IFNAMSIZ ))
741
- return dev ;
742
-
743
- return NULL ;
799
+ node_name = netdev_name_node_lookup (net , name );
800
+ return node_name ? node_name -> dev : NULL ;
744
801
}
745
802
EXPORT_SYMBOL (__dev_get_by_name );
746
803
@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name);
758
815
759
816
struct net_device * dev_get_by_name_rcu (struct net * net , const char * name )
760
817
{
761
- struct net_device * dev ;
762
- struct hlist_head * head = dev_name_hash (net , name );
763
-
764
- hlist_for_each_entry_rcu (dev , head , name_hlist )
765
- if (!strncmp (dev -> name , name , IFNAMSIZ ))
766
- return dev ;
818
+ struct netdev_name_node * node_name ;
767
819
768
- return NULL ;
820
+ node_name = netdev_name_node_lookup_rcu (net , name );
821
+ return node_name ? node_name -> dev : NULL ;
769
822
}
770
823
EXPORT_SYMBOL (dev_get_by_name_rcu );
771
824
@@ -1232,13 +1285,13 @@ int dev_change_name(struct net_device *dev, const char *newname)
1232
1285
netdev_adjacent_rename_links (dev , oldname );
1233
1286
1234
1287
write_lock_bh (& dev_base_lock );
1235
- hlist_del_rcu ( & dev -> name_hlist );
1288
+ netdev_name_node_del ( dev -> name_node );
1236
1289
write_unlock_bh (& dev_base_lock );
1237
1290
1238
1291
synchronize_rcu ();
1239
1292
1240
1293
write_lock_bh (& dev_base_lock );
1241
- hlist_add_head_rcu ( & dev -> name_hlist , dev_name_hash ( net , dev -> name ) );
1294
+ netdev_name_node_add ( net , dev -> name_node );
1242
1295
write_unlock_bh (& dev_base_lock );
1243
1296
1244
1297
ret = call_netdevice_notifiers (NETDEV_CHANGENAME , dev );
@@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head)
8264
8317
dev_uc_flush (dev );
8265
8318
dev_mc_flush (dev );
8266
8319
8320
+ netdev_name_node_free (dev -> name_node );
8321
+
8267
8322
if (dev -> netdev_ops -> ndo_uninit )
8268
8323
dev -> netdev_ops -> ndo_uninit (dev );
8269
8324
@@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev)
8706
8761
if (ret < 0 )
8707
8762
goto out ;
8708
8763
8764
+ dev -> name_node = netdev_name_node_head_alloc (dev );
8765
+ if (!dev -> name_node )
8766
+ goto out ;
8767
+
8709
8768
/* Init, if this function is available */
8710
8769
if (dev -> netdev_ops -> ndo_init ) {
8711
8770
ret = dev -> netdev_ops -> ndo_init (dev );
@@ -8827,6 +8886,8 @@ int register_netdevice(struct net_device *dev)
8827
8886
return ret ;
8828
8887
8829
8888
err_uninit :
8889
+ if (dev -> name_node )
8890
+ netdev_name_node_free (dev -> name_node );
8830
8891
if (dev -> netdev_ops -> ndo_uninit )
8831
8892
dev -> netdev_ops -> ndo_uninit (dev );
8832
8893
if (dev -> priv_destructor )
0 commit comments