You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.8 KiB
106 lines
3.8 KiB
2 years ago
|
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
|
||
|
--- a/lib/nx_deflate.c
|
||
|
+++ b/lib/nx_deflate.c
|
||
|
@@ -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
|
||
|
--- a/lib/nx_inflate.c
|
||
|
+++ b/lib/nx_inflate.c
|
||
|
@@ -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
|
||
|
--- a/lib/nx_zlib.h
|
||
|
+++ b/lib/nx_zlib.h
|
||
|
@@ -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
|
||
|
|