aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_input.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-06-21 09:58:31 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-22 20:11:13 -0400
commit6648bd7e0e62c0c8c03b15e00c9e7015e232feff (patch)
treee5e1fdadea6ea51b4341017c40906e71c1913774 /net/ipv4/ip_input.c
parent8e27628ecf883b9e5825103e40e6f86bf8225f1a (diff)
ipv4: Add sysctl knob to control early socket demux
This change is meant to add a control for disabling early socket demux. The main motivation behind this patch is to provide an option to disable the feature as it adds an additional cost to routing that reduces overall throughput by up to 5%. For example one of my systems went from 12.1Mpps to 11.6 after the early socket demux was added. It looks like the reason for the regression is that we are now having to perform two lookups, first the one for an established socket, and then the one for the routing table. By adding this patch and toggling the value for ip_early_demux to 0 I am able to get back to the 12.1Mpps I was previously seeing. [ Move local variables in ip_rcv_finish() down into the basic block in which they are actually used. -DaveM ] Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_input.c')
-rw-r--r--net/ipv4/ip_input.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 93b092c9a394..bca25179cdb9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -313,6 +313,8 @@ drop:
313 return true; 313 return true;
314} 314}
315 315
316int sysctl_ip_early_demux __read_mostly = 1;
317
316static int ip_rcv_finish(struct sk_buff *skb) 318static int ip_rcv_finish(struct sk_buff *skb)
317{ 319{
318 const struct iphdr *iph = ip_hdr(skb); 320 const struct iphdr *iph = ip_hdr(skb);
@@ -323,16 +325,18 @@ static int ip_rcv_finish(struct sk_buff *skb)
323 * how the packet travels inside Linux networking. 325 * how the packet travels inside Linux networking.
324 */ 326 */
325 if (skb_dst(skb) == NULL) { 327 if (skb_dst(skb) == NULL) {
326 const struct net_protocol *ipprot; 328 int err = -ENOENT;
327 int protocol = iph->protocol;
328 int err;
329 329
330 rcu_read_lock(); 330 if (sysctl_ip_early_demux) {
331 ipprot = rcu_dereference(inet_protos[protocol]); 331 const struct net_protocol *ipprot;
332 err = -ENOENT; 332 int protocol = iph->protocol;
333 if (ipprot && ipprot->early_demux) 333
334 err = ipprot->early_demux(skb); 334 rcu_read_lock();
335 rcu_read_unlock(); 335 ipprot = rcu_dereference(inet_protos[protocol]);
336 if (ipprot && ipprot->early_demux)
337 err = ipprot->early_demux(skb);
338 rcu_read_unlock();
339 }
336 340
337 if (err) { 341 if (err) {
338 err = ip_route_input_noref(skb, iph->daddr, iph->saddr, 342 err = ip_route_input_noref(skb, iph->daddr, iph->saddr,