Skip to content

Commit 084c953

Browse files
committed
Merge branch 'qdisc-hashtable'
Jiri Kosina says: ==================== Convert qdisc linked list into a hashtable This is a respin of the v6 of the original patch [1], split into two-patch series as requested by davem; first patch fixes all symbol conflicts that'd happen once netdevice.h starts to include hashtable.h, the second one performs the actual switch to hashtable. I've preserved Cong's Reviewed-by:, as code-wise this series is identical to the original v6 of the patch. [1] lkml.kernel.org/r/alpine.LNX.2.00.1608011220580.22028@cbobk.fhfr.pm ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents b89b815 + 59cc1f6 commit 084c953

File tree

13 files changed

+58
-46
lines changed

13 files changed

+58
-46
lines changed

drivers/net/ethernet/ti/davinci_emac.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,14 @@ static u32 hash_get(u8 *addr)
597597
}
598598

599599
/**
600-
* hash_add - Hash function to add mac addr from hash table
600+
* emac_hash_add - Hash function to add mac addr from hash table
601601
* @priv: The DaVinci EMAC private adapter structure
602602
* @mac_addr: mac address to delete from hash table
603603
*
604604
* Adds mac address to the internal hash table
605605
*
606606
*/
607-
static int hash_add(struct emac_priv *priv, u8 *mac_addr)
607+
static int emac_hash_add(struct emac_priv *priv, u8 *mac_addr)
608608
{
609609
struct device *emac_dev = &priv->ndev->dev;
610610
u32 rc = 0;
@@ -613,7 +613,7 @@ static int hash_add(struct emac_priv *priv, u8 *mac_addr)
613613

614614
if (hash_value >= EMAC_NUM_MULTICAST_BITS) {
615615
if (netif_msg_drv(priv)) {
616-
dev_err(emac_dev, "DaVinci EMAC: hash_add(): Invalid "\
616+
dev_err(emac_dev, "DaVinci EMAC: emac_hash_add(): Invalid "\
617617
"Hash %08x, should not be greater than %08x",
618618
hash_value, (EMAC_NUM_MULTICAST_BITS - 1));
619619
}
@@ -639,14 +639,14 @@ static int hash_add(struct emac_priv *priv, u8 *mac_addr)
639639
}
640640

641641
/**
642-
* hash_del - Hash function to delete mac addr from hash table
642+
* emac_hash_del - Hash function to delete mac addr from hash table
643643
* @priv: The DaVinci EMAC private adapter structure
644644
* @mac_addr: mac address to delete from hash table
645645
*
646646
* Removes mac address from the internal hash table
647647
*
648648
*/
649-
static int hash_del(struct emac_priv *priv, u8 *mac_addr)
649+
static int emac_hash_del(struct emac_priv *priv, u8 *mac_addr)
650650
{
651651
u32 hash_value;
652652
u32 hash_bit;
@@ -696,10 +696,10 @@ static void emac_add_mcast(struct emac_priv *priv, u32 action, u8 *mac_addr)
696696

697697
switch (action) {
698698
case EMAC_MULTICAST_ADD:
699-
update = hash_add(priv, mac_addr);
699+
update = emac_hash_add(priv, mac_addr);
700700
break;
701701
case EMAC_MULTICAST_DEL:
702-
update = hash_del(priv, mac_addr);
702+
update = emac_hash_del(priv, mac_addr);
703703
break;
704704
case EMAC_ALL_MULTI_SET:
705705
update = 1;

include/linux/netdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <uapi/linux/netdevice.h>
5353
#include <uapi/linux/if_bonding.h>
5454
#include <uapi/linux/pkt_cls.h>
55+
#include <linux/hashtable.h>
5556

5657
struct netpoll_info;
5758
struct device;
@@ -1800,6 +1801,9 @@ struct net_device {
18001801
unsigned int num_tx_queues;
18011802
unsigned int real_num_tx_queues;
18021803
struct Qdisc *qdisc;
1804+
#ifdef CONFIG_NET_SCHED
1805+
DECLARE_HASHTABLE (qdisc_hash, 4);
1806+
#endif
18031807
unsigned long tx_queue_len;
18041808
spinlock_t tx_global_lock;
18051809
int watchdog_timeo;

include/net/pkt_sched.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ int unregister_qdisc(struct Qdisc_ops *qops);
9090
void qdisc_get_default(char *id, size_t len);
9191
int qdisc_set_default(const char *id);
9292

93-
void qdisc_list_add(struct Qdisc *q);
94-
void qdisc_list_del(struct Qdisc *q);
93+
void qdisc_hash_add(struct Qdisc *q);
94+
void qdisc_hash_del(struct Qdisc *q);
9595
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
9696
struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
9797
struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,

include/net/sch_generic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct Qdisc {
6161
u32 limit;
6262
const struct Qdisc_ops *ops;
6363
struct qdisc_size_table __rcu *stab;
64-
struct list_head list;
64+
struct hlist_node hash;
6565
u32 handle;
6666
u32 parent;
6767
void *u32_node;

net/core/dev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7629,6 +7629,9 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
76297629
INIT_LIST_HEAD(&dev->all_adj_list.lower);
76307630
INIT_LIST_HEAD(&dev->ptype_all);
76317631
INIT_LIST_HEAD(&dev->ptype_specific);
7632+
#ifdef CONFIG_NET_SCHED
7633+
hash_init(dev->qdisc_hash);
7634+
#endif
76327635
dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
76337636
setup(dev);
76347637

net/ipv6/ip6_gre.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ static bool log_ecn_error = true;
6161
module_param(log_ecn_error, bool, 0644);
6262
MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
6363

64-
#define HASH_SIZE_SHIFT 5
65-
#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
64+
#define IP6_GRE_HASH_SIZE_SHIFT 5
65+
#define IP6_GRE_HASH_SIZE (1 << IP6_GRE_HASH_SIZE_SHIFT)
6666

6767
static int ip6gre_net_id __read_mostly;
6868
struct ip6gre_net {
69-
struct ip6_tnl __rcu *tunnels[4][HASH_SIZE];
69+
struct ip6_tnl __rcu *tunnels[4][IP6_GRE_HASH_SIZE];
7070

7171
struct net_device *fb_tunnel_dev;
7272
};
@@ -96,12 +96,12 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu);
9696
will match fallback tunnel.
9797
*/
9898

99-
#define HASH_KEY(key) (((__force u32)key^((__force u32)key>>4))&(HASH_SIZE - 1))
99+
#define HASH_KEY(key) (((__force u32)key^((__force u32)key>>4))&(IP6_GRE_HASH_SIZE - 1))
100100
static u32 HASH_ADDR(const struct in6_addr *addr)
101101
{
102102
u32 hash = ipv6_addr_hash(addr);
103103

104-
return hash_32(hash, HASH_SIZE_SHIFT);
104+
return hash_32(hash, IP6_GRE_HASH_SIZE_SHIFT);
105105
}
106106

107107
#define tunnels_r_l tunnels[3]
@@ -1089,7 +1089,7 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
10891089

10901090
for (prio = 0; prio < 4; prio++) {
10911091
int h;
1092-
for (h = 0; h < HASH_SIZE; h++) {
1092+
for (h = 0; h < IP6_GRE_HASH_SIZE; h++) {
10931093
struct ip6_tnl *t;
10941094

10951095
t = rtnl_dereference(ign->tunnels[prio][h]);

net/ipv6/ip6_tunnel.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ MODULE_LICENSE("GPL");
6464
MODULE_ALIAS_RTNL_LINK("ip6tnl");
6565
MODULE_ALIAS_NETDEV("ip6tnl0");
6666

67-
#define HASH_SIZE_SHIFT 5
68-
#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
67+
#define IP6_TUNNEL_HASH_SIZE_SHIFT 5
68+
#define IP6_TUNNEL_HASH_SIZE (1 << IP6_TUNNEL_HASH_SIZE_SHIFT)
6969

7070
static bool log_ecn_error = true;
7171
module_param(log_ecn_error, bool, 0644);
@@ -75,7 +75,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
7575
{
7676
u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
7777

78-
return hash_32(hash, HASH_SIZE_SHIFT);
78+
return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
7979
}
8080

8181
static int ip6_tnl_dev_init(struct net_device *dev);
@@ -87,7 +87,7 @@ struct ip6_tnl_net {
8787
/* the IPv6 tunnel fallback device */
8888
struct net_device *fb_tnl_dev;
8989
/* lists for storing tunnels in use */
90-
struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE];
90+
struct ip6_tnl __rcu *tnls_r_l[IP6_TUNNEL_HASH_SIZE];
9191
struct ip6_tnl __rcu *tnls_wc[1];
9292
struct ip6_tnl __rcu **tnls[2];
9393
};
@@ -2031,7 +2031,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct net *net)
20312031
if (dev->rtnl_link_ops == &ip6_link_ops)
20322032
unregister_netdevice_queue(dev, &list);
20332033

2034-
for (h = 0; h < HASH_SIZE; h++) {
2034+
for (h = 0; h < IP6_TUNNEL_HASH_SIZE; h++) {
20352035
t = rtnl_dereference(ip6n->tnls_r_l[h]);
20362036
while (t) {
20372037
/* If dev is in the same netns, it has already

net/ipv6/ip6_vti.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@
5050
#include <net/net_namespace.h>
5151
#include <net/netns/generic.h>
5252

53-
#define HASH_SIZE_SHIFT 5
54-
#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
53+
#define IP6_VTI_HASH_SIZE_SHIFT 5
54+
#define IP6_VTI_HASH_SIZE (1 << IP6_VTI_HASH_SIZE_SHIFT)
5555

5656
static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
5757
{
5858
u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
5959

60-
return hash_32(hash, HASH_SIZE_SHIFT);
60+
return hash_32(hash, IP6_VTI_HASH_SIZE_SHIFT);
6161
}
6262

6363
static int vti6_dev_init(struct net_device *dev);
@@ -69,7 +69,7 @@ struct vti6_net {
6969
/* the vti6 tunnel fallback device */
7070
struct net_device *fb_tnl_dev;
7171
/* lists for storing tunnels in use */
72-
struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE];
72+
struct ip6_tnl __rcu *tnls_r_l[IP6_VTI_HASH_SIZE];
7373
struct ip6_tnl __rcu *tnls_wc[1];
7474
struct ip6_tnl __rcu **tnls[2];
7575
};
@@ -1040,7 +1040,7 @@ static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n)
10401040
struct ip6_tnl *t;
10411041
LIST_HEAD(list);
10421042

1043-
for (h = 0; h < HASH_SIZE; h++) {
1043+
for (h = 0; h < IP6_VTI_HASH_SIZE; h++) {
10441044
t = rtnl_dereference(ip6n->tnls_r_l[h]);
10451045
while (t) {
10461046
unregister_netdevice_queue(t->dev, &list);

net/ipv6/sit.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
For comments look at net/ipv4/ip_gre.c --ANK
6363
*/
6464

65-
#define HASH_SIZE 16
65+
#define IP6_SIT_HASH_SIZE 16
6666
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
6767

6868
static bool log_ecn_error = true;
@@ -78,9 +78,9 @@ static struct rtnl_link_ops sit_link_ops __read_mostly;
7878

7979
static int sit_net_id __read_mostly;
8080
struct sit_net {
81-
struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE];
82-
struct ip_tunnel __rcu *tunnels_r[HASH_SIZE];
83-
struct ip_tunnel __rcu *tunnels_l[HASH_SIZE];
81+
struct ip_tunnel __rcu *tunnels_r_l[IP6_SIT_HASH_SIZE];
82+
struct ip_tunnel __rcu *tunnels_r[IP6_SIT_HASH_SIZE];
83+
struct ip_tunnel __rcu *tunnels_l[IP6_SIT_HASH_SIZE];
8484
struct ip_tunnel __rcu *tunnels_wc[1];
8585
struct ip_tunnel __rcu **tunnels[4];
8686

@@ -1783,7 +1783,7 @@ static void __net_exit sit_destroy_tunnels(struct net *net,
17831783

17841784
for (prio = 1; prio < 4; prio++) {
17851785
int h;
1786-
for (h = 0; h < HASH_SIZE; h++) {
1786+
for (h = 0; h < IP6_SIT_HASH_SIZE; h++) {
17871787
struct ip_tunnel *t;
17881788

17891789
t = rtnl_dereference(sitn->tunnels[prio][h]);

net/sched/sch_api.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/hrtimer.h>
3030
#include <linux/lockdep.h>
3131
#include <linux/slab.h>
32+
#include <linux/hashtable.h>
3233

3334
#include <net/net_namespace.h>
3435
#include <net/sock.h>
@@ -263,33 +264,33 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
263264
root->handle == handle)
264265
return root;
265266

266-
list_for_each_entry_rcu(q, &root->list, list) {
267+
hash_for_each_possible_rcu(qdisc_dev(root)->qdisc_hash, q, hash, handle) {
267268
if (q->handle == handle)
268269
return q;
269270
}
270271
return NULL;
271272
}
272273

273-
void qdisc_list_add(struct Qdisc *q)
274+
void qdisc_hash_add(struct Qdisc *q)
274275
{
275276
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
276277
struct Qdisc *root = qdisc_dev(q)->qdisc;
277278

278279
WARN_ON_ONCE(root == &noop_qdisc);
279280
ASSERT_RTNL();
280-
list_add_tail_rcu(&q->list, &root->list);
281+
hash_add_rcu(qdisc_dev(q)->qdisc_hash, &q->hash, q->handle);
281282
}
282283
}
283-
EXPORT_SYMBOL(qdisc_list_add);
284+
EXPORT_SYMBOL(qdisc_hash_add);
284285

285-
void qdisc_list_del(struct Qdisc *q)
286+
void qdisc_hash_del(struct Qdisc *q)
286287
{
287288
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
288289
ASSERT_RTNL();
289-
list_del_rcu(&q->list);
290+
hash_del_rcu(&q->hash);
290291
}
291292
}
292-
EXPORT_SYMBOL(qdisc_list_del);
293+
EXPORT_SYMBOL(qdisc_hash_del);
293294

294295
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
295296
{
@@ -998,7 +999,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
998999
goto err_out4;
9991000
}
10001001

1001-
qdisc_list_add(sch);
1002+
qdisc_hash_add(sch);
10021003

10031004
return sch;
10041005
}
@@ -1435,6 +1436,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
14351436
{
14361437
int ret = 0, q_idx = *q_idx_p;
14371438
struct Qdisc *q;
1439+
int b;
14381440

14391441
if (!root)
14401442
return 0;
@@ -1449,7 +1451,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
14491451
goto done;
14501452
q_idx++;
14511453
}
1452-
list_for_each_entry(q, &root->list, list) {
1454+
hash_for_each(qdisc_dev(root)->qdisc_hash, b, q, hash) {
14531455
if (q_idx < s_q_idx) {
14541456
q_idx++;
14551457
continue;
@@ -1765,14 +1767,15 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
17651767
int *t_p, int s_t)
17661768
{
17671769
struct Qdisc *q;
1770+
int b;
17681771

17691772
if (!root)
17701773
return 0;
17711774

17721775
if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0)
17731776
return -1;
17741777

1775-
list_for_each_entry(q, &root->list, list) {
1778+
hash_for_each(qdisc_dev(root)->qdisc_hash, b, q, hash) {
17761779
if (tc_dump_tclass_qdisc(q, skb, tcm, cb, t_p, s_t) < 0)
17771780
return -1;
17781781
}

0 commit comments

Comments
 (0)