Module Name: src
Committed By: drochner
Date: Wed Feb 16 19:08:58 UTC 2011
Modified Files:
src/sys/opencrypto: deflate.c deflate.h
Log Message:
-avoid allocation of an extra result buffer and data copy in case
the DEFLATE complssion/decompression result is within a single
buffer already
-simplify bookkeeping of allocated buffers (and don't waste the
last member of the metadata array)
from Wolfgang Stukenbrock per PR kern/36865 (with some cleanup
of error handling by me)
The Gzip compression case can be improved too, but for now I've applied
the buffer bookkeeping changes.
tested with IP4 IPCOMP
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/opencrypto/deflate.c
cvs rdiff -u -r1.6 -r1.7 src/sys/opencrypto/deflate.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/opencrypto/deflate.c
diff -u src/sys/opencrypto/deflate.c:1.14 src/sys/opencrypto/deflate.c:1.15
--- src/sys/opencrypto/deflate.c:1.14 Thu Feb 10 21:17:49 2011
+++ src/sys/opencrypto/deflate.c Wed Feb 16 19:08:57 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: deflate.c,v 1.14 2011/02/10 21:17:49 drochner Exp $ */
+/* $NetBSD: deflate.c,v 1.15 2011/02/16 19:08:57 drochner Exp $ */
/* $FreeBSD: src/sys/opencrypto/deflate.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: deflate.c,v 1.3 2001/08/20 02:45:22 hugh Exp $ */
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.14 2011/02/10 21:17:49 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.15 2011/02/16 19:08:57 drochner Exp $");
#include <sys/types.h>
#include <sys/malloc.h>
@@ -77,10 +77,10 @@
z_stream zbuf;
u_int8_t *output;
- u_int32_t count, result;
- int error, i = 0, j;
+ u_int32_t count, result, tocopy;
+ int error, i, j;
struct deflate_buf *buf, *tmp;
- size_t len, old_len;
+ size_t len;
DPRINTF(("deflate_global: size %d\n", size));
@@ -90,9 +90,6 @@
return 0;
memset(&zbuf, 0, sizeof(z_stream));
- for (j = 0; j < len; j++)
- buf[j].flag = 0;
-
zbuf.next_in = data; /* data that is going to be processed */
zbuf.zalloc = ocf_zalloc;
zbuf.zfree = ocf_zfree;
@@ -100,12 +97,7 @@
zbuf.avail_in = size; /* Total length of data to be processed */
if (!decomp) {
- buf[i].out = malloc(size, M_CRYPTO_DATA, M_NOWAIT);
- if (buf[i].out == NULL)
- goto bad;
- buf[i].size = size;
- buf[i].flag = 1;
- i++;
+ buf[0].size = size;
} else {
/*
* Choose a buffer with 4x the size of the input buffer
@@ -114,13 +106,12 @@
* updated while the decompression is going on
*/
- buf[i].size = size * 4;
- buf[i].out = malloc(buf[i].size, M_CRYPTO_DATA, M_NOWAIT);
- if (buf[i].out == NULL)
- goto bad;
- buf[i].flag = 1;
- i++;
+ buf[0].size = size * 4;
}
+ buf[0].out = malloc(buf[0].size, M_CRYPTO_DATA, M_NOWAIT);
+ if (buf[0].out == NULL)
+ goto bad3;
+ i = 1;
zbuf.next_out = buf[0].out;
zbuf.avail_out = buf[0].size;
@@ -130,7 +121,7 @@
window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY);
if (error != Z_OK)
- goto bad;
+ goto bad2;
for (;;) {
error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) :
deflate(&zbuf, Z_FINISH);
@@ -139,16 +130,13 @@
else if (zbuf.avail_in == 0 && zbuf.avail_out != 0)
goto end;
else if (zbuf.avail_out == 0) {
- if (i == (len-1)) {
- old_len = i;
+ if (i == len) {
len += ZBUF;
tmp = realloc(buf,len*sizeof(struct deflate_buf),
M_CRYPTO_DATA, M_NOWAIT);
if (tmp == NULL)
goto bad;
buf = tmp;
- for (j = old_len; j < len; j++)
- buf[j].flag = 0;
}
/* we need more output space, allocate size */
buf[i].out = malloc(size, M_CRYPTO_DATA, M_NOWAIT);
@@ -156,7 +144,6 @@
goto bad;
zbuf.next_out = buf[i].out;
buf[i].size = size;
- buf[i].flag = 1;
zbuf.avail_out = buf[i].size;
i++;
} else
@@ -166,41 +153,41 @@
end:
result = count = zbuf.total_out;
- *out = malloc(result, M_CRYPTO_DATA, M_NOWAIT);
- if (*out == NULL)
- goto bad;
- if (decomp)
- inflateEnd(&zbuf);
- else
- deflateEnd(&zbuf);
- output = *out;
- for (j = 0; buf[j].flag != 0; j++) {
- if (count > buf[j].size) {
- memcpy(*out, buf[j].out, buf[j].size);
- *out += buf[j].size;
- free(buf[j].out, M_CRYPTO_DATA);
- count -= buf[j].size;
- } else {
- /* it should be the last buffer */
- memcpy(*out, buf[j].out, count);
- *out += count;
+ if (i != 1) { /* copy everything into one buffer */
+ output = malloc(result, M_CRYPTO_DATA, M_NOWAIT);
+ if (output == NULL)
+ goto bad;
+ *out = output;
+ for (j = 0; j < i; j++) {
+ tocopy = MIN(count, buf[j].size);
+ /* XXX the last buf can be empty */
+ KASSERT(tocopy || j == (i - 1));
+ memcpy(output, buf[j].out, tocopy);
+ output += tocopy;
free(buf[j].out, M_CRYPTO_DATA);
- count = 0;
+ count -= tocopy;
}
+ KASSERT(count == 0);
+ } else {
+ *out = buf[0].out;
}
free(buf, M_CRYPTO_DATA);
- *out = output;
+ if (decomp)
+ inflateEnd(&zbuf);
+ else
+ deflateEnd(&zbuf);
return result;
bad:
- *out = NULL;
- for (j = 0; buf[j].flag != 0; j++)
- free(buf[j].out, M_CRYPTO_DATA);
- free(buf, M_CRYPTO_DATA);
if (decomp)
inflateEnd(&zbuf);
else
deflateEnd(&zbuf);
+bad2:
+ for (j = 0; j < i; j++)
+ free(buf[j].out, M_CRYPTO_DATA);
+bad3:
+ free(buf, M_CRYPTO_DATA);
return 0;
}
@@ -244,7 +231,7 @@
u_int32_t count, result;
int error, i = 0, j;
struct deflate_buf *buf, *tmp;
- size_t nbufs, old_nbufs;
+ size_t nbufs;
u_int32_t crc;
u_int32_t isize;
@@ -259,9 +246,6 @@
}
memset(&zbuf, 0, sizeof(z_stream));
- for (j = 0; j < nbufs; j++)
- buf[j].flag = 0;
-
zbuf.zalloc = ocf_zalloc;
zbuf.zfree = ocf_zfree;
zbuf.opaque = Z_NULL;
@@ -277,16 +261,8 @@
i, size, sizeof(gzip_header), GZIP_TAIL_SIZE,
size + sizeof(gzip_header) + GZIP_TAIL_SIZE));
- buf[i].out = malloc(size, M_CRYPTO_DATA, M_NOWAIT);
- if (buf[i].out == NULL)
- goto bad2;
- buf[i].size = size;
- buf[i].flag = 1;
+ buf[0].size = size;
- zbuf.next_out = buf[i].out;
- zbuf.avail_out = buf[i].size;
- i++;
-
crc = crc32(crc, data, size);
DPRINTF(("gzip_compress: size %d, crc 0x%x\n", size, crc));
} else {
@@ -323,25 +299,23 @@
data[size-2],
data[size-1]));
- buf[i].size = isize;
- buf[i].out = malloc(buf[i].size, M_CRYPTO_DATA, M_NOWAIT);
- if (buf[i].out == NULL)
- goto bad2;
- buf[i].flag = 1;
- zbuf.next_out = buf[i].out;
- zbuf.avail_out = buf[i].size;
- i++;
+ buf[0].size = isize;
/* skip over the gzip header */
zbuf.next_in = data + sizeof(gzip_header);
/* actual payload size stripped of gzip header and tail */
zbuf.avail_in = size - sizeof(gzip_header) - GZIP_TAIL_SIZE;
- DPRINTF(("zbuf avail_in %d, avail_out %d\n",
- zbuf.avail_in, zbuf.avail_out));
-
}
+ buf[0].out = malloc(buf[0].size, M_CRYPTO_DATA, M_NOWAIT);
+ if (buf[0].out == NULL)
+ goto bad2;
+ zbuf.next_out = buf[0].out;
+ zbuf.avail_out = buf[0].size;
+ DPRINTF(("zbuf avail_in %d, avail_out %d\n",
+ zbuf.avail_in, zbuf.avail_out));
+ i = 1;
error = decomp ? inflateInit2(&zbuf, window_inflate) :
deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
@@ -368,16 +342,13 @@
DPRINTF(("gzip_global: avail_in == 0, avail_out == 0, ending\n"));
goto end;
} else if (zbuf.avail_out == 0) {
- if (i == (nbufs-1)) {
- old_nbufs = i;
+ if (i == nbufs) {
nbufs += ZBUF;
tmp = realloc(buf,nbufs*sizeof(struct deflate_buf),
M_CRYPTO_DATA, M_NOWAIT);
if (tmp == NULL)
goto bad;
buf = tmp;
- for (j = old_nbufs; j < nbufs; j++)
- buf[j].flag = 0;
}
/* we need more output space, allocate size */
buf[i].out = malloc(size, M_CRYPTO_DATA, M_NOWAIT);
@@ -385,7 +356,6 @@
goto bad;
zbuf.next_out = buf[i].out;
buf[i].size = size;
- buf[i].flag = 1;
zbuf.avail_out = buf[i].size;
i++;
} else
@@ -416,7 +386,7 @@
memcpy(output, gzip_header, sizeof(gzip_header));
output += sizeof(gzip_header);
}
- for (j = 0; buf[j].flag != 0; j++) {
+ for (j = 0; j < i; j++) {
if (decomp) {
/* update crc for decompressed data */
crc = crc32(crc, buf[j].out, buf[j].size);
@@ -458,7 +428,7 @@
deflateEnd(&zbuf);
bad2:
*out = NULL;
- for (j = 0; buf[j].flag != 0; j++)
+ for (j = 0; j < i; j++)
free(buf[j].out, M_CRYPTO_DATA);
free(buf, M_CRYPTO_DATA);
return 0;
Index: src/sys/opencrypto/deflate.h
diff -u src/sys/opencrypto/deflate.h:1.6 src/sys/opencrypto/deflate.h:1.7
--- src/sys/opencrypto/deflate.h:1.6 Wed Mar 25 01:26:13 2009
+++ src/sys/opencrypto/deflate.h Wed Feb 16 19:08:58 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: deflate.h,v 1.6 2009/03/25 01:26:13 darran Exp $ */
+/* $NetBSD: deflate.h,v 1.7 2011/02/16 19:08:58 drochner Exp $ */
/* $FreeBSD: src/sys/opencrypto/deflate.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: deflate.h,v 1.3 2002/03/14 01:26:51 millert Exp $ */
@@ -52,7 +52,6 @@
struct deflate_buf {
u_int8_t *out;
u_int32_t size;
- int flag;
};
#endif /* _CRYPTO_DEFLATE_H_ */