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