parent
1e2f66900e
commit
9006047624
299
zlib-1.2.11-IBM-Z-hw-accelrated-inflate-small-window.patch
Normal file
299
zlib-1.2.11-IBM-Z-hw-accelrated-inflate-small-window.patch
Normal file
@ -0,0 +1,299 @@
|
||||
--- a/contrib/s390/dfltcc.c
|
||||
+++ b/contrib/s390/dfltcc.c
|
||||
@@ -539,10 +539,6 @@ int ZLIB_INTERNAL dfltcc_can_inflate(strm)
|
||||
struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
|
||||
struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
|
||||
- /* Unsupported compression settings */
|
||||
- if (state->wbits != HB_BITS)
|
||||
- return 0;
|
||||
-
|
||||
/* Unsupported hardware */
|
||||
return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
|
||||
is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
|
||||
@@ -606,8 +602,6 @@ dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate(strm, flush, ret)
|
||||
/* Translate stream to parameter block */
|
||||
param->cvt = state->flags ? CVT_CRC32 : CVT_ADLER32;
|
||||
param->sbb = state->bits;
|
||||
- param->hl = state->whave; /* Software and hardware history formats match */
|
||||
- param->ho = (state->wnext - state->whave) & ((1 << HB_BITS) - 1);
|
||||
if (param->hl)
|
||||
param->nt = 0; /* Honor history for the first block */
|
||||
param->cv = state->flags ? ZSWAP32(state->check) : state->check;
|
||||
@@ -621,8 +615,6 @@ dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate(strm, flush, ret)
|
||||
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
||||
state->last = cc == DFLTCC_CC_OK;
|
||||
state->bits = param->sbb;
|
||||
- state->whave = param->hl;
|
||||
- state->wnext = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
|
||||
strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv;
|
||||
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
|
||||
/* Report an error if stream is corrupted */
|
||||
@@ -644,11 +636,52 @@ int ZLIB_INTERNAL dfltcc_was_inflate_used(strm)
|
||||
return !param->nt;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ Rotates a circular buffer.
|
||||
+ The implementation is based on https://cplusplus.com/reference/algorithm/rotate/
|
||||
+ */
|
||||
+local void rotate OF((Bytef *start, Bytef *pivot, Bytef *end));
|
||||
+local void rotate(start, pivot, end)
|
||||
+ Bytef *start;
|
||||
+ Bytef *pivot;
|
||||
+ Bytef *end;
|
||||
+{
|
||||
+ Bytef *p = pivot;
|
||||
+ Bytef tmp;
|
||||
+
|
||||
+ while (p != start) {
|
||||
+ tmp = *start;
|
||||
+ *start = *p;
|
||||
+ *p = tmp;
|
||||
+
|
||||
+ start++;
|
||||
+ p++;
|
||||
+
|
||||
+ if (p == end)
|
||||
+ p = pivot;
|
||||
+ else if (start == pivot)
|
||||
+ pivot = p;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define MIN(x, y) ({ \
|
||||
+ typeof(x) _x = (x); \
|
||||
+ typeof(y) _y = (y); \
|
||||
+ _x < _y ? _x : _y; \
|
||||
+})
|
||||
+
|
||||
+#define MAX(x, y) ({ \
|
||||
+ typeof(x) _x = (x); \
|
||||
+ typeof(y) _y = (y); \
|
||||
+ _x > _y ? _x : _y; \
|
||||
+})
|
||||
+
|
||||
int ZLIB_INTERNAL dfltcc_inflate_disable(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
|
||||
struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
+ struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||
|
||||
if (!dfltcc_can_inflate(strm))
|
||||
return 0;
|
||||
@@ -660,6 +693,9 @@ int ZLIB_INTERNAL dfltcc_inflate_disable(strm)
|
||||
return 1;
|
||||
/* DFLTCC was not used yet - decompress in software */
|
||||
memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
|
||||
+ /* Convert the window from the hardware to the software format */
|
||||
+ rotate(state->window, state->window + param->ho, state->window + HB_SIZE);
|
||||
+ state->whave = state->wnext = MIN(param->hl, state->wsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -830,9 +866,9 @@ voidpf ZLIB_INTERNAL dfltcc_alloc_window(strm, items, size)
|
||||
voidpf p, w;
|
||||
|
||||
/* To simplify freeing, we store the pointer to the allocated buffer right
|
||||
- * before the window.
|
||||
+ * before the window. Note that DFLTCC always uses HB_SIZE bytes.
|
||||
*/
|
||||
- p = ZALLOC(strm, sizeof(voidpf) + items * size + PAGE_ALIGN,
|
||||
+ p = ZALLOC(strm, sizeof(voidpf) + MAX(items * size, HB_SIZE) + PAGE_ALIGN,
|
||||
sizeof(unsigned char));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
@@ -841,6 +877,14 @@ voidpf ZLIB_INTERNAL dfltcc_alloc_window(strm, items, size)
|
||||
return w;
|
||||
}
|
||||
|
||||
+void ZLIB_INTERNAL dfltcc_copy_window(dest, src, n)
|
||||
+ void *dest;
|
||||
+ const void *src;
|
||||
+ size_t n;
|
||||
+{
|
||||
+ memcpy(dest, src, MAX(n, HB_SIZE));
|
||||
+}
|
||||
+
|
||||
void ZLIB_INTERNAL dfltcc_free_window(strm, w)
|
||||
z_streamp strm;
|
||||
voidpf w;
|
||||
@@ -951,6 +995,24 @@ local void append_history(param, history, buf, count)
|
||||
}
|
||||
}
|
||||
|
||||
+local void get_history OF((struct dfltcc_param_v0 FAR *param,
|
||||
+ const Bytef *history,
|
||||
+ Bytef *buf));
|
||||
+local void get_history(param, history, buf)
|
||||
+ struct dfltcc_param_v0 FAR *param;
|
||||
+ const Bytef *history;
|
||||
+ Bytef *buf;
|
||||
+{
|
||||
+ if (param->ho + param->hl <= HB_SIZE)
|
||||
+ /* Circular history buffer does not wrap - copy one chunk */
|
||||
+ memcpy(buf, history + param->ho, param->hl);
|
||||
+ else {
|
||||
+ /* Circular history buffer wraps - copy two chunks */
|
||||
+ memcpy(buf, history + param->ho, HB_SIZE - param->ho);
|
||||
+ memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length)
|
||||
z_streamp strm;
|
||||
const Bytef *dictionary;
|
||||
@@ -975,20 +1037,43 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary(strm, dictionary, dict_length)
|
||||
struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
|
||||
|
||||
- if (dictionary) {
|
||||
- if (param->ho + param->hl <= HB_SIZE)
|
||||
- /* Circular history buffer does not wrap - copy one chunk */
|
||||
- zmemcpy(dictionary, state->window + param->ho, param->hl);
|
||||
- else {
|
||||
- /* Circular history buffer wraps - copy two chunks */
|
||||
- zmemcpy(dictionary,
|
||||
- state->window + param->ho,
|
||||
- HB_SIZE - param->ho);
|
||||
- zmemcpy(dictionary + HB_SIZE - param->ho,
|
||||
- state->window,
|
||||
- param->ho + param->hl - HB_SIZE);
|
||||
- }
|
||||
+ if (dictionary)
|
||||
+ get_history(param, state->window, dictionary);
|
||||
+ if (dict_length)
|
||||
+ *dict_length = param->hl;
|
||||
+ return Z_OK;
|
||||
+}
|
||||
+
|
||||
+int ZLIB_INTERNAL dfltcc_inflate_set_dictionary(strm, dictionary, dict_length)
|
||||
+ z_streamp strm;
|
||||
+ const Bytef *dictionary;
|
||||
+ uInt dict_length;
|
||||
+{
|
||||
+ struct inflate_state *state = (struct inflate_state *)strm->state;
|
||||
+ struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
+ struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||
+
|
||||
+ if (inflate_ensure_window(state)) {
|
||||
+ state->mode = MEM;
|
||||
+ return Z_MEM_ERROR;
|
||||
}
|
||||
+
|
||||
+ append_history(param, state->window, dictionary, dict_length);
|
||||
+ state->havedict = 1;
|
||||
+ return Z_OK;
|
||||
+}
|
||||
+
|
||||
+int ZLIB_INTERNAL dfltcc_inflate_get_dictionary(strm, dictionary, dict_length)
|
||||
+ z_streamp strm;
|
||||
+ Bytef *dictionary;
|
||||
+ uInt *dict_length;
|
||||
+{
|
||||
+ struct inflate_state *state = (struct inflate_state *)strm->state;
|
||||
+ struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
+ struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||
+
|
||||
+ if (dictionary && state->window)
|
||||
+ get_history(param, state->window, dictionary);
|
||||
if (dict_length)
|
||||
*dict_length = param->hl;
|
||||
return Z_OK;
|
||||
--- a/contrib/s390/dfltcc.h
|
||||
+++ b/contrib/s390/dfltcc.h
|
||||
@@ -11,6 +11,8 @@ void ZLIB_INTERNAL dfltcc_copy_state OF((voidpf dst, const voidpf src,
|
||||
void ZLIB_INTERNAL dfltcc_reset OF((z_streamp strm, uInt size));
|
||||
voidpf ZLIB_INTERNAL dfltcc_alloc_window OF((z_streamp strm, uInt items,
|
||||
uInt size));
|
||||
+void ZLIB_INTERNAL dfltcc_copy_window OF((void *dest, const void *src,
|
||||
+ size_t n));
|
||||
void ZLIB_INTERNAL dfltcc_free_window OF((z_streamp strm, voidpf w));
|
||||
#define DFLTCC_BLOCK_HEADER_BITS 3
|
||||
#define DFLTCC_HLITS_COUNT_BITS 5
|
||||
@@ -44,11 +46,18 @@ dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate OF((z_streamp strm,
|
||||
int flush, int *ret));
|
||||
int ZLIB_INTERNAL dfltcc_was_inflate_used OF((z_streamp strm));
|
||||
int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm));
|
||||
+int ZLIB_INTERNAL dfltcc_inflate_set_dictionary OF((z_streamp strm,
|
||||
+ const Bytef *dictionary,
|
||||
+ uInt dict_length));
|
||||
+int ZLIB_INTERNAL dfltcc_inflate_get_dictionary OF((z_streamp strm,
|
||||
+ Bytef *dictionary,
|
||||
+ uInt* dict_length));
|
||||
|
||||
#define ZALLOC_STATE dfltcc_alloc_state
|
||||
#define ZFREE_STATE ZFREE
|
||||
#define ZCOPY_STATE dfltcc_copy_state
|
||||
#define ZALLOC_WINDOW dfltcc_alloc_window
|
||||
+#define ZCOPY_WINDOW dfltcc_copy_window
|
||||
#define ZFREE_WINDOW dfltcc_free_window
|
||||
#define TRY_FREE_WINDOW dfltcc_free_window
|
||||
#define INFLATE_RESET_KEEP_HOOK(strm) \
|
||||
@@ -77,5 +86,15 @@ int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm));
|
||||
do { \
|
||||
if (dfltcc_was_inflate_used((strm))) return Z_STREAM_ERROR; \
|
||||
} while (0)
|
||||
+#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \
|
||||
+ do { \
|
||||
+ if (dfltcc_can_inflate(strm)) \
|
||||
+ return dfltcc_inflate_set_dictionary(strm, dict, dict_len); \
|
||||
+ } while (0)
|
||||
+#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \
|
||||
+ do { \
|
||||
+ if (dfltcc_can_inflate(strm)) \
|
||||
+ return dfltcc_inflate_get_dictionary(strm, dict, dict_len); \
|
||||
+ } while (0)
|
||||
|
||||
#endif
|
||||
\ No newline at end of file
|
||||
diff --git a/inflate.c b/inflate.c
|
||||
index 3750152..a0e2169 100644
|
||||
--- a/inflate.c
|
||||
+++ b/inflate.c
|
||||
@@ -93,6 +93,7 @@
|
||||
#define ZFREE_STATE ZFREE
|
||||
#define ZCOPY_STATE zmemcpy
|
||||
#define ZALLOC_WINDOW ZALLOC
|
||||
+#define ZCOPY_WINDOW zmemcpy
|
||||
#define ZFREE_WINDOW ZFREE
|
||||
#define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
|
||||
#define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0)
|
||||
@@ -101,6 +102,8 @@
|
||||
#define INFLATE_NEED_UPDATEWINDOW(strm) 1
|
||||
#define INFLATE_MARK_HOOK(strm) do {} while (0)
|
||||
#define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0)
|
||||
+#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
|
||||
+#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef MAKEFIXED
|
||||
@@ -1330,6 +1333,8 @@ uInt *dictLength;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
+ INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength);
|
||||
+
|
||||
/* copy dictionary */
|
||||
if (state->whave && dictionary != Z_NULL) {
|
||||
zmemcpy(dictionary, state->window + state->wnext,
|
||||
@@ -1365,6 +1370,8 @@ uInt dictLength;
|
||||
return Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
+ INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength);
|
||||
+
|
||||
/* copy dictionary to window using updatewindow(), which will amend the
|
||||
existing dictionary if appropriate */
|
||||
ret = updatewindow(strm, dictionary + dictLength, dictLength);
|
||||
@@ -1529,8 +1536,7 @@ z_streamp source;
|
||||
}
|
||||
copy->next = copy->codes + (state->next - state->codes);
|
||||
if (window != Z_NULL) {
|
||||
- wsize = 1U << state->wbits;
|
||||
- zmemcpy(window, state->window, wsize);
|
||||
+ ZCOPY_WINDOW(window, state->window, 1U << state->wbits);
|
||||
}
|
||||
copy->window = window;
|
||||
dest->state = (struct internal_state FAR *)copy;
|
@ -2,7 +2,7 @@
|
||||
|
||||
Name: zlib
|
||||
Version: 1.2.11
|
||||
Release: 35%{?dist}
|
||||
Release: 36%{?dist}
|
||||
Summary: Compression and decompression library
|
||||
# /contrib/dotzlib/ have Boost license
|
||||
License: zlib and Boost
|
||||
@ -46,6 +46,8 @@ Patch20: zlib-1.2.11-cve-2022-37434_2.patch
|
||||
# Fix setting strm.adler on z15
|
||||
Patch21: zlib-1.2.11-IBM-Z-hw-accelrated-deflate-strm-adler-fix.patch
|
||||
|
||||
# Optimization for z15
|
||||
Patch22: zlib-1.2.11-IBM-Z-hw-accelrated-inflate-small-window.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: automake, autoconf, libtool
|
||||
@ -119,6 +121,7 @@ developing applications which use minizip.
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
|
||||
|
||||
iconv -f iso-8859-2 -t utf-8 < ChangeLog > ChangeLog.tmp
|
||||
@ -196,6 +199,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Dec 19 2022 Ilya Leoshkevich <iii@linux.ibm.com> - 1.2.11-36
|
||||
- Inflate small window optimization for IBM z15 rhbz#2154775
|
||||
|
||||
* Wed Oct 12 2022 Ilya Leoshkevich <iii@linux.ibm.com> - 1.2.11-35
|
||||
- Fix for IBM strm.adler rhbz#2134074
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user