If source mbuf chain consists of only one mbuf, use it directly as source

buffer to avoid extra copying.
This commit is contained in:
Alexander Motin 2009-01-18 21:09:34 +00:00
parent 129c5c814d
commit 67898a2385

@ -489,22 +489,29 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
if ((d->cfg.bits & MPPC_BIT) != 0) { if ((d->cfg.bits & MPPC_BIT) != 0) {
u_short flags = MPPC_MANDATORY_COMPRESS_FLAGS; u_short flags = MPPC_MANDATORY_COMPRESS_FLAGS;
u_char *inbuf, *outbuf; u_char *inbuf, *outbuf;
int outlen, inlen; int outlen, inlen, ina;
u_char *source, *dest; u_char *source, *dest;
u_long sourceCnt, destCnt; u_long sourceCnt, destCnt;
int rtn; int rtn;
/* Work with contiguous regions of memory. */ /* Work with contiguous regions of memory. */
inlen = m->m_pkthdr.len; inlen = m->m_pkthdr.len;
inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT); if (m->m_next == NULL) {
if (inbuf == NULL) inbuf = mtod(m, u_char *);
goto err1; ina = 0;
m_copydata(m, 0, inlen, (caddr_t)inbuf); } else {
inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (inbuf == NULL)
goto err1;
m_copydata(m, 0, inlen, (caddr_t)inbuf);
ina = 1;
}
outlen = MPPC_MAX_BLOWUP(inlen); outlen = MPPC_MAX_BLOWUP(inlen);
outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT); outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (outbuf == NULL) { if (outbuf == NULL) {
free(inbuf, M_NETGRAPH_MPPC); if (ina)
free(inbuf, M_NETGRAPH_MPPC);
err1: err1:
m_freem(m); m_freem(m);
MPPC_InitCompressionHistory(d->history); MPPC_InitCompressionHistory(d->history);
@ -544,7 +551,8 @@ err1:
d->flushed = (rtn & MPPC_EXPANDED) != 0 d->flushed = (rtn & MPPC_EXPANDED) != 0
|| (flags & MPPC_SAVE_HISTORY) == 0; || (flags & MPPC_SAVE_HISTORY) == 0;
free(inbuf, M_NETGRAPH_MPPC); if (ina)
free(inbuf, M_NETGRAPH_MPPC);
free(outbuf, M_NETGRAPH_MPPC); free(outbuf, M_NETGRAPH_MPPC);
/* Check mbuf chain reload result. */ /* Check mbuf chain reload result. */
@ -731,36 +739,43 @@ failed:
/* Decompress packet */ /* Decompress packet */
if ((header & MPPC_FLAG_COMPRESSED) != 0) { if ((header & MPPC_FLAG_COMPRESSED) != 0) {
int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS; int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS;
u_char *decompbuf, *source, *dest; u_char *inbuf, *outbuf;
int inlen, outlen, ina;
u_char *source, *dest;
u_long sourceCnt, destCnt; u_long sourceCnt, destCnt;
int decomplen, rtn; int rtn;
u_char *buf;
int len;
/* Copy payload into a contiguous region of memory. */ /* Copy payload into a contiguous region of memory. */
len = m->m_pkthdr.len; inlen = m->m_pkthdr.len;
buf = malloc(len, M_NETGRAPH_MPPC, M_NOWAIT); if (m->m_next == NULL) {
if (buf == NULL) { inbuf = mtod(m, u_char *);
m_freem(m); ina = 0;
return (ENOMEM); } else {
inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (inbuf == NULL) {
m_freem(m);
return (ENOMEM);
}
m_copydata(m, 0, inlen, (caddr_t)inbuf);
ina = 1;
} }
m_copydata(m, 0, len, (caddr_t)buf);
/* Allocate a buffer for decompressed data */ /* Allocate a buffer for decompressed data */
decompbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY, outbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY,
M_NETGRAPH_MPPC, M_NOWAIT); M_NETGRAPH_MPPC, M_NOWAIT);
if (decompbuf == NULL) { if (outbuf == NULL) {
m_freem(m); m_freem(m);
free(buf, M_NETGRAPH_MPPC); if (ina)
free(inbuf, M_NETGRAPH_MPPC);
return (ENOMEM); return (ENOMEM);
} }
decomplen = MPPC_DECOMP_BUFSIZE; outlen = MPPC_DECOMP_BUFSIZE;
/* Prepare to decompress */ /* Prepare to decompress */
source = buf; source = inbuf;
sourceCnt = len; sourceCnt = inlen;
dest = decompbuf; dest = outbuf;
destCnt = decomplen; destCnt = outlen;
if ((header & MPPC_FLAG_RESTART) != 0) if ((header & MPPC_FLAG_RESTART) != 0)
flags |= MPPC_RESTART_HISTORY; flags |= MPPC_RESTART_HISTORY;
@ -774,22 +789,24 @@ failed:
|| (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) { || (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
log(LOG_ERR, "%s: decomp returned 0x%x", log(LOG_ERR, "%s: decomp returned 0x%x",
__func__, rtn); __func__, rtn);
free(buf, M_NETGRAPH_MPPC); if (ina)
free(decompbuf, M_NETGRAPH_MPPC); free(inbuf, M_NETGRAPH_MPPC);
free(outbuf, M_NETGRAPH_MPPC);
goto failed; goto failed;
} }
/* Replace compressed data with decompressed data */ /* Replace compressed data with decompressed data */
free(buf, M_NETGRAPH_MPPC); if (ina)
len = decomplen - destCnt; free(inbuf, M_NETGRAPH_MPPC);
outlen -= destCnt;
m_copyback(m, 0, len, (caddr_t)decompbuf); m_copyback(m, 0, outlen, (caddr_t)outbuf);
if (m->m_pkthdr.len < len) { if (m->m_pkthdr.len < outlen) {
m_freem(m); m_freem(m);
m = NULL; m = NULL;
} else if (len < m->m_pkthdr.len) } else if (outlen < m->m_pkthdr.len)
m_adj(m, len - m->m_pkthdr.len); m_adj(m, outlen - m->m_pkthdr.len);
free(decompbuf, M_NETGRAPH_MPPC); free(outbuf, M_NETGRAPH_MPPC);
} }
#endif #endif