Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/opencrypto -avoid allocation of an extra result buffer a...



details:   https://anonhg.NetBSD.org/src/rev/e2b4eb0db10c
branches:  trunk
changeset: 762150:e2b4eb0db10c
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Feb 16 19:08:57 2011 +0000

description:
-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

diffstat:

 sys/opencrypto/deflate.c |  138 ++++++++++++++++++----------------------------
 sys/opencrypto/deflate.h |    3 +-
 2 files changed, 55 insertions(+), 86 deletions(-)

diffs (truncated from 312 to 300 lines):

diff -r 6d4a463628b3 -r e2b4eb0db10c sys/opencrypto/deflate.c
--- a/sys/opencrypto/deflate.c  Wed Feb 16 18:55:50 2011 +0000
+++ b/sys/opencrypto/deflate.c  Wed Feb 16 19:08:57 2011 +0000
@@ -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;
+       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 -= buf[j].size;
-               } else {
-                       /* it should be the last buffer */
-                       memcpy(*out, buf[j].out, count);
-                       *out += count;
-                       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;
-       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);
+       return result;
+
+bad:
+       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;
diff -r 6d4a463628b3 -r e2b4eb0db10c sys/opencrypto/deflate.h
--- a/sys/opencrypto/deflate.h  Wed Feb 16 18:55:50 2011 +0000
+++ b/sys/opencrypto/deflate.h  Wed Feb 16 19:08:57 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: deflate.h,v 1.6 2009/03/25 01:26:13 darran Exp $ */



Home | Main Index | Thread Index | Old Index