linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib
@ 2023-01-26 13:14 Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 1/8] lib/zlib: Adjust offset calculation for dfltcc_state Mikhail Zaslonko
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

Patches 1-7 represent a set of s390 zlib hardware support (DFLTCC) related fixes
and enhancements integrated from zlib-ng repo relevant to kernel zlib
(https://github.com/zlib-ng/zlib-ng).
Since the official zlib repository never got DFLTCC support code merged, all
the patches have been picked from zlib-ng fork (zlib data compression library
for the next generation systems). This repo contains new optimizations and
fixes not getting implemented into the official zlib repository and falls under
the same zlib License. All of the original patches from zlib-ng were authored
by Ilya Leoshkevich <iii@linux.ibm.com>. Coding style has been preserved for
future maintainability.
Patches 1-2 should have no effect for the kernel zlib but make the code
closer to zlib-ng for future maintainability.
Only Patch 3 touches common zlib_deflate code, other patches are relevant to
s390 tree only.

Patch 8 is separate and intends to resolve an issue with kernel PPP driver
which can use kernel zlib for packet compression. Without this patch PPP
decompression can fail due to error code returned by hardware (dfltcc_inflate)
and PPP disables zlib compression for further packets.

@Andrew, would you pick this patch series yourself (which is totally fine
with me) or shall we carry it via s390 tree?

Mikhail Zaslonko (8):
  lib/zlib: Adjust offset calculation for dfltcc_state
  lib/zlib: Implement switching between DFLTCC and software
  lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams
  lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0
  lib/zlib: DFLTCC not writing header bits when avail_out == 0
  lib/zlib: Split deflate and inflate states for DFLTCC
  lib/zlib: DFLTCC support inflate with small window
  lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH
    option

 lib/zlib_deflate/deflate.c       | 23 ++++++---
 lib/zlib_dfltcc/dfltcc.c         | 25 ++-------
 lib/zlib_dfltcc/dfltcc.h         | 57 +++++---------------
 lib/zlib_dfltcc/dfltcc_deflate.c | 89 +++++++++++++++++++++-----------
 lib/zlib_dfltcc/dfltcc_deflate.h | 21 ++++++++
 lib/zlib_dfltcc/dfltcc_inflate.c | 24 +++++----
 lib/zlib_dfltcc/dfltcc_inflate.h | 37 +++++++++++++
 lib/zlib_inflate/inflate.c       |  2 +-
 8 files changed, 163 insertions(+), 115 deletions(-)
 create mode 100644 lib/zlib_dfltcc/dfltcc_deflate.h
 create mode 100644 lib/zlib_dfltcc/dfltcc_inflate.h

-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/8] lib/zlib: Adjust offset calculation for dfltcc_state
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 2/8] lib/zlib: Implement switching between DFLTCC and software Mikhail Zaslonko
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/d8b67f5

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/zlib_dfltcc/dfltcc.h b/lib/zlib_dfltcc/dfltcc.h
index 2a2fac1d050a..1f63094366e9 100644
--- a/lib/zlib_dfltcc/dfltcc.h
+++ b/lib/zlib_dfltcc/dfltcc.h
@@ -100,8 +100,9 @@ struct dfltcc_state {
     char msg[64];                      /* Buffer for strm->msg */
 };
 
+#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
 /* Resides right after inflate_state or deflate_state */
-#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((state) + 1))
+#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))
 
 /* External functions */
 int dfltcc_can_deflate(z_streamp strm);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/8] lib/zlib: Implement switching between DFLTCC and software
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 1/8] lib/zlib: Adjust offset calculation for dfltcc_state Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 3/8] lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams Mikhail Zaslonko
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/fc04275

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc_deflate.c | 38 ++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/lib/zlib_dfltcc/dfltcc_deflate.c b/lib/zlib_dfltcc/dfltcc_deflate.c
index 6c946e8532ee..dc85ec890163 100644
--- a/lib/zlib_dfltcc/dfltcc_deflate.c
+++ b/lib/zlib_dfltcc/dfltcc_deflate.c
@@ -112,30 +112,36 @@ int dfltcc_deflate(
     int soft_bcc;
     int no_flush;
 
-    if (!dfltcc_can_deflate(strm))
+    if (!dfltcc_can_deflate(strm)) {
+        /* Clear history. */
+        if (flush == Z_FULL_FLUSH)
+            param->hl = 0;
         return 0;
+    }
 
 again:
     masked_avail_in = 0;
     soft_bcc = 0;
     no_flush = flush == Z_NO_FLUSH;
 
-    /* Trailing empty block. Switch to software, except when Continuation Flag
-     * is set, which means that DFLTCC has buffered some output in the
-     * parameter block and needs to be called again in order to flush it.
+    /* No input data. Return, except when Continuation Flag is set, which means
+     * that DFLTCC has buffered some output in the parameter block and needs to
+     * be called again in order to flush it.
      */
-    if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
-        if (param->bcf) {
-            /* A block is still open, and the hardware does not support closing
-             * blocks without adding data. Thus, close it manually.
-             */
+    if (strm->avail_in == 0 && !param->cf) {
+        /* A block is still open, and the hardware does not support closing
+         * blocks without adding data. Thus, close it manually.
+         */
+        if (!no_flush && param->bcf) {
             send_eobs(strm, param);
             param->bcf = 0;
         }
-        return 0;
-    }
-
-    if (strm->avail_in == 0 && !param->cf) {
+        /* Let one of deflate_* functions write a trailing empty block. */
+        if (flush == Z_FINISH)
+            return 0;
+        /* Clear history. */
+        if (flush == Z_FULL_FLUSH)
+            param->hl = 0;
         *result = need_more;
         return 1;
     }
@@ -189,7 +195,7 @@ int dfltcc_deflate(
     param->cvt = CVT_ADLER32;
     if (!no_flush)
         /* We need to close a block. Always do this in software - when there is
-         * no input data, the hardware will not nohor BCC. */
+         * no input data, the hardware will not hohor BCC. */
         soft_bcc = 1;
     if (flush == Z_FINISH && !param->bcf)
         /* We are about to open a BFINAL block, set Block Header Final bit
@@ -204,8 +210,8 @@ int dfltcc_deflate(
     param->sbb = (unsigned int)state->bi_valid;
     if (param->sbb > 0)
         *strm->next_out = (Byte)state->bi_buf;
-    if (param->hl)
-        param->nt = 0; /* Honor history */
+    /* Honor history and check value */
+    param->nt = 0;
     param->cv = strm->adler;
 
     /* When opening a block, choose a Huffman-Table Type */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/8] lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 1/8] lib/zlib: Adjust offset calculation for dfltcc_state Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 2/8] lib/zlib: Implement switching between DFLTCC and software Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 4/8] lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0 Mikhail Zaslonko
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/ca99a88

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_deflate/deflate.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c
index 8a878d0d892c..f30d6b8a69b2 100644
--- a/lib/zlib_deflate/deflate.c
+++ b/lib/zlib_deflate/deflate.c
@@ -451,17 +451,24 @@ int zlib_deflate(
     Assert(strm->avail_out > 0, "bug2");
 
     if (flush != Z_FINISH) return Z_OK;
-    if (s->noheader) return Z_STREAM_END;
 
-    /* Write the zlib trailer (adler32) */
-    putShortMSB(s, (uInt)(strm->adler >> 16));
-    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    if (!s->noheader) {
+	/* Write zlib trailer (adler32) */
+	putShortMSB(s, (uInt)(strm->adler >> 16));
+	putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
     flush_pending(strm);
     /* If avail_out is zero, the application will call deflate again
      * to flush the rest.
      */
-    s->noheader = -1; /* write the trailer only once! */
-    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+    if (!s->noheader) {
+	s->noheader = -1; /* write the trailer only once! */
+    }
+    if (s->pending == 0) {
+	Assert(s->bi_valid == 0, "bi_buf not flushed");
+	return Z_STREAM_END;
+    }
+    return Z_OK;
 }
 
 /* ========================================================================= */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/8] lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (2 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 3/8] lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 5/8] lib/zlib: DFLTCC not writing header bits when avail_out " Mikhail Zaslonko
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/40acb3f

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc_deflate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/zlib_dfltcc/dfltcc_deflate.c b/lib/zlib_dfltcc/dfltcc_deflate.c
index dc85ec890163..211d344710d5 100644
--- a/lib/zlib_dfltcc/dfltcc_deflate.c
+++ b/lib/zlib_dfltcc/dfltcc_deflate.c
@@ -142,7 +142,8 @@ int dfltcc_deflate(
         /* Clear history. */
         if (flush == Z_FULL_FLUSH)
             param->hl = 0;
-        *result = need_more;
+        /* Trigger block post-processing if necessary. */
+        *result = no_flush ? need_more : block_done;
         return 1;
     }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/8] lib/zlib: DFLTCC not writing header bits when avail_out == 0
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (3 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 4/8] lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0 Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 6/8] lib/zlib: Split deflate and inflate states for DFLTCC Mikhail Zaslonko
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/ce409c6

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc_deflate.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/zlib_dfltcc/dfltcc_deflate.c b/lib/zlib_dfltcc/dfltcc_deflate.c
index 211d344710d5..d4c92f99808e 100644
--- a/lib/zlib_dfltcc/dfltcc_deflate.c
+++ b/lib/zlib_dfltcc/dfltcc_deflate.c
@@ -170,13 +170,18 @@ int dfltcc_deflate(
             param->bcf = 0;
             dfltcc_state->block_threshold =
                 strm->total_in + dfltcc_state->block_size;
-            if (strm->avail_out == 0) {
-                *result = need_more;
-                return 1;
-            }
         }
     }
 
+    /* No space for compressed data. If we proceed, dfltcc_cmpr() will return
+     * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still
+     * set BCF=1, which is wrong. Avoid complications and return early.
+     */
+    if (strm->avail_out == 0) {
+        *result = need_more;
+        return 1;
+    }
+
     /* The caller gave us too much data. Pass only one block worth of
      * uncompressed data to DFLTCC and mask the rest, so that on the next
      * iteration we start a new block.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/8] lib/zlib: Split deflate and inflate states for DFLTCC
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (4 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 5/8] lib/zlib: DFLTCC not writing header bits when avail_out " Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 7/8] lib/zlib: DFLTCC support inflate with small window Mikhail Zaslonko
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

Currently deflate and inflate both use a common state struct. There are
several variables in this struct that we don't need for inflate, and
more may be coming in the future. Therefore split them in two separate
structs.
Apart from that, introduce separate headers for dfltcc_deflate and
dfltcc_inflate.

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/c592b1b

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_deflate/deflate.c       |  4 +--
 lib/zlib_dfltcc/dfltcc.c         | 25 ++-------------
 lib/zlib_dfltcc/dfltcc.h         | 52 ++++++--------------------------
 lib/zlib_dfltcc/dfltcc_deflate.c | 35 ++++++++++++++++-----
 lib/zlib_dfltcc/dfltcc_deflate.h | 21 +++++++++++++
 lib/zlib_dfltcc/dfltcc_inflate.c | 10 +++++-
 lib/zlib_dfltcc/dfltcc_inflate.h | 37 +++++++++++++++++++++++
 lib/zlib_inflate/inflate.c       |  2 +-
 8 files changed, 110 insertions(+), 76 deletions(-)
 create mode 100644 lib/zlib_dfltcc/dfltcc_deflate.h
 create mode 100644 lib/zlib_dfltcc/dfltcc_inflate.h

diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c
index f30d6b8a69b2..3a1d8d34182e 100644
--- a/lib/zlib_deflate/deflate.c
+++ b/lib/zlib_deflate/deflate.c
@@ -54,7 +54,7 @@
 
 /* architecture-specific bits */
 #ifdef CONFIG_ZLIB_DFLTCC
-#  include "../zlib_dfltcc/dfltcc.h"
+#  include "../zlib_dfltcc/dfltcc_deflate.h"
 #else
 #define DEFLATE_RESET_HOOK(strm) do {} while (0)
 #define DEFLATE_HOOK(strm, flush, bstate) 0
@@ -106,7 +106,7 @@ typedef struct deflate_workspace {
     deflate_state deflate_memory;
 #ifdef CONFIG_ZLIB_DFLTCC
     /* State memory for s390 hardware deflate */
-    struct dfltcc_state dfltcc_memory;
+    struct dfltcc_deflate_state dfltcc_memory;
 #endif
     Byte *window_memory;
     Pos *prev_memory;
diff --git a/lib/zlib_dfltcc/dfltcc.c b/lib/zlib_dfltcc/dfltcc.c
index 782f76e9d4da..ac6ac9739f5b 100644
--- a/lib/zlib_dfltcc/dfltcc.c
+++ b/lib/zlib_dfltcc/dfltcc.c
@@ -23,37 +23,18 @@ char *oesc_msg(
     }
 }
 
-void dfltcc_reset(
-    z_streamp strm,
-    uInt size
-)
-{
-    struct dfltcc_state *dfltcc_state =
-        (struct dfltcc_state *)((char *)strm->state + size);
-    struct dfltcc_qaf_param *param =
-        (struct dfltcc_qaf_param *)&dfltcc_state->param;
-
+void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) {
     /* Initialize available functions */
     if (is_dfltcc_enabled()) {
-        dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL);
-        memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af));
+        dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL);
+        memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af));
     } else
         memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
 
     /* Initialize parameter block */
     memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
     dfltcc_state->param.nt = 1;
-
-    /* Initialize tuning parameters */
-    if (zlib_dfltcc_support == ZLIB_DFLTCC_FULL_DEBUG)
-        dfltcc_state->level_mask = DFLTCC_LEVEL_MASK_DEBUG;
-    else
-        dfltcc_state->level_mask = DFLTCC_LEVEL_MASK;
-    dfltcc_state->block_size = DFLTCC_BLOCK_SIZE;
-    dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE;
-    dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE;
     dfltcc_state->param.ribm = DFLTCC_RIBM;
 }
-EXPORT_SYMBOL(dfltcc_reset);
 
 MODULE_LICENSE("GPL");
diff --git a/lib/zlib_dfltcc/dfltcc.h b/lib/zlib_dfltcc/dfltcc.h
index 1f63094366e9..b96232bdd44d 100644
--- a/lib/zlib_dfltcc/dfltcc.h
+++ b/lib/zlib_dfltcc/dfltcc.h
@@ -93,64 +93,32 @@ static_assert(sizeof(struct dfltcc_param_v0) == 1536);
 struct dfltcc_state {
     struct dfltcc_param_v0 param;      /* Parameter block */
     struct dfltcc_qaf_param af;        /* Available functions */
+    char msg[64];                      /* Buffer for strm->msg */
+};
+
+/*
+ *  Extension of inflate_state and deflate_state for DFLTCC.
+ */
+struct dfltcc_deflate_state {
+    struct dfltcc_state common;        /* Parameter block */
     uLong level_mask;                  /* Levels on which to use DFLTCC */
     uLong block_size;                  /* New block each X bytes */
     uLong block_threshold;             /* New block after total_in > X */
     uLong dht_threshold;               /* New block only if avail_in >= X */
-    char msg[64];                      /* Buffer for strm->msg */
 };
 
 #define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
 /* Resides right after inflate_state or deflate_state */
 #define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))
 
-/* External functions */
-int dfltcc_can_deflate(z_streamp strm);
-int dfltcc_deflate(z_streamp strm,
-                   int flush,
-                   block_state *result);
-void dfltcc_reset(z_streamp strm, uInt size);
-int dfltcc_can_inflate(z_streamp strm);
-typedef enum {
-    DFLTCC_INFLATE_CONTINUE,
-    DFLTCC_INFLATE_BREAK,
-    DFLTCC_INFLATE_SOFTWARE,
-} dfltcc_inflate_action;
-dfltcc_inflate_action dfltcc_inflate(z_streamp strm,
-                                     int flush, int *ret);
+void dfltcc_reset_state(struct dfltcc_state *dfltcc_state);
+
 static inline int is_dfltcc_enabled(void)
 {
 return (zlib_dfltcc_support != ZLIB_DFLTCC_DISABLED &&
         test_facility(DFLTCC_FACILITY));
 }
 
-#define DEFLATE_RESET_HOOK(strm) \
-    dfltcc_reset((strm), sizeof(deflate_state))
-
-#define DEFLATE_HOOK dfltcc_deflate
-
-#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
-
 #define DEFLATE_DFLTCC_ENABLED() is_dfltcc_enabled()
 
-#define INFLATE_RESET_HOOK(strm) \
-    dfltcc_reset((strm), sizeof(struct inflate_state))
-
-#define INFLATE_TYPEDO_HOOK(strm, flush) \
-    if (dfltcc_can_inflate((strm))) { \
-        dfltcc_inflate_action action; \
-\
-        RESTORE(); \
-        action = dfltcc_inflate((strm), (flush), &ret); \
-        LOAD(); \
-        if (action == DFLTCC_INFLATE_CONTINUE) \
-            break; \
-        else if (action == DFLTCC_INFLATE_BREAK) \
-            goto inf_leave; \
-    }
-
-#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
-
-#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
-
 #endif /* DFLTCC_H */
diff --git a/lib/zlib_dfltcc/dfltcc_deflate.c b/lib/zlib_dfltcc/dfltcc_deflate.c
index d4c92f99808e..80924f067c24 100644
--- a/lib/zlib_dfltcc/dfltcc_deflate.c
+++ b/lib/zlib_dfltcc/dfltcc_deflate.c
@@ -2,11 +2,13 @@
 
 #include "../zlib_deflate/defutil.h"
 #include "dfltcc_util.h"
-#include "dfltcc.h"
+#include "dfltcc_deflate.h"
 #include <asm/setup.h>
 #include <linux/export.h>
 #include <linux/zutil.h>
 
+#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state))
+
 /*
  * Compress.
  */
@@ -15,7 +17,7 @@ int dfltcc_can_deflate(
 )
 {
     deflate_state *state = (deflate_state *)strm->state;
-    struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
+    struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
 
     /* Check for kernel dfltcc command line parameter */
     if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
@@ -28,15 +30,32 @@ int dfltcc_can_deflate(
         return 0;
 
     /* Unsupported hardware */
-    if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
-            !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
-            !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
+    if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) ||
+            !is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) ||
+            !is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0))
         return 0;
 
     return 1;
 }
 EXPORT_SYMBOL(dfltcc_can_deflate);
 
+void dfltcc_reset_deflate_state(z_streamp strm) {
+    deflate_state *state = (deflate_state *)strm->state;
+    struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
+
+    dfltcc_reset_state(&dfltcc_state->common);
+
+    /* Initialize tuning parameters */
+    if (zlib_dfltcc_support == ZLIB_DFLTCC_FULL_DEBUG)
+        dfltcc_state->level_mask = DFLTCC_LEVEL_MASK_DEBUG;
+    else
+        dfltcc_state->level_mask = DFLTCC_LEVEL_MASK;
+    dfltcc_state->block_size = DFLTCC_BLOCK_SIZE;
+    dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE;
+    dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE;
+}
+EXPORT_SYMBOL(dfltcc_reset_deflate_state);
+
 static void dfltcc_gdht(
     z_streamp strm
 )
@@ -104,8 +123,8 @@ int dfltcc_deflate(
 )
 {
     deflate_state *state = (deflate_state *)strm->state;
-    struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
-    struct dfltcc_param_v0 *param = &dfltcc_state->param;
+    struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
+    struct dfltcc_param_v0 *param = &dfltcc_state->common.param;
     uInt masked_avail_in;
     dfltcc_cc cc;
     int need_empty_block;
@@ -244,7 +263,7 @@ int dfltcc_deflate(
     } while (cc == DFLTCC_CC_AGAIN);
 
     /* Translate parameter block to stream */
-    strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
+    strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc);
     state->bi_valid = param->sbb;
     if (state->bi_valid == 0)
         state->bi_buf = 0; /* Avoid accessing next_out */
diff --git a/lib/zlib_dfltcc/dfltcc_deflate.h b/lib/zlib_dfltcc/dfltcc_deflate.h
new file mode 100644
index 000000000000..be44b43833b1
--- /dev/null
+++ b/lib/zlib_dfltcc/dfltcc_deflate.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: Zlib
+#ifndef DFLTCC_DEFLATE_H
+#define DFLTCC_DEFLATE_H
+
+#include "dfltcc.h"
+
+/* External functions */
+int dfltcc_can_deflate(z_streamp strm);
+int dfltcc_deflate(z_streamp strm,
+                   int flush,
+                   block_state *result);
+void dfltcc_reset_deflate_state(z_streamp strm);
+
+#define DEFLATE_RESET_HOOK(strm) \
+    dfltcc_reset_deflate_state((strm))
+
+#define DEFLATE_HOOK dfltcc_deflate
+
+#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
+
+#endif /* DFLTCC_DEFLATE_H */
diff --git a/lib/zlib_dfltcc/dfltcc_inflate.c b/lib/zlib_dfltcc/dfltcc_inflate.c
index fb60b5a6a1cb..a16f416c8811 100644
--- a/lib/zlib_dfltcc/dfltcc_inflate.c
+++ b/lib/zlib_dfltcc/dfltcc_inflate.c
@@ -2,7 +2,7 @@
 
 #include "../zlib_inflate/inflate.h"
 #include "dfltcc_util.h"
-#include "dfltcc.h"
+#include "dfltcc_inflate.h"
 #include <asm/setup.h>
 #include <linux/export.h>
 #include <linux/zutil.h>
@@ -32,6 +32,14 @@ int dfltcc_can_inflate(
 }
 EXPORT_SYMBOL(dfltcc_can_inflate);
 
+void dfltcc_reset_inflate_state(z_streamp strm) {
+    struct inflate_state *state = (struct inflate_state *)strm->state;
+    struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
+
+    dfltcc_reset_state(dfltcc_state);
+}
+EXPORT_SYMBOL(dfltcc_reset_inflate_state);
+
 static int dfltcc_was_inflate_used(
     z_streamp strm
 )
diff --git a/lib/zlib_dfltcc/dfltcc_inflate.h b/lib/zlib_dfltcc/dfltcc_inflate.h
new file mode 100644
index 000000000000..98d4bc42e526
--- /dev/null
+++ b/lib/zlib_dfltcc/dfltcc_inflate.h
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: Zlib
+#ifndef DFLTCC_INFLATE_H
+#define DFLTCC_INFLATE_H
+
+#include "dfltcc.h"
+
+/* External functions */
+void dfltcc_reset_inflate_state(z_streamp strm);
+int dfltcc_can_inflate(z_streamp strm);
+typedef enum {
+    DFLTCC_INFLATE_CONTINUE,
+    DFLTCC_INFLATE_BREAK,
+    DFLTCC_INFLATE_SOFTWARE,
+} dfltcc_inflate_action;
+dfltcc_inflate_action dfltcc_inflate(z_streamp strm,
+                                     int flush, int *ret);
+#define INFLATE_RESET_HOOK(strm) \
+    dfltcc_reset_inflate_state((strm))
+
+#define INFLATE_TYPEDO_HOOK(strm, flush) \
+    if (dfltcc_can_inflate((strm))) { \
+        dfltcc_inflate_action action; \
+\
+        RESTORE(); \
+        action = dfltcc_inflate((strm), (flush), &ret); \
+        LOAD(); \
+        if (action == DFLTCC_INFLATE_CONTINUE) \
+            break; \
+        else if (action == DFLTCC_INFLATE_BREAK) \
+            goto inf_leave; \
+    }
+
+#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
+
+#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
+
+#endif /* DFLTCC_DEFLATE_H */
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index ee39b5eb71f7..d1efad69f02b 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -17,7 +17,7 @@
 
 /* architecture-specific bits */
 #ifdef CONFIG_ZLIB_DFLTCC
-#  include "../zlib_dfltcc/dfltcc.h"
+#  include "../zlib_dfltcc/dfltcc_inflate.h"
 #else
 #define INFLATE_RESET_HOOK(strm) do {} while (0)
 #define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/8] lib/zlib: DFLTCC support inflate with small window
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (5 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 6/8] lib/zlib: Split deflate and inflate states for DFLTCC Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 13:14 ` [PATCH 8/8] lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH option Mikhail Zaslonko
  2023-01-26 23:16 ` [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Andrew Morton
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

There is no hardware control for DFLTCC window size.
After this change, software and hardware window formats no longer
match: the software will use wbits and wsize, and the hardware will use
HB_BITS and HB_SIZE.

Since neither dictionary manipulation nor internal allocation functions
are relevant to kernel zlib and zlib_inflate_workspacesize() always use
MAX_WBITS for window size calculation, only dfltcc_can_inflate() and
dfltcc_inflate() functions are affected by this patch.

This commit is based on:
  https://github.com/zlib-ng/zlib-ng/commit/3eab317

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc_inflate.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/lib/zlib_dfltcc/dfltcc_inflate.c b/lib/zlib_dfltcc/dfltcc_inflate.c
index a16f416c8811..5786030c6dc2 100644
--- a/lib/zlib_dfltcc/dfltcc_inflate.c
+++ b/lib/zlib_dfltcc/dfltcc_inflate.c
@@ -22,10 +22,6 @@ int dfltcc_can_inflate(
             zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY)
         return 0;
 
-    /* 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);
@@ -129,8 +125,6 @@ dfltcc_inflate_action dfltcc_inflate(
     /* Translate stream to parameter block */
     param->cvt = CVT_ADLER32;
     param->sbb = state->bits;
-    param->hl = state->whave; /* Software and hardware history formats match */
-    param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1);
     if (param->hl)
         param->nt = 0; /* Honor history for the first block */
     param->cv = state->check;
@@ -144,8 +138,6 @@ dfltcc_inflate_action dfltcc_inflate(
     strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
     state->last = cc == DFLTCC_CC_OK;
     state->bits = param->sbb;
-    state->whave = param->hl;
-    state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
     state->check = param->cv;
     if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
         /* Report an error if stream is corrupted */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/8] lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH option
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (6 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 7/8] lib/zlib: DFLTCC support inflate with small window Mikhail Zaslonko
@ 2023-01-26 13:14 ` Mikhail Zaslonko
  2023-01-26 23:16 ` [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Andrew Morton
  8 siblings, 0 replies; 10+ messages in thread
From: Mikhail Zaslonko @ 2023-01-26 13:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich, Mikhail Zaslonko

Since hardware inflate does not support Z_PACKET_FLUSH option
(used exclusively by kernel PPP driver), always switch to
software like we already do for Z_BLOCK flush option.
Without this patch, PPP might get Z_DATA_ERROR return code from
zlib_inflate() and disable zlib compression for the packets.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc_inflate.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/zlib_dfltcc/dfltcc_inflate.c b/lib/zlib_dfltcc/dfltcc_inflate.c
index 5786030c6dc2..437cd34c8490 100644
--- a/lib/zlib_dfltcc/dfltcc_inflate.c
+++ b/lib/zlib_dfltcc/dfltcc_inflate.c
@@ -95,8 +95,10 @@ dfltcc_inflate_action dfltcc_inflate(
     struct dfltcc_param_v0 *param = &dfltcc_state->param;
     dfltcc_cc cc;
 
-    if (flush == Z_BLOCK) {
-        /* DFLTCC does not support stopping on block boundaries */
+    if (flush == Z_BLOCK || flush == Z_PACKET_FLUSH) {
+        /* DFLTCC does not support stopping on block boundaries (Z_BLOCK flush option)
+         * as well as the use of Z_PACKET_FLUSH option (used exclusively by PPP driver)
+         */
         if (dfltcc_inflate_disable(strm)) {
             *ret = Z_STREAM_ERROR;
             return DFLTCC_INFLATE_BREAK;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib
  2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
                   ` (7 preceding siblings ...)
  2023-01-26 13:14 ` [PATCH 8/8] lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH option Mikhail Zaslonko
@ 2023-01-26 23:16 ` Andrew Morton
  8 siblings, 0 replies; 10+ messages in thread
From: Andrew Morton @ 2023-01-26 23:16 UTC (permalink / raw)
  To: Mikhail Zaslonko; +Cc: LKML, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich

On Thu, 26 Jan 2023 14:14:20 +0100 Mikhail Zaslonko <zaslonko@linux.ibm.com> wrote:

> Patches 1-7 represent a set of s390 zlib hardware support (DFLTCC) related fixes
> and enhancements integrated from zlib-ng repo relevant to kernel zlib
> (https://github.com/zlib-ng/zlib-ng).
> Since the official zlib repository never got DFLTCC support code merged, all
> the patches have been picked from zlib-ng fork (zlib data compression library
> for the next generation systems). This repo contains new optimizations and
> fixes not getting implemented into the official zlib repository and falls under
> the same zlib License. All of the original patches from zlib-ng were authored
> by Ilya Leoshkevich <iii@linux.ibm.com>. Coding style has been preserved for
> future maintainability.
> Patches 1-2 should have no effect for the kernel zlib but make the code
> closer to zlib-ng for future maintainability.
> Only Patch 3 touches common zlib_deflate code, other patches are relevant to
> s390 tree only.
> 
> Patch 8 is separate and intends to resolve an issue with kernel PPP driver
> which can use kernel zlib for packet compression. Without this patch PPP
> decompression can fail due to error code returned by hardware (dfltcc_inflate)
> and PPP disables zlib compression for further packets.
> 
> @Andrew, would you pick this patch series yourself (which is totally fine
> with me) or shall we carry it via s390 tree?

I'll grab.  zlib changes are pretty rare, but perhaps someone else will
do something..

> Mikhail Zaslonko (8):
>   lib/zlib: Adjust offset calculation for dfltcc_state
>   lib/zlib: Implement switching between DFLTCC and software
>   lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams
>   lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0
>   lib/zlib: DFLTCC not writing header bits when avail_out == 0
>   lib/zlib: Split deflate and inflate states for DFLTCC
>   lib/zlib: DFLTCC support inflate with small window
>   lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH
>     option

Most of these have a github link in lieu of a changelog.  And most of
the github commits are unchangelogged.  That's pretty sad, but the zlib
audience is small and zlib isn't really kernel code anyway, so I guess
we can look the other way.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-01-26 23:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-26 13:14 [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 1/8] lib/zlib: Adjust offset calculation for dfltcc_state Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 2/8] lib/zlib: Implement switching between DFLTCC and software Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 3/8] lib/zlib: Fix DFLTCC not flushing EOBS when creating raw streams Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 4/8] lib/zlib: Fix DFLTCC ignoring flush modes when avail_in == 0 Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 5/8] lib/zlib: DFLTCC not writing header bits when avail_out " Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 6/8] lib/zlib: Split deflate and inflate states for DFLTCC Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 7/8] lib/zlib: DFLTCC support inflate with small window Mikhail Zaslonko
2023-01-26 13:14 ` [PATCH 8/8] lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH option Mikhail Zaslonko
2023-01-26 23:16 ` [PATCH 0/8] lib/zlib: Set of s390 DFLTCC related patches for kernel zlib Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).