diff options
author | Jesse Gross <jesse@nicira.com> | 2015-01-02 21:26:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-04 22:21:33 -0500 |
commit | df5dba8e52be50e615e03ef73b34611d82587f42 (patch) | |
tree | e74e1098ddf8f923670a44f67799863794259416 /net | |
parent | 829a3ada9cc7d4c30fa61f8033403fb6c8f8092a (diff) |
geneve: Remove socket hash table.
The hash table for open Geneve ports is used only on creation and
deletion time. It is not performance critical and is not likely to
grow to a large number of items. Therefore, this can be changed
to use a simple linked list.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/geneve.c | 26 |
1 files changed, 7 insertions, 19 deletions
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index ad8dbae11d01..4fe5a592821c 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/if_ether.h> | 27 | #include <linux/if_ether.h> |
28 | #include <linux/if_vlan.h> | 28 | #include <linux/if_vlan.h> |
29 | #include <linux/hash.h> | ||
30 | #include <linux/ethtool.h> | 29 | #include <linux/ethtool.h> |
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | #include <net/arp.h> | 31 | #include <net/arp.h> |
@@ -54,12 +53,9 @@ | |||
54 | /* Protects sock_list and refcounts. */ | 53 | /* Protects sock_list and refcounts. */ |
55 | static DEFINE_MUTEX(geneve_mutex); | 54 | static DEFINE_MUTEX(geneve_mutex); |
56 | 55 | ||
57 | #define PORT_HASH_BITS 8 | ||
58 | #define PORT_HASH_SIZE (1<<PORT_HASH_BITS) | ||
59 | |||
60 | /* per-network namespace private data for this module */ | 56 | /* per-network namespace private data for this module */ |
61 | struct geneve_net { | 57 | struct geneve_net { |
62 | struct hlist_head sock_list[PORT_HASH_SIZE]; | 58 | struct list_head sock_list; |
63 | }; | 59 | }; |
64 | 60 | ||
65 | static int geneve_net_id; | 61 | static int geneve_net_id; |
@@ -69,19 +65,13 @@ static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb) | |||
69 | return (struct genevehdr *)(udp_hdr(skb) + 1); | 65 | return (struct genevehdr *)(udp_hdr(skb) + 1); |
70 | } | 66 | } |
71 | 67 | ||
72 | static struct hlist_head *gs_head(struct net *net, __be16 port) | ||
73 | { | ||
74 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
75 | |||
76 | return &gn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)]; | ||
77 | } | ||
78 | |||
79 | /* Find geneve socket based on network namespace and UDP port */ | 68 | /* Find geneve socket based on network namespace and UDP port */ |
80 | static struct geneve_sock *geneve_find_sock(struct net *net, __be16 port) | 69 | static struct geneve_sock *geneve_find_sock(struct net *net, __be16 port) |
81 | { | 70 | { |
71 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
82 | struct geneve_sock *gs; | 72 | struct geneve_sock *gs; |
83 | 73 | ||
84 | hlist_for_each_entry(gs, gs_head(net, port), hlist) { | 74 | list_for_each_entry(gs, &gn->sock_list, list) { |
85 | if (inet_sk(gs->sock->sk)->inet_sport == port) | 75 | if (inet_sk(gs->sock->sk)->inet_sport == port) |
86 | return gs; | 76 | return gs; |
87 | } | 77 | } |
@@ -339,6 +329,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, | |||
339 | geneve_rcv_t *rcv, void *data, | 329 | geneve_rcv_t *rcv, void *data, |
340 | bool ipv6) | 330 | bool ipv6) |
341 | { | 331 | { |
332 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
342 | struct geneve_sock *gs; | 333 | struct geneve_sock *gs; |
343 | struct socket *sock; | 334 | struct socket *sock; |
344 | struct udp_tunnel_sock_cfg tunnel_cfg; | 335 | struct udp_tunnel_sock_cfg tunnel_cfg; |
@@ -371,7 +362,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, | |||
371 | tunnel_cfg.encap_destroy = NULL; | 362 | tunnel_cfg.encap_destroy = NULL; |
372 | setup_udp_tunnel_sock(net, sock, &tunnel_cfg); | 363 | setup_udp_tunnel_sock(net, sock, &tunnel_cfg); |
373 | 364 | ||
374 | hlist_add_head(&gs->hlist, gs_head(net, port)); | 365 | list_add(&gs->list, &gn->sock_list); |
375 | 366 | ||
376 | return gs; | 367 | return gs; |
377 | } | 368 | } |
@@ -407,7 +398,7 @@ void geneve_sock_release(struct geneve_sock *gs) | |||
407 | if (--gs->refcnt) | 398 | if (--gs->refcnt) |
408 | goto unlock; | 399 | goto unlock; |
409 | 400 | ||
410 | hlist_del(&gs->hlist); | 401 | list_del(&gs->list); |
411 | geneve_notify_del_rx_port(gs); | 402 | geneve_notify_del_rx_port(gs); |
412 | udp_tunnel_sock_release(gs->sock); | 403 | udp_tunnel_sock_release(gs->sock); |
413 | kfree_rcu(gs, rcu); | 404 | kfree_rcu(gs, rcu); |
@@ -420,17 +411,14 @@ EXPORT_SYMBOL_GPL(geneve_sock_release); | |||
420 | static __net_init int geneve_init_net(struct net *net) | 411 | static __net_init int geneve_init_net(struct net *net) |
421 | { | 412 | { |
422 | struct geneve_net *gn = net_generic(net, geneve_net_id); | 413 | struct geneve_net *gn = net_generic(net, geneve_net_id); |
423 | unsigned int h; | ||
424 | 414 | ||
425 | for (h = 0; h < PORT_HASH_SIZE; ++h) | 415 | INIT_LIST_HEAD(&gn->sock_list); |
426 | INIT_HLIST_HEAD(&gn->sock_list[h]); | ||
427 | 416 | ||
428 | return 0; | 417 | return 0; |
429 | } | 418 | } |
430 | 419 | ||
431 | static struct pernet_operations geneve_net_ops = { | 420 | static struct pernet_operations geneve_net_ops = { |
432 | .init = geneve_init_net, | 421 | .init = geneve_init_net, |
433 | .exit = NULL, | ||
434 | .id = &geneve_net_id, | 422 | .id = &geneve_net_id, |
435 | .size = sizeof(struct geneve_net), | 423 | .size = sizeof(struct geneve_net), |
436 | }; | 424 | }; |