Skip to content

Commit ff92741

Browse files
jpirkodavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6958c97 commit ff92741

File tree

2 files changed

+87
-20
lines changed

2 files changed

+87
-20
lines changed

include/linux/netdevice.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,12 @@ struct dev_ifalias {
925925
struct devlink;
926926
struct tlsdev_ops;
927927

928+
struct netdev_name_node {
929+
struct hlist_node hlist;
930+
struct net_device *dev;
931+
const char *name;
932+
};
933+
928934
/*
929935
* This structure defines the management hooks for network devices.
930936
* The following hooks can be defined; unless noted otherwise, they are
@@ -1564,7 +1570,7 @@ enum netdev_priv_flags {
15641570
* (i.e. as seen by users in the "Space.c" file). It is the name
15651571
* of the interface.
15661572
*
1567-
* @name_hlist: Device name hash chain, please keep it close to name[]
1573+
* @name_node: Name hashlist node
15681574
* @ifalias: SNMP alias
15691575
* @mem_end: Shared memory end
15701576
* @mem_start: Shared memory start
@@ -1774,7 +1780,7 @@ enum netdev_priv_flags {
17741780

17751781
struct net_device {
17761782
char name[IFNAMSIZ];
1777-
struct hlist_node name_hlist;
1783+
struct netdev_name_node *name_node;
17781784
struct dev_ifalias __rcu *ifalias;
17791785
/*
17801786
* I/O specific fields

net/core/dev.c

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */
232293
static 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

734795
struct 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
}
745802
EXPORT_SYMBOL(__dev_get_by_name);
746803

@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name);
758815

759816
struct 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
}
770823
EXPORT_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

88298888
err_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

Comments
 (0)