aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2012-04-11 19:05:28 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-13 13:39:37 -0400
commit447167bf565a474ff0cfb0f41d54936937479e97 (patch)
tree38b03cb4e23bec19939545575e36f7395c5b156e /net/ipv4/udp.c
parent77577bf93275b485cecb4f358a085949c32e9dcd (diff)
udp: intoduce udp_encap_needed static_key
Most machines dont use UDP encapsulation (L2TP) Adds a static_key so that udp_queue_rcv_skb() doesnt have to perform a test if L2TP never setup the encap_rcv on a socket. Idea of this patch came after Simon Horman proposal to add a hook on TCP as well. If static_key is not yet enabled, the fast path does a single JMP . When static_key is enabled, JMP destination is patched to reach the real encap_type/encap_rcv logic, possibly adding cache misses. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Simon Horman <horms@verge.net.au> Cc: dev@openvswitch.org Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index fe141052a1be..ad1e0dd4da48 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -107,6 +107,7 @@
107#include <net/checksum.h> 107#include <net/checksum.h>
108#include <net/xfrm.h> 108#include <net/xfrm.h>
109#include <trace/events/udp.h> 109#include <trace/events/udp.h>
110#include <linux/static_key.h>
110#include "udp_impl.h" 111#include "udp_impl.h"
111 112
112struct udp_table udp_table __read_mostly; 113struct udp_table udp_table __read_mostly;
@@ -1379,6 +1380,14 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1379 1380
1380} 1381}
1381 1382
1383static struct static_key udp_encap_needed __read_mostly;
1384void udp_encap_enable(void)
1385{
1386 if (!static_key_enabled(&udp_encap_needed))
1387 static_key_slow_inc(&udp_encap_needed);
1388}
1389EXPORT_SYMBOL(udp_encap_enable);
1390
1382/* returns: 1391/* returns:
1383 * -1: error 1392 * -1: error
1384 * 0: success 1393 * 0: success
@@ -1400,7 +1409,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1400 goto drop; 1409 goto drop;
1401 nf_reset(skb); 1410 nf_reset(skb);
1402 1411
1403 if (up->encap_type) { 1412 if (static_key_false(&udp_encap_needed) && up->encap_type) {
1404 int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); 1413 int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
1405 1414
1406 /* 1415 /*
@@ -1760,6 +1769,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1760 /* FALLTHROUGH */ 1769 /* FALLTHROUGH */
1761 case UDP_ENCAP_L2TPINUDP: 1770 case UDP_ENCAP_L2TPINUDP:
1762 up->encap_type = val; 1771 up->encap_type = val;
1772 udp_encap_enable();
1763 break; 1773 break;
1764 default: 1774 default:
1765 err = -ENOPROTOOPT; 1775 err = -ENOPROTOOPT;