Commit 6434c041 authored by Stephen Hemminger's avatar Stephen Hemminger

[NET]: Hash netdevices by ifindex for faster lookup.

parent fa13a7b8
...@@ -377,6 +377,8 @@ struct net_device ...@@ -377,6 +377,8 @@ struct net_device
struct list_head todo_list; struct list_head todo_list;
/* device name hash chain */ /* device name hash chain */
struct hlist_node name_hlist; struct hlist_node name_hlist;
/* device index hash chain */
struct hlist_node index_hlist;
/* register/unregister state machine */ /* register/unregister state machine */
enum { NETREG_UNINITIALIZED=0, enum { NETREG_UNINITIALIZED=0,
......
...@@ -188,6 +188,7 @@ EXPORT_SYMBOL(dev_base_lock); ...@@ -188,6 +188,7 @@ EXPORT_SYMBOL(dev_base_lock);
#define NETDEV_HASHBITS 8 #define NETDEV_HASHBITS 8
static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS]; static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS];
static struct hlist_head dev_index_head[1<<NETDEV_HASHBITS];
static inline struct hlist_head *dev_name_hash(const char *name) static inline struct hlist_head *dev_name_hash(const char *name)
{ {
...@@ -195,6 +196,11 @@ static inline struct hlist_head *dev_name_hash(const char *name) ...@@ -195,6 +196,11 @@ static inline struct hlist_head *dev_name_hash(const char *name)
return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)]; return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)];
} }
static inline struct hlist_head *dev_index_hash(int ifindex)
{
return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
}
/* /*
* Our notifier list * Our notifier list
*/ */
...@@ -554,12 +560,15 @@ int __dev_get(const char *name) ...@@ -554,12 +560,15 @@ int __dev_get(const char *name)
struct net_device *__dev_get_by_index(int ifindex) struct net_device *__dev_get_by_index(int ifindex)
{ {
struct net_device *dev; struct hlist_node *p;
for (dev = dev_base; dev; dev = dev->next) hlist_for_each(p, dev_index_hash(ifindex)) {
struct net_device *dev
= hlist_entry(p, struct net_device, index_hlist);
if (dev->ifindex == ifindex) if (dev->ifindex == ifindex)
break;
return dev; return dev;
}
return NULL;
} }
...@@ -2842,6 +2851,7 @@ int register_netdevice(struct net_device *dev) ...@@ -2842,6 +2851,7 @@ int register_netdevice(struct net_device *dev)
*dev_tail = dev; *dev_tail = dev;
dev_tail = &dev->next; dev_tail = &dev->next;
hlist_add_head(&dev->name_hlist, head); hlist_add_head(&dev->name_hlist, head);
hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
dev_hold(dev); dev_hold(dev);
dev->reg_state = NETREG_REGISTERING; dev->reg_state = NETREG_REGISTERING;
write_unlock_bh(&dev_base_lock); write_unlock_bh(&dev_base_lock);
...@@ -3064,6 +3074,7 @@ int unregister_netdevice(struct net_device *dev) ...@@ -3064,6 +3074,7 @@ int unregister_netdevice(struct net_device *dev)
if (d == dev) { if (d == dev) {
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
hlist_del(&dev->name_hlist); hlist_del(&dev->name_hlist);
hlist_del(&dev->index_hlist);
if (dev_tail == &dev->next) if (dev_tail == &dev->next)
dev_tail = dp; dev_tail = dp;
*dp = d->next; *dp = d->next;
...@@ -3145,6 +3156,9 @@ static int __init net_dev_init(void) ...@@ -3145,6 +3156,9 @@ static int __init net_dev_init(void)
for (i = 0; i < ARRAY_SIZE(dev_name_head); i++) for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
INIT_HLIST_HEAD(&dev_name_head[i]); INIT_HLIST_HEAD(&dev_name_head[i]);
for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
INIT_HLIST_HEAD(&dev_index_head[i]);
/* /*
* Initialise the packet receive queues. * Initialise the packet receive queues.
*/ */
......
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