Blame SOURCES/pr174.patch

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