Introduce name_node structure to hold name of device and put it into hashlist instead of putting there struct net_device directly. Add a necessary infrastructure to manipulate the hashlist. This prepares the code to use the same hashlist for alternative names introduced later in this set.
Unified · Split
| @@ -925,6 +925,12 @@ struct dev_ifalias { · 924 unmodified lines | |||
| 925 | struct devlink; | 925 | struct devlink; |
| 926 | struct tlsdev_ops; | 926 | struct tlsdev_ops; |
| 927 | 927 | ||
| 928 | struct netdev_name_node { | ||
| 929 | struct hlist_node hlist; | ||
| 930 | struct net_device *dev; | ||
| 931 | const char *name; | ||
| 932 | }; | ||
| 933 | |||
| 928 | /* | 934 | /* |
| 929 | * This structure defines the management hooks for network devices. | 935 | * This structure defines the management hooks for network devices. |
| 930 | * The following hooks can be defined; unless noted otherwise, they are | 936 | * The following hooks can be defined; unless noted otherwise, they are |
| @@ -1564,7 +1570,7 @@ enum netdev_priv_flags { · 633 unmodified lines | |||
| 1564 | * (i.e. as seen by users in the "Space.c" file). It is the name | 1570 | * (i.e. as seen by users in the "Space.c" file). It is the name |
| 1565 | * of the interface. | 1571 | * of the interface. |
| 1566 | * | 1572 | * |
| 1567 | * @name_hlist: Device name hash chain, please keep it close to name[] | 1573 | * @name_node: Name hashlist node |
| 1568 | * @ifalias: SNMP alias | 1574 | * @ifalias: SNMP alias |
| 1569 | * @mem_end: Shared memory end | 1575 | * @mem_end: Shared memory end |
| 1570 | * @mem_start: Shared memory start | 1576 | * @mem_start: Shared memory start |
| @@ -1774,7 +1780,7 @@ enum netdev_priv_flags { · 203 unmodified lines | |||
| 1774 | 1780 | ||
| 1775 | struct net_device { | 1781 | struct net_device { |
| 1776 | char name[IFNAMSIZ]; | 1782 | char name[IFNAMSIZ]; |
| 1777 | struct hlist_node name_hlist; | 1783 | struct netdev_name_node *name_node; |
| 1778 | struct dev_ifalias __rcu *ifalias; | 1784 | struct dev_ifalias __rcu *ifalias; |
| 1779 | /* | 1785 | /* |
| 1780 | * I/O specific fields | 1786 | * I/O specific fields |
| @@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd) · 227 unmodified lines | |||
| 228 | #endif | 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 | /* Device list insertion */ | 292 | /* Device list insertion */ |
| 232 | static void list_netdevice(struct net_device *dev) | 293 | static void list_netdevice(struct net_device *dev) |
| 233 | { | 294 | { |
| @@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev) · 3 unmodified lines | |||
| 237 | 298 | ||
| 238 | write_lock_bh(&dev_base_lock); | 299 | write_lock_bh(&dev_base_lock); |
| 239 | list_add_tail_rcu(&dev->dev_list, &net->dev_base_head); | 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 | hlist_add_head_rcu(&dev->index_hlist, | 302 | hlist_add_head_rcu(&dev->index_hlist, |
| 242 | dev_index_hash(net, dev->ifindex)); | 303 | dev_index_hash(net, dev->ifindex)); |
| 243 | write_unlock_bh(&dev_base_lock); | 304 | write_unlock_bh(&dev_base_lock); |
| @@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev) · 11 unmodified lines | |||
| 255 | /* Unlink dev from the device chain */ | 316 | /* Unlink dev from the device chain */ |
| 256 | write_lock_bh(&dev_base_lock); | 317 | write_lock_bh(&dev_base_lock); |
| 257 | list_del_rcu(&dev->dev_list); | 318 | list_del_rcu(&dev->dev_list); |
| 258 | hlist_del_rcu(&dev->name_hlist); | 319 | netdev_name_node_del(dev->name_node); |
| 259 | hlist_del_rcu(&dev->index_hlist); | 320 | hlist_del_rcu(&dev->index_hlist); |
| 260 | write_unlock_bh(&dev_base_lock); | 321 | write_unlock_bh(&dev_base_lock); |
| 261 | 322 | ||
| @@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst); · 471 unmodified lines | |||
| 733 | 794 | ||
| 734 | struct net_device *__dev_get_by_name(struct net *net, const char *name) | 795 | struct net_device *__dev_get_by_name(struct net *net, const char *name) |
| 735 | { | 796 | { |
| 736 | struct net_device *dev; | 797 | struct netdev_name_node *node_name; |
| 737 | struct hlist_head *head = dev_name_hash(net, name); | ||
| 738 | 798 | ||
| 739 | hlist_for_each_entry(dev, head, name_hlist) | 799 | node_name = netdev_name_node_lookup(net, name); |
| 740 | if (!strncmp(dev->name, name, IFNAMSIZ)) | 800 | return node_name ? node_name->dev : NULL; |
| 741 | return dev; | ||
| 742 | |||
| 743 | return NULL; | ||
| 744 | } | 801 | } |
| 745 | EXPORT_SYMBOL(__dev_get_by_name); | 802 | EXPORT_SYMBOL(__dev_get_by_name); |
| 746 | 803 | ||
| @@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name); · 11 unmodified lines | |||
| 758 | 815 | ||
| 759 | struct net_device *dev_get_by_name_rcu(struct net *net, const char *name) | 816 | struct net_device *dev_get_by_name_rcu(struct net *net, const char *name) |
| 760 | { | 817 | { |
| 761 | struct net_device *dev; | 818 | struct netdev_name_node *node_name; |
| 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; | ||
| 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 | EXPORT_SYMBOL(dev_get_by_name_rcu); | 823 | EXPORT_SYMBOL(dev_get_by_name_rcu); |
| 771 | 824 | ||
| @@ -1232,13 +1285,13 @@ rollback: · 460 unmodified lines | |||
| 1232 | netdev_adjacent_rename_links(dev, oldname); | 1285 | netdev_adjacent_rename_links(dev, oldname); |
| 1233 | 1286 | ||
| 1234 | write_lock_bh(&dev_base_lock); | 1287 | write_lock_bh(&dev_base_lock); |
| 1235 | hlist_del_rcu(&dev->name_hlist); | 1288 | netdev_name_node_del(dev->name_node); |
| 1236 | write_unlock_bh(&dev_base_lock); | 1289 | write_unlock_bh(&dev_base_lock); |
| 1237 | 1290 | ||
| 1238 | synchronize_rcu(); | 1291 | synchronize_rcu(); |
| 1239 | 1292 | ||
| 1240 | write_lock_bh(&dev_base_lock); | 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 | write_unlock_bh(&dev_base_lock); | 1295 | write_unlock_bh(&dev_base_lock); |
| 1243 | 1296 | ||
| 1244 | ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev); | 1297 | ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev); |
| @@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head) · 7019 unmodified lines | |||
| 8264 | dev_uc_flush(dev); | 8317 | dev_uc_flush(dev); |
| 8265 | dev_mc_flush(dev); | 8318 | dev_mc_flush(dev); |
| 8266 | 8319 | ||
| 8320 | netdev_name_node_free(dev->name_node); | ||
| 8321 | |||
| 8267 | if (dev->netdev_ops->ndo_uninit) | 8322 | if (dev->netdev_ops->ndo_uninit) |
| 8268 | dev->netdev_ops->ndo_uninit(dev); | 8323 | dev->netdev_ops->ndo_uninit(dev); |
| 8269 | 8324 | ||
| @@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev) · 436 unmodified lines | |||
| 8706 | if (ret < 0) | 8761 | if (ret < 0) |
| 8707 | goto out; | 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 | /* Init, if this function is available */ | 8768 | /* Init, if this function is available */ |
| 8710 | if (dev->netdev_ops->ndo_init) { | 8769 | if (dev->netdev_ops->ndo_init) { |
| 8711 | ret = dev->netdev_ops->ndo_init(dev); | 8770 | ret = dev->netdev_ops->ndo_init(dev); |
| @@ -8827,6 +8886,8 @@ out: · 115 unmodified lines | |||
| 8827 | return ret; | 8886 | return ret; |
| 8828 | 8887 | ||
| 8829 | err_uninit: | 8888 | err_uninit: |
| 8889 | if (dev->name_node) | ||
| 8890 | netdev_name_node_free(dev->name_node); | ||
| 8830 | if (dev->netdev_ops->ndo_uninit) | 8891 | if (dev->netdev_ops->ndo_uninit) |
| 8831 | dev->netdev_ops->ndo_uninit(dev); | 8892 | dev->netdev_ops->ndo_uninit(dev); |
| 8832 | if (dev->priv_destructor) | 8893 | if (dev->priv_destructor) |