Module Name: src Committed By: tls Date: Thu Apr 1 01:23:32 UTC 2010
Modified Files: src/sys/netinet: ip_input.c Log Message: As suggested by at least 3 different people (the guilty parties know who they are) avoid repeated kernel_lock/unlock by using an intrq on the stack. About 5%-10% better from run to run, on my *very* simpleminded test. Can't possibly be worse. To generate a diff of this commit: cvs rdiff -u -r1.285 -r1.286 src/sys/netinet/ip_input.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/ip_input.c diff -u src/sys/netinet/ip_input.c:1.285 src/sys/netinet/ip_input.c:1.286 --- src/sys/netinet/ip_input.c:1.285 Wed Mar 31 07:31:15 2010 +++ src/sys/netinet/ip_input.c Thu Apr 1 01:23:32 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.285 2010/03/31 07:31:15 tls Exp $ */ +/* $NetBSD: ip_input.c,v 1.286 2010/04/01 01:23:32 tls Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.285 2010/03/31 07:31:15 tls Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.286 2010/04/01 01:23:32 tls Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -231,6 +231,7 @@ int in_multientries; /* total number of addrs */ struct in_multihashhead *in_multihashtbl; struct ifqueue ipintrq; + uint16_t ip_id; percpu_t *ipstat_percpu; @@ -474,20 +475,35 @@ { int s; struct mbuf *m; + struct ifqueue lcl_intrq; + + memset(&lcl_intrq, 0, sizeof(lcl_intrq)); + ipintrq.ifq_maxlen = ipqmaxlen; mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); - while (!IF_IS_EMPTY(&ipintrq)) { + if (!IF_IS_EMPTY(&ipintrq)) { s = splnet(); - IF_DEQUEUE(&ipintrq, m); + + /* Take existing queue onto stack */ + lcl_intrq = ipintrq; + + /* Zero out global queue, preserving maxlen and drops */ + ipintrq.ifq_head = NULL; + ipintrq.ifq_tail = NULL; + ipintrq.ifq_len = 0; + ipintrq.ifq_maxlen = lcl_intrq.ifq_maxlen; + ipintrq.ifq_drops = lcl_intrq.ifq_drops; + splx(s); + } + KERNEL_UNLOCK_ONE(NULL); + while (!IF_IS_EMPTY(&lcl_intrq)) { + IF_DEQUEUE(&lcl_intrq, m); if (m == NULL) break; - KERNEL_UNLOCK_ONE(NULL); ip_input(m); - KERNEL_LOCK(1, NULL); } - KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); }