@@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd)
228228#endif
229229}
230230
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+
231292/* Device list insertion */
232293static void list_netdevice (struct net_device * dev )
233294{
@@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev)
237298
238299 write_lock_bh (& dev_base_lock );
239300 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 );
241302 hlist_add_head_rcu (& dev -> index_hlist ,
242303 dev_index_hash (net , dev -> ifindex ));
243304 write_unlock_bh (& dev_base_lock );
@@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev)
255316 /* Unlink dev from the device chain */
256317 write_lock_bh (& dev_base_lock );
257318 list_del_rcu (& dev -> dev_list );
258- hlist_del_rcu ( & dev -> name_hlist );
319+ netdev_name_node_del ( dev -> name_node );
259320 hlist_del_rcu (& dev -> index_hlist );
260321 write_unlock_bh (& dev_base_lock );
261322
@@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
733794
734795struct net_device * __dev_get_by_name (struct net * net , const char * name )
735796{
736- struct net_device * dev ;
737- struct hlist_head * head = dev_name_hash (net , name );
797+ struct netdev_name_node * node_name ;
738798
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 ;
744801}
745802EXPORT_SYMBOL (__dev_get_by_name );
746803
@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name);
758815
759816struct net_device * dev_get_by_name_rcu (struct net * net , const char * name )
760817{
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 ;
767819
768- return NULL ;
820+ node_name = netdev_name_node_lookup_rcu (net , name );
821+ return node_name ? node_name -> dev : NULL ;
769822}
770823EXPORT_SYMBOL (dev_get_by_name_rcu );
771824
@@ -1232,13 +1285,13 @@ int dev_change_name(struct net_device *dev, const char *newname)
12321285 netdev_adjacent_rename_links (dev , oldname );
12331286
12341287 write_lock_bh (& dev_base_lock );
1235- hlist_del_rcu ( & dev -> name_hlist );
1288+ netdev_name_node_del ( dev -> name_node );
12361289 write_unlock_bh (& dev_base_lock );
12371290
12381291 synchronize_rcu ();
12391292
12401293 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 );
12421295 write_unlock_bh (& dev_base_lock );
12431296
12441297 ret = call_netdevice_notifiers (NETDEV_CHANGENAME , dev );
@@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head)
82648317 dev_uc_flush (dev );
82658318 dev_mc_flush (dev );
82668319
8320+ netdev_name_node_free (dev -> name_node );
8321+
82678322 if (dev -> netdev_ops -> ndo_uninit )
82688323 dev -> netdev_ops -> ndo_uninit (dev );
82698324
@@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev)
87068761 if (ret < 0 )
87078762 goto out ;
87088763
8764+ dev -> name_node = netdev_name_node_head_alloc (dev );
8765+ if (!dev -> name_node )
8766+ goto out ;
8767+
87098768 /* Init, if this function is available */
87108769 if (dev -> netdev_ops -> ndo_init ) {
87118770 ret = dev -> netdev_ops -> ndo_init (dev );
@@ -8827,6 +8886,8 @@ int register_netdevice(struct net_device *dev)
88278886 return ret ;
88288887
88298888err_uninit :
8889+ if (dev -> name_node )
8890+ netdev_name_node_free (dev -> name_node );
88308891 if (dev -> netdev_ops -> ndo_uninit )
88318892 dev -> netdev_ops -> ndo_uninit (dev );
88328893 if (dev -> priv_destructor )
0 commit comments