Fix an issue that caused premature fallback to software

Backport the first patch from https://github.com/libnxz/power-gzip/pull/174.
This commit is contained in:
Tulio Magno Quites Machado Filho 2022-06-20 15:30:16 -03:00 committed by Tulio Magno Quites Machado Filho
parent 70841f055d
commit e6f6493cbf
2 changed files with 111 additions and 1 deletions

View File

@ -4,7 +4,7 @@
Name: libnxz Name: libnxz
Version: 0.63 Version: 0.63
Release: 3%{?dist} Release: 4%{?dist}
Summary: Zlib implementation for POWER processors Summary: Zlib implementation for POWER processors
License: ASL 2.0 or GPLv2+ License: ASL 2.0 or GPLv2+
Url: https://github.com/libnxz/power-gzip Url: https://github.com/libnxz/power-gzip
@ -15,6 +15,8 @@ Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
Patch0: pr150.patch Patch0: pr150.patch
# https://github.com/libnxz/power-gzip/pull/155 # https://github.com/libnxz/power-gzip/pull/155
Patch1: pr155.patch Patch1: pr155.patch
# https://github.com/libnxz/power-gzip/pull/174
Patch2: pr174.patch
# Be explicit about the soname in order to avoid unintentional changes. # Be explicit about the soname in order to avoid unintentional changes.
%global soname libnxz.so.0 %global soname libnxz.so.0
@ -85,6 +87,9 @@ fi
%{_libdir}/libnxz.la %{_libdir}/libnxz.la
%changelog %changelog
* Mon Jun 20 2022 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> - 0.63-4
- Fix an issue that caused premature fallback to software.
* Tue Jun 14 2022 Jakub Čajka <jcajka@redhat.com> - 0.63-3 * Tue Jun 14 2022 Jakub Čajka <jcajka@redhat.com> - 0.63-3
- Move udev rule to the powerpc-utils-core - Move udev rule to the powerpc-utils-core

105
pr174.patch Normal file
View File

@ -0,0 +1,105 @@
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