| From f8b15699d654c8ace6819287dcdd3c8e493b7f6c Mon Sep 17 00:00:00 2001 |
| From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> |
| Date: Fri, 3 Jun 2022 13:47:34 -0300 |
| Subject: [PATCH] Reduce the scope for SW usage on length threshold |
| |
| When compressing/decompressing large amounts of data, the first call to |
| deflate()/inflate() may not have data enough to pass the threshold, |
| causing libnxz to fallback to software prematurely. |
| We can only take that decision if the software indicates that all the |
| input has been made available, i.e. when flush == Z_FINISH. |
| |
| Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> |
| |
| lib/nx_deflate.c | 3 ++- |
| lib/nx_inflate.c | 3 ++- |
| lib/nx_zlib.h | 27 +++++++++++++++++++-------- |
| 3 files changed, 23 insertions(+), 10 deletions(-) |
| |
| diff --git a/lib/nx_deflate.c b/lib/nx_deflate.c |
| index f2d5222..05b3580 100644 |
| |
| |
| @@ -1534,7 +1534,8 @@ int nx_deflate(z_streamp strm, int flush) |
| return Z_STREAM_ERROR; |
| |
| /* check for sw deflate first */ |
| - if( (has_nx_state(strm)) && s->switchable && (0 == use_nx_deflate(strm))){ |
| + if (has_nx_state(strm) && s->switchable |
| + && (0 == use_nx_deflate(strm, flush))) { |
| /* Use software zlib, switch the sw and hw state */ |
| s = (nx_streamp) strm->state; |
| s->switchable = 0; /* decided to use sw zlib and not switchable */ |
| diff --git a/lib/nx_inflate.c b/lib/nx_inflate.c |
| index 6dac0ad..d59d5db 100644 |
| |
| |
| @@ -289,7 +289,8 @@ int nx_inflate(z_streamp strm, int flush) |
| if (s == NULL) return Z_STREAM_ERROR; |
| |
| /* check for sw deflate first*/ |
| - if(has_nx_state(strm) && s->switchable && (0 == use_nx_inflate(strm))){ |
| + if (has_nx_state(strm) && s->switchable |
| + && (0 == use_nx_inflate(strm, flush))) { |
| /*Use software zlib, switch the sw and hw state*/ |
| s = (nx_streamp) strm->state; |
| s->switchable = 0; /* decided to use sw zlib and not switchable */ |
| diff --git a/lib/nx_zlib.h b/lib/nx_zlib.h |
| index 7550c65..2c0bdb5 100644 |
| |
| |
| @@ -341,7 +341,7 @@ static inline int has_nx_state(z_streamp strm) |
| return (nx_state->magic1 == MAGIC1); |
| } |
| |
| -static inline int use_nx_inflate(z_streamp strm) |
| +static inline int use_nx_inflate(z_streamp strm, int flush) |
| { |
| uint64_t rnd; |
| assert(strm != NULL); |
| @@ -349,8 +349,13 @@ static inline int use_nx_inflate(z_streamp strm) |
| if(nx_config.mode.inflate == GZIP_NX) return 1; |
| if(nx_config.mode.inflate == GZIP_SW) return 0; |
| |
| - /* #1 Threshold */ |
| - if(strm->avail_in <= DECOMPRESS_THRESHOLD) return 0; |
| + /* #2 Length threshold |
| + Even when decompressing a large amount of data, the first call to |
| + inflate() may not have enough input. So, avoid switching to software |
| + decompression prematurely unless there is a guarantee that all the |
| + input has been provided, i.e. when using Z_FINISH. */ |
| + if(flush == Z_FINISH && strm->avail_in <= DECOMPRESS_THRESHOLD) |
| + return 0; |
| |
| if(nx_config.mode.inflate == GZIP_AUTO) return 1; |
| |
| @@ -363,15 +368,21 @@ static inline int use_nx_inflate(z_streamp strm) |
| } |
| } |
| |
| -static inline int use_nx_deflate(z_streamp strm) |
| +static inline int use_nx_deflate(z_streamp strm, int flush) |
| { |
| assert(strm != NULL); |
| |
| - if(nx_config.mode.deflate == GZIP_NX) return 1; |
| - if(nx_config.mode.deflate == GZIP_SW) return 0; |
| + if(nx_config.mode.deflate == GZIP_NX) return 1; |
| + if(nx_config.mode.deflate == GZIP_SW) return 0; |
| + |
| + /* #2 Length threshold |
| + Even when compressing a large amount of data, the first call to |
| + deflate() may not have enough input. So, avoid switching to software |
| + compression prematurely unless there is a guarantee that all the |
| + input has been provided, i.e. when using Z_FINISH. */ |
| + if(flush == Z_FINISH && strm->avail_in <= COMPRESS_THRESHOLD) |
| + return 0; |
| |
| - /* #1 Threshold */ |
| - if(strm->avail_in <= COMPRESS_THRESHOLD) return 0; |
| return 1; |
| } |
| |
| -- |
| 2.35.3 |
| |