Blame SOURCES/pr174.patch

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