Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v retrieving revision 1.285 retrieving revision 1.286 diff -u -p -r1.285 -r1.286 --- src/sys/netinet/ip_input.c 2010/03/31 07:31:15 1.285 +++ src/sys/netinet/ip_input.c 2010/04/01 01:23:32 1.286 @@ -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 -__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 @@ u_long in_multihash; /* size of hash 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 @@ ipintr(void) { 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); }