Commit ff927412 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

net: introduce name_node struct to be used in hashlist

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.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6958c97a
...@@ -925,6 +925,12 @@ struct dev_ifalias { ...@@ -925,6 +925,12 @@ struct dev_ifalias {
struct devlink; struct devlink;
struct tlsdev_ops; struct tlsdev_ops;
struct netdev_name_node {
struct hlist_node hlist;
struct net_device *dev;
const char *name;
};
/* /*
* This structure defines the management hooks for network devices. * This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are * The following hooks can be defined; unless noted otherwise, they are
...@@ -1564,7 +1570,7 @@ enum netdev_priv_flags { ...@@ -1564,7 +1570,7 @@ enum netdev_priv_flags {
* (i.e. as seen by users in the "Space.c" file). It is the name * (i.e. as seen by users in the "Space.c" file). It is the name
* of the interface. * of the interface.
* *
* @name_hlist: Device name hash chain, please keep it close to name[] * @name_node: Name hashlist node
* @ifalias: SNMP alias * @ifalias: SNMP alias
* @mem_end: Shared memory end * @mem_end: Shared memory end
* @mem_start: Shared memory start * @mem_start: Shared memory start
...@@ -1774,7 +1780,7 @@ enum netdev_priv_flags { ...@@ -1774,7 +1780,7 @@ enum netdev_priv_flags {
struct net_device { struct net_device {
char name[IFNAMSIZ]; char name[IFNAMSIZ];
struct hlist_node name_hlist; struct netdev_name_node *name_node;
struct dev_ifalias __rcu *ifalias; struct dev_ifalias __rcu *ifalias;
/* /*
* I/O specific fields * I/O specific fields
......
...@@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd) ...@@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd)
#endif #endif
} }
static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev,
const char *name)
{
struct netdev_name_node *name_node;
name_node = kmalloc(sizeof(*name_node), GFP_KERNEL);
if (!name_node)
return NULL;
INIT_HLIST_NODE(&name_node->hlist);
name_node->dev = dev;
name_node->name = name;
return name_node;
}
static struct netdev_name_node *
netdev_name_node_head_alloc(struct net_device *dev)
{
return netdev_name_node_alloc(dev, dev->name);
}
static void netdev_name_node_free(struct netdev_name_node *name_node)
{
kfree(name_node);
}
static void netdev_name_node_add(struct net *net,
struct netdev_name_node *name_node)
{
hlist_add_head_rcu(&name_node->hlist,
dev_name_hash(net, name_node->name));
}
static void netdev_name_node_del(struct netdev_name_node *name_node)
{
hlist_del_rcu(&name_node->hlist);
}
static struct netdev_name_node *netdev_name_node_lookup(struct net *net,
const char *name)
{
struct hlist_head *head = dev_name_hash(net, name);
struct netdev_name_node *name_node;
hlist_for_each_entry(name_node, head, hlist)
if (!strcmp(name_node->name, name))
return name_node;
return NULL;
}
static struct netdev_name_node *netdev_name_node_lookup_rcu(struct net *net,
const char *name)
{
struct hlist_head *head = dev_name_hash(net, name);
struct netdev_name_node *name_node;
hlist_for_each_entry_rcu(name_node, head, hlist)
if (!strcmp(name_node->name, name))
return name_node;
return NULL;
}
/* Device list insertion */ /* Device list insertion */
static void list_netdevice(struct net_device *dev) static void list_netdevice(struct net_device *dev)
{ {
...@@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev) ...@@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev)
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
list_add_tail_rcu(&dev->dev_list, &net->dev_base_head); list_add_tail_rcu(&dev->dev_list, &net->dev_base_head);
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name)); netdev_name_node_add(net, dev->name_node);
hlist_add_head_rcu(&dev->index_hlist, hlist_add_head_rcu(&dev->index_hlist,
dev_index_hash(net, dev->ifindex)); dev_index_hash(net, dev->ifindex));
write_unlock_bh(&dev_base_lock); write_unlock_bh(&dev_base_lock);
...@@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev) ...@@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev)
/* Unlink dev from the device chain */ /* Unlink dev from the device chain */
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
list_del_rcu(&dev->dev_list); list_del_rcu(&dev->dev_list);
hlist_del_rcu(&dev->name_hlist); netdev_name_node_del(dev->name_node);
hlist_del_rcu(&dev->index_hlist); hlist_del_rcu(&dev->index_hlist);
write_unlock_bh(&dev_base_lock); write_unlock_bh(&dev_base_lock);
...@@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst); ...@@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
struct net_device *__dev_get_by_name(struct net *net, const char *name) struct net_device *__dev_get_by_name(struct net *net, const char *name)
{ {
struct net_device *dev; struct netdev_name_node *node_name;
struct hlist_head *head = dev_name_hash(net, name);
hlist_for_each_entry(dev, head, name_hlist) node_name = netdev_name_node_lookup(net, name);
if (!strncmp(dev->name, name, IFNAMSIZ)) return node_name ? node_name->dev : NULL;
return dev;
return NULL;
} }
EXPORT_SYMBOL(__dev_get_by_name); EXPORT_SYMBOL(__dev_get_by_name);
...@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name); ...@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name);
struct net_device *dev_get_by_name_rcu(struct net *net, const char *name) struct net_device *dev_get_by_name_rcu(struct net *net, const char *name)
{ {
struct net_device *dev; struct netdev_name_node *node_name;
struct hlist_head *head = dev_name_hash(net, name);
hlist_for_each_entry_rcu(dev, head, name_hlist) node_name = netdev_name_node_lookup_rcu(net, name);
if (!strncmp(dev->name, name, IFNAMSIZ)) return node_name ? node_name->dev : NULL;
return dev;
return NULL;
} }
EXPORT_SYMBOL(dev_get_by_name_rcu); EXPORT_SYMBOL(dev_get_by_name_rcu);
...@@ -1232,13 +1285,13 @@ int dev_change_name(struct net_device *dev, const char *newname) ...@@ -1232,13 +1285,13 @@ int dev_change_name(struct net_device *dev, const char *newname)
netdev_adjacent_rename_links(dev, oldname); netdev_adjacent_rename_links(dev, oldname);
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
hlist_del_rcu(&dev->name_hlist); netdev_name_node_del(dev->name_node);
write_unlock_bh(&dev_base_lock); write_unlock_bh(&dev_base_lock);
synchronize_rcu(); synchronize_rcu();
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name)); netdev_name_node_add(net, dev->name_node);
write_unlock_bh(&dev_base_lock); write_unlock_bh(&dev_base_lock);
ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev); ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
...@@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head) ...@@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head)
dev_uc_flush(dev); dev_uc_flush(dev);
dev_mc_flush(dev); dev_mc_flush(dev);
netdev_name_node_free(dev->name_node);
if (dev->netdev_ops->ndo_uninit) if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev); dev->netdev_ops->ndo_uninit(dev);
...@@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev) ...@@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev)
if (ret < 0) if (ret < 0)
goto out; goto out;
dev->name_node = netdev_name_node_head_alloc(dev);
if (!dev->name_node)
goto out;
/* Init, if this function is available */ /* Init, if this function is available */
if (dev->netdev_ops->ndo_init) { if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev); ret = dev->netdev_ops->ndo_init(dev);
...@@ -8827,6 +8886,8 @@ int register_netdevice(struct net_device *dev) ...@@ -8827,6 +8886,8 @@ int register_netdevice(struct net_device *dev)
return ret; return ret;
err_uninit: err_uninit:
if (dev->name_node)
netdev_name_node_free(dev->name_node);
if (dev->netdev_ops->ndo_uninit) if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev); dev->netdev_ops->ndo_uninit(dev);
if (dev->priv_destructor) if (dev->priv_destructor)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment