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: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6958c97a48
commit
ff92741270
@ -925,6 +925,12 @@ struct dev_ifalias {
|
||||
struct devlink;
|
||||
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.
|
||||
* The following hooks can be defined; unless noted otherwise, they are
|
||||
@ -1564,7 +1570,7 @@ enum netdev_priv_flags {
|
||||
* (i.e. as seen by users in the "Space.c" file). It is the name
|
||||
* of the interface.
|
||||
*
|
||||
* @name_hlist: Device name hash chain, please keep it close to name[]
|
||||
* @name_node: Name hashlist node
|
||||
* @ifalias: SNMP alias
|
||||
* @mem_end: Shared memory end
|
||||
* @mem_start: Shared memory start
|
||||
@ -1774,7 +1780,7 @@ enum netdev_priv_flags {
|
||||
|
||||
struct net_device {
|
||||
char name[IFNAMSIZ];
|
||||
struct hlist_node name_hlist;
|
||||
struct netdev_name_node *name_node;
|
||||
struct dev_ifalias __rcu *ifalias;
|
||||
/*
|
||||
* I/O specific fields
|
||||
|
@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd)
|
||||
#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 */
|
||||
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);
|
||||
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,
|
||||
dev_index_hash(net, dev->ifindex));
|
||||
write_unlock_bh(&dev_base_lock);
|
||||
@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev)
|
||||
/* Unlink dev from the device chain */
|
||||
write_lock_bh(&dev_base_lock);
|
||||
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);
|
||||
write_unlock_bh(&dev_base_lock);
|
||||
|
||||
@ -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;
|
||||
struct hlist_head *head = dev_name_hash(net, name);
|
||||
struct netdev_name_node *node_name;
|
||||
|
||||
hlist_for_each_entry(dev, head, name_hlist)
|
||||
if (!strncmp(dev->name, name, IFNAMSIZ))
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
node_name = netdev_name_node_lookup(net, name);
|
||||
return node_name ? node_name->dev : NULL;
|
||||
}
|
||||
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;
|
||||
struct hlist_head *head = dev_name_hash(net, name);
|
||||
struct netdev_name_node *node_name;
|
||||
|
||||
hlist_for_each_entry_rcu(dev, head, name_hlist)
|
||||
if (!strncmp(dev->name, name, IFNAMSIZ))
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
node_name = netdev_name_node_lookup_rcu(net, name);
|
||||
return node_name ? node_name->dev : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_get_by_name_rcu);
|
||||
|
||||
@ -1232,13 +1285,13 @@ rollback:
|
||||
netdev_adjacent_rename_links(dev, oldname);
|
||||
|
||||
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);
|
||||
|
||||
synchronize_rcu();
|
||||
|
||||
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);
|
||||
|
||||
ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
|
||||
@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head)
|
||||
dev_uc_flush(dev);
|
||||
dev_mc_flush(dev);
|
||||
|
||||
netdev_name_node_free(dev->name_node);
|
||||
|
||||
if (dev->netdev_ops->ndo_uninit)
|
||||
dev->netdev_ops->ndo_uninit(dev);
|
||||
|
||||
@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
dev->name_node = netdev_name_node_head_alloc(dev);
|
||||
if (!dev->name_node)
|
||||
goto out;
|
||||
|
||||
/* Init, if this function is available */
|
||||
if (dev->netdev_ops->ndo_init) {
|
||||
ret = dev->netdev_ops->ndo_init(dev);
|
||||
@ -8827,6 +8886,8 @@ out:
|
||||
return ret;
|
||||
|
||||
err_uninit:
|
||||
if (dev->name_node)
|
||||
netdev_name_node_free(dev->name_node);
|
||||
if (dev->netdev_ops->ndo_uninit)
|
||||
dev->netdev_ops->ndo_uninit(dev);
|
||||
if (dev->priv_destructor)
|
||||
|
Loading…
Reference in New Issue
Block a user