MFp4 bz_ipv6_fast:

Optimize in6_cksum(), re-ordering work and limiting variable
  initialization, removing a bzero() for mostly re-initialized
  struct values, making use of the newly introduced in6_getscope(),
  as well as converting an if/panic to a KASSERT().

  Sponsored by:	The FreeBSD Foundation
  Sponsored by:	iXsystems

Reviewed by:	gnn (as part of the whole)
MFC After:	3 days
This commit is contained in:
Bjoern A. Zeeb 2012-05-24 18:05:10 +00:00
parent e9651b7649
commit 2889eb8bdf

View File

@ -89,12 +89,10 @@ __FBSDID("$FreeBSD$");
int
in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
{
u_int16_t *w;
int sum = 0;
int mlen = 0;
int byte_swapped = 0;
struct ip6_hdr *ip6;
struct in6_addr in6;
u_int16_t *w, scope;
int byte_swapped, mlen;
int sum;
union {
u_int16_t phs[4];
struct {
@ -112,43 +110,39 @@ in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
u_int32_t l;
} l_util;
/* sanity check */
if (m->m_pkthdr.len < off + len) {
panic("in6_cksum: mbuf len (%d) < off+len (%d+%d)",
m->m_pkthdr.len, off, len);
}
bzero(&uph, sizeof(uph));
/* Sanity check. */
KASSERT(m->m_pkthdr.len >= off + len, ("%s: mbuf len (%d) < off(%d)+"
"len(%d)", __func__, m->m_pkthdr.len, off, len));
/*
* First create IP6 pseudo header and calculate a summary.
*/
ip6 = mtod(m, struct ip6_hdr *);
uph.ph.ph_len = htonl(len);
uph.ph.ph_zero[0] = uph.ph.ph_zero[1] = uph.ph.ph_zero[2] = 0;
uph.ph.ph_nxt = nxt;
/*
* IPv6 source address.
* XXX: we'd like to avoid copying the address, but we can't due to
* the possibly embedded scope zone ID.
*/
in6 = ip6->ip6_src;
in6_clearscope(&in6);
w = (u_int16_t *)&in6;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
/* IPv6 destination address */
in6 = ip6->ip6_dst;
in6_clearscope(&in6);
w = (u_int16_t *)&in6;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
/* Payload length and upper layer identifier */
sum += uph.phs[0]; sum += uph.phs[1];
/* Payload length and upper layer identifier. */
sum = uph.phs[0]; sum += uph.phs[1];
sum += uph.phs[2]; sum += uph.phs[3];
ip6 = mtod(m, struct ip6_hdr *);
/* IPv6 source address. */
scope = in6_getscope(&ip6->ip6_src);
w = (u_int16_t *)&ip6->ip6_src;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
if (scope != 0)
sum -= scope;
/* IPv6 destination address. */
scope = in6_getscope(&ip6->ip6_dst);
w = (u_int16_t *)&ip6->ip6_dst;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
if (scope != 0)
sum -= scope;
/*
* Secondly calculate a summary of the first mbuf excluding offset.
*/
@ -167,14 +161,16 @@ in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
/*
* Force to even boundary.
*/
if ((1 & (long) w) && (mlen > 0)) {
if ((1 & (long)w) && (mlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(u_char *)w;
w = (u_int16_t *)((char *)w + 1);
mlen--;
byte_swapped = 1;
}
} else
byte_swapped = 0;
/*
* Unroll the loop to make overhead from
* branches &c small.