Module Name: src Committed By: martin Date: Wed Oct 3 17:53:56 UTC 2018
Modified Files: src/sys/netinet [netbsd-8]: ip_reass.c Log Message: Pull up following revision(s) (requested by maxv in ticket #1045): sys/netinet/ip_reass.c: revision 1.19 Hold ip_off and ip_len in the fragment entry, instead of always reading the associated mbuf (and converting to host order). This reduces the cache/TLB misses when processing long lists. To generate a diff of this commit: cvs rdiff -u -r1.11.8.4 -r1.11.8.5 src/sys/netinet/ip_reass.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_reass.c diff -u src/sys/netinet/ip_reass.c:1.11.8.4 src/sys/netinet/ip_reass.c:1.11.8.5 --- src/sys/netinet/ip_reass.c:1.11.8.4 Thu Sep 27 15:07:34 2018 +++ src/sys/netinet/ip_reass.c Wed Oct 3 17:53:56 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_reass.c,v 1.11.8.4 2018/09/27 15:07:34 martin Exp $ */ +/* $NetBSD: ip_reass.c,v 1.11.8.5 2018/10/03 17:53:56 martin Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1993 @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_reass.c,v 1.11.8.4 2018/09/27 15:07:34 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_reass.c,v 1.11.8.5 2018/10/03 17:53:56 martin Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -80,6 +80,8 @@ typedef struct ipfr_qent { struct ip * ipqe_ip; struct mbuf * ipqe_m; bool ipqe_mff; + uint16_t ipqe_off; + uint16_t ipqe_len; } ipfr_qent_t; TAILQ_HEAD(ipfr_qent_head, ipfr_qent); @@ -215,7 +217,7 @@ ip_nmbclusters_changed(void) struct mbuf * ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t *fp, const u_int hash) { - struct ip *ip = ipqe->ipqe_ip, *qip; + struct ip *ip = ipqe->ipqe_ip; const int hlen = ip->ip_hl << 2; struct mbuf *m = ipqe->ipqe_m, *t; int ipsecflags = m->m_flags & (M_DECRYPTED|M_AUTHIPHDR); @@ -230,16 +232,6 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t m->m_data += hlen; m->m_len -= hlen; -#ifdef notyet - /* Make sure fragment limit is up-to-date. */ - CHECK_NMBCLUSTER_PARAMS(); - - /* If we have too many fragments, drop the older half. */ - if (ip_nfrags >= ip_maxfrags) { - ip_reass_drophalf(void); - } -#endif - /* * We are about to add a fragment; increment frag count. */ @@ -255,9 +247,9 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t * never accept fragments b) if maxfrag is -1, accept * all fragments without limitation. */ - if (ip_maxfragpackets < 0) - ; - else if (ip_nfragpackets >= ip_maxfragpackets) { + if (ip_maxfragpackets < 0) { + /* no limit */ + } else if (ip_nfragpackets >= ip_maxfragpackets) { goto dropfrag; } fp = malloc(sizeof(ipfr_queue_t), M_FTABLE, M_NOWAIT); @@ -285,7 +277,7 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t * Find a segment which begins after this one does. */ TAILQ_FOREACH(q, &fp->ipq_fragq, ipqe_q) { - if (ntohs(q->ipqe_ip->ip_off) > ntohs(ip->ip_off)) + if (q->ipqe_off > ipqe->ipqe_off) break; } if (q != NULL) { @@ -300,15 +292,14 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t * If it provides all of our data, drop us. */ if (p != NULL) { - i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) - - ntohs(ip->ip_off); + i = p->ipqe_off + p->ipqe_len - ipqe->ipqe_off; if (i > 0) { - if (i >= ntohs(ip->ip_len)) { + if (i >= ipqe->ipqe_len) { goto dropfrag; } m_adj(ipqe->ipqe_m, i); - ip->ip_off = htons(ntohs(ip->ip_off) + i); - ip->ip_len = htons(ntohs(ip->ip_len) - i); + ipqe->ipqe_off = ipqe->ipqe_off + i; + ipqe->ipqe_len = ipqe->ipqe_len - i; } } @@ -317,17 +308,13 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t * completely covered, dequeue them. */ while (q != NULL) { - size_t end; - - qip = q->ipqe_ip; - end = ntohs(ip->ip_off) + ntohs(ip->ip_len); - if (end <= ntohs(qip->ip_off)) { + i = ipqe->ipqe_off + ipqe->ipqe_len - q->ipqe_off; + if (i <= 0) { break; } - i = end - ntohs(qip->ip_off); - if (i < ntohs(qip->ip_len)) { - qip->ip_len = htons(ntohs(qip->ip_len) - i); - qip->ip_off = htons(ntohs(qip->ip_off) + i); + if (i < q->ipqe_len) { + q->ipqe_off = q->ipqe_off + i; + q->ipqe_len = q->ipqe_len - i; m_adj(q->ipqe_m, i); break; } @@ -351,12 +338,11 @@ insert: } next = 0; TAILQ_FOREACH(q, &fp->ipq_fragq, ipqe_q) { - qip = q->ipqe_ip; - if (ntohs(qip->ip_off) != next) { + if (q->ipqe_off != next) { mutex_exit(&ipfr_lock); return NULL; } - next += ntohs(qip->ip_len); + next += q->ipqe_len; } p = TAILQ_LAST(&fp->ipq_fragq, ipfr_qent_head); if (p->ipqe_mff) { @@ -651,13 +637,6 @@ ip_reass_packet(struct mbuf **m0, struct return EINVAL; } - /* - * Adjust total IP length to not reflect header and convert - * offset of this to bytes. XXX: clobbers struct ip. - */ - ip->ip_len = htons(flen); - ip->ip_off = htons(off); - /* Look for queue of fragments of this datagram. */ mutex_enter(&ipfr_lock); hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); @@ -702,6 +681,8 @@ ip_reass_packet(struct mbuf **m0, struct ipqe->ipqe_mff = mff; ipqe->ipqe_m = m; ipqe->ipqe_ip = ip; + ipqe->ipqe_off = off; + ipqe->ipqe_len = flen; *m0 = ip_reass(ipqe, fp, hash); if (*m0) {