linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] lib/lzo: performance improvements
@ 2018-11-27 16:19 Dave Rodgman
  2018-11-27 16:19 ` [PATCH 1/7] lib/lzo: tidy-up ifdefs Dave Rodgman
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

This patch series introduces performance improvements for lzo.

The previous version of this patchset is here:
https://lkml.org/lkml/2018/11/21/625

This version tidies up the ifdefs as per Christoph's comment (although
certainly more could be done, this is at least a bit more consistent
with normal kernel coding style).

On 23/11/2018 2:12 am, Sergey Senozhatsky wrote:

>> The graph below shows the weighted round-trip throughput of lzo, lz4 and
>> lzo-rle, for randomly generated 4k chunks of data with varying levels of
>> entropy. (To calculate weighted round-trip throughput, compression performance
>> is emphasised to reflect the fact that zram does around 2.25x more compression
>> than decompression.
> 
> Right. The number is data dependent. Not all swapped out pages can be
> compressed; compressed pages that end up being >= zs_huge_class_size() are
> considered incompressible and stored as it.
> 
> I'd say that on my setups around 50-60% of pages are incompressible.

So, just to give a bit more detail: the test setup was a Samsung
Chromebook Pro, cycling through 80 tabs in Chrome. With lzo-rle, only
5% of pages increased in size, and 90% of pages compress to 75% of
original size (or better). Mean compression ratio was 41%. Importantly
for lzo-rle, there are a lot of low-entropy pages where it can do well:
in total about 20% of the data is zeros forming part of a run of 4 or
more bytes.

As a quick summary of the impact of these patches on bigger chunks of
data, I've compared the performance of four different variants of lzo
on two large (~40 MB) files. The numbers show round-trip throughput
in MB/s:

Variant         | Low-entropy | High-entropy
Current lzo     |  242        | 157
Arm opts        |  290        | 159
RLE             |  876        | 151
Arm opts + RLE  | 1150        | 181

So both the Arm optimisations (8,16-byte copy & CTZ patches), and the
RLE implementation make a significant contribution to the overall
performance uplift.


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

* [PATCH 1/7] lib/lzo: tidy-up ifdefs
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-27 16:19 ` [PATCH 2/7] lib/lzo: clean-up by introducing COPY16 Dave Rodgman
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

Modify the ifdefs in lzodefs.h to be more consistent with normal kernel
macros (e.g., change __aarch64__ to CONFIG_ARM64).

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
---
 lib/lzo/lzodefs.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index 4edefd2f540c..497f9c9f03a8 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -15,7 +15,7 @@
 
 #define COPY4(dst, src)	\
 		put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
-#if defined(__x86_64__)
+#if defined(CONFIG_X86_64)
 #define COPY8(dst, src)	\
 		put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst))
 #else
@@ -25,12 +25,12 @@
 
 #if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
 #error "conflicting endian definitions"
-#elif defined(__x86_64__)
+#elif defined(CONFIG_X86_64)
 #define LZO_USE_CTZ64	1
 #define LZO_USE_CTZ32	1
-#elif defined(__i386__) || defined(__powerpc__)
+#elif defined(CONFIG_X86) || defined(CONFIG_PPC)
 #define LZO_USE_CTZ32	1
-#elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 5)
+#elif defined(CONFIG_ARM) && (__LINUX_ARM_ARCH__ >= 5)
 #define LZO_USE_CTZ32	1
 #endif
 
-- 
2.16.4


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

* [PATCH 2/7] lib/lzo: clean-up by introducing COPY16
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
  2018-11-27 16:19 ` [PATCH 1/7] lib/lzo: tidy-up ifdefs Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-27 22:50   ` Andrew Morton
  2018-11-27 16:19 ` [PATCH 3/7] lib/lzo: enable 64-bit CTZ on Arm Dave Rodgman
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

From: Matt Sealey <matt.sealey@arm.com>

Most compilers should be able to merge adjacent loads/stores of sizes
which are less than but effect a multiple of a machine word size (in
effect a memcpy() of a constant amount). However the semantics of the
macro are that it just does the copy, the pointer increment is in the
code, hence we see

    *a = *b
    a += 8
    b += 8
    *a = *b
    a += 8
    b += 8

This introduces a dependency between the two groups of statements which
seems to defeat said compiler optimizers and generate some very strange
sequences of addition and subtraction of address offsets (i.e. it is
overcomplicated).

Since COPY8 is only ever used to copy amounts of 16 bytes (in pairs),
just define COPY16 as COPY8,COPY8. We leave the definition to preserve
the need to do unaligned accesses to machine-sized words per the
original code intent, we just don't use it in the code proper.

COPY16 then gives us code like:

    *a = *b
    *(a+8) = *(b+8)
    a += 16
    b += 16

This seems to allow compilers to generate much better code by using
base register writeback or simply positively incrementing offsets which
seems to positively affect performance. It is, at least, fewer
instructions to do the same job.

Signed-off-by: Matt Sealey <matt.sealey@arm.com>
---
 lib/lzo/lzo1x_compress.c        |  9 +++------
 lib/lzo/lzo1x_decompress_safe.c | 18 ++++++------------
 lib/lzo/lzodefs.h               |  3 +++
 3 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
index 236eb21167b5..82fb5571ce5e 100644
--- a/lib/lzo/lzo1x_compress.c
+++ b/lib/lzo/lzo1x_compress.c
@@ -60,8 +60,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 				op += t;
 			} else if (t <= 16) {
 				*op++ = (t - 3);
-				COPY8(op, ii);
-				COPY8(op + 8, ii + 8);
+				COPY16(op, ii);
 				op += t;
 			} else {
 				if (t <= 18) {
@@ -76,8 +75,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 					*op++ = tt;
 				}
 				do {
-					COPY8(op, ii);
-					COPY8(op + 8, ii + 8);
+					COPY16(op, ii);
 					op += 16;
 					ii += 16;
 					t -= 16;
@@ -255,8 +253,7 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len,
 			*op++ = tt;
 		}
 		if (t >= 16) do {
-			COPY8(op, ii);
-			COPY8(op + 8, ii + 8);
+			COPY16(op, ii);
 			op += 16;
 			ii += 16;
 			t -= 16;
diff --git a/lib/lzo/lzo1x_decompress_safe.c b/lib/lzo/lzo1x_decompress_safe.c
index a1c387f6afba..aa95d3066b7d 100644
--- a/lib/lzo/lzo1x_decompress_safe.c
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -86,12 +86,9 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 					const unsigned char *ie = ip + t;
 					unsigned char *oe = op + t;
 					do {
-						COPY8(op, ip);
-						op += 8;
-						ip += 8;
-						COPY8(op, ip);
-						op += 8;
-						ip += 8;
+						COPY16(op, ip);
+						op += 16;
+						ip += 16;
 					} while (ip < ie);
 					ip = ie;
 					op = oe;
@@ -187,12 +184,9 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 			unsigned char *oe = op + t;
 			if (likely(HAVE_OP(t + 15))) {
 				do {
-					COPY8(op, m_pos);
-					op += 8;
-					m_pos += 8;
-					COPY8(op, m_pos);
-					op += 8;
-					m_pos += 8;
+					COPY16(op, m_pos);
+					op += 16;
+					m_pos += 16;
 				} while (op < oe);
 				op = oe;
 				if (HAVE_IP(6)) {
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index 497f9c9f03a8..e1b3cf6459a9 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -23,6 +23,9 @@
 		COPY4(dst, src); COPY4((dst) + 4, (src) + 4)
 #endif
 
+#define COPY16(dst, src) \
+	do { COPY8(dst, src); COPY8((dst) + 8, (src) + 8); } while (0)
+
 #if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
 #error "conflicting endian definitions"
 #elif defined(CONFIG_X86_64)
-- 
2.16.4


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

* [PATCH 3/7] lib/lzo: enable 64-bit CTZ on Arm
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
  2018-11-27 16:19 ` [PATCH 1/7] lib/lzo: tidy-up ifdefs Dave Rodgman
  2018-11-27 16:19 ` [PATCH 2/7] lib/lzo: clean-up by introducing COPY16 Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-27 16:19 ` [PATCH 4/7] lib/lzo: 64-bit CTZ on arm64 Dave Rodgman
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

From: Matt Sealey <matt.sealey@arm.com>

ARMv6 Thumb state introduced an RBIT instruction which, combined with CLZ
as present in ARMv5, introduces an extremely fast path for counting
trailing zeroes.

Enable the use of the GCC builtin for this on ARMv6+ with
CONFIG_THUMB2_KERNEL to ensure we get the 'new' instruction usage.

We do not bother enabling LZO_USE_CTZ64 support for ARMv5 as the builtin
code path does the same thing as the LZO_USE_CTZ32 code, only with more
register pressure.

Signed-off-by: Matt Sealey <matt.sealey@arm.com>
---
 lib/lzo/lzodefs.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index e1b3cf6459a9..c0193f726db0 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -33,9 +33,14 @@
 #define LZO_USE_CTZ32	1
 #elif defined(CONFIG_X86) || defined(CONFIG_PPC)
 #define LZO_USE_CTZ32	1
-#elif defined(CONFIG_ARM) && (__LINUX_ARM_ARCH__ >= 5)
+#elif defined(CONFIG_ARM)
+#if (__LINUX_ARM_ARCH__ >= 5)
 #define LZO_USE_CTZ32	1
 #endif
+#if (__LINUX_ARM_ARCH__ >= 6) && defined(CONFIG_THUMB2_KERNEL)
+#define LZO_USE_CTZ64	1
+#endif
+#endif
 
 #define M1_MAX_OFFSET	0x0400
 #define M2_MAX_OFFSET	0x0800
-- 
2.16.4


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

* [PATCH 5/7] lib/lzo: fast 8-byte copy on arm64
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
                   ` (3 preceding siblings ...)
  2018-11-27 16:19 ` [PATCH 4/7] lib/lzo: 64-bit CTZ on arm64 Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-27 16:19 ` [PATCH 6/7] lib/lzo: implement run-length encoding Dave Rodgman
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

From: Matt Sealey <matt.sealey@arm.com>

Enable faster 8-byte copies on arm64.

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
Signed-off-by: Matt Sealey <matt.sealey@arm.com>
---
 lib/lzo/lzodefs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index c8965dc181df..06fa83a38e0a 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -15,7 +15,7 @@
 
 #define COPY4(dst, src)	\
 		put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
-#if defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
 #define COPY8(dst, src)	\
 		put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst))
 #else
-- 
2.16.4


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

* [PATCH 4/7] lib/lzo: 64-bit CTZ on arm64
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
                   ` (2 preceding siblings ...)
  2018-11-27 16:19 ` [PATCH 3/7] lib/lzo: enable 64-bit CTZ on Arm Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-27 16:19 ` [PATCH 5/7] lib/lzo: fast 8-byte copy " Dave Rodgman
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

From: Matt Sealey <matt.sealey@arm.com>

LZO leaves some performance on the table by not realising that arm64 can
optimize count-trailing-zeros bit operations.

Add CONFIG_ARM64 to the checked definitions alongside CONFIG_X86_64 to
enable the use of rbit/clz instructions on full 64-bit quantities.

Signed-off-by: Matt Sealey <matt.sealey@arm.com>
Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
---
 lib/lzo/lzodefs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index c0193f726db0..c8965dc181df 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -28,7 +28,7 @@
 
 #if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
 #error "conflicting endian definitions"
-#elif defined(CONFIG_X86_64)
+#elif defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
 #define LZO_USE_CTZ64	1
 #define LZO_USE_CTZ32	1
 #elif defined(CONFIG_X86) || defined(CONFIG_PPC)
-- 
2.16.4


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

* [PATCH 6/7] lib/lzo: implement run-length encoding
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
                   ` (4 preceding siblings ...)
  2018-11-27 16:19 ` [PATCH 5/7] lib/lzo: fast 8-byte copy " Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-29  3:08   ` Sergey Senozhatsky
  2018-11-27 16:19 ` [PATCH 7/7] lib/lzo: separate lzo-rle from lzo Dave Rodgman
  2018-11-29  4:46 ` [PATCH v2 0/7] lib/lzo: performance improvements Sergey Senozhatsky
  7 siblings, 1 reply; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

When using zram, we frequently encounter long runs of zero bytes.
This adds a special case which identifies runs of zeros and encodes
them using run-length encoding.

This is faster for both compression and decompresion. For
high-entropy data which doesn't hit this case, impact is minimal.

Compression ratio is within a few percent in all cases.

This modifies the bitstream in a way which is backwards compatible
(i.e., we can decompress old bitstreams, but old versions of lzo
cannot decompress new bitstreams).

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
---
 Documentation/lzo.txt           | 35 ++++++++++++---
 include/linux/lzo.h             |  2 +-
 lib/lzo/lzo1x_compress.c        | 98 ++++++++++++++++++++++++++++++++++++-----
 lib/lzo/lzo1x_decompress_safe.c | 75 +++++++++++++++++++++----------
 lib/lzo/lzodefs.h               | 12 ++++-
 5 files changed, 180 insertions(+), 42 deletions(-)

diff --git a/Documentation/lzo.txt b/Documentation/lzo.txt
index 6fa6a93d0949..306c60344ca7 100644
--- a/Documentation/lzo.txt
+++ b/Documentation/lzo.txt
@@ -78,16 +78,30 @@ Description
      is an implementation design choice independent on the algorithm or
      encoding.
 
+Versions
+
+0: Original version
+1: LZO-RLE
+
+Version 1 of LZO implements an extension to encode runs of zeros using run
+length encoding. This improves speed for data with many zeros, which is a
+common case for zram. This modifies the bitstream in a backwards compatible way
+(v1 can correctly decompress v0 compressed data, but v0 cannot read v1 data).
+
 Byte sequences
 ==============
 
   First byte encoding::
 
-      0..17   : follow regular instruction encoding, see below. It is worth
-                noting that codes 16 and 17 will represent a block copy from
-                the dictionary which is empty, and that they will always be
+      0..16   : follow regular instruction encoding, see below. It is worth
+                noting that code 16 will represent a block copy from the
+                dictionary which is empty, and that it will always be
                 invalid at this place.
 
+      17      : bitstream version. If the first byte is 17, the next byte
+                gives the bitstream version. If the first byte is not 17,
+                the bitstream version is 0.
+
       18..21  : copy 0..3 literals
                 state = (byte - 17) = 0..3  [ copy <state> literals ]
                 skip byte
@@ -140,6 +154,11 @@ Byte sequences
            state = S (copy S literals after this block)
            End of stream is reached if distance == 16384
 
+        In version 1, this instruction is also used to encode a run of zeros if
+        distance = 0xbfff, i.e. H = 1 and the D bits are all 1.
+           In this case, it is followed by a fourth byte, X.
+           run length = ((X << 3) | (0 0 0 0 0 L L L)) + 4.
+
       0 0 1 L L L L L  (32..63)
            Copy of small block within 16kB distance (preferably less than 34B)
            length = 2 + (L ?: 31 + (zero_bytes * 255) + non_zero_byte)
@@ -165,7 +184,9 @@ Authors
 =======
 
   This document was written by Willy Tarreau <w@1wt.eu> on 2014/07/19 during an
-  analysis of the decompression code available in Linux 3.16-rc5. The code is
-  tricky, it is possible that this document contains mistakes or that a few
-  corner cases were overlooked. In any case, please report any doubt, fix, or
-  proposed updates to the author(s) so that the document can be updated.
+  analysis of the decompression code available in Linux 3.16-rc5, and updated
+  by Dave Rodgman <dave.rodgman@arm.com> on 2018/10/30 to introduce run-length
+  encoding. The code is tricky, it is possible that this document contains
+  mistakes or that a few corner cases were overlooked. In any case, please
+  report any doubt, fix, or proposed updates to the author(s) so that the
+  document can be updated.
diff --git a/include/linux/lzo.h b/include/linux/lzo.h
index 2ae27cb89927..547a86c71e1b 100644
--- a/include/linux/lzo.h
+++ b/include/linux/lzo.h
@@ -18,7 +18,7 @@
 #define LZO1X_1_MEM_COMPRESS	(8192 * sizeof(unsigned short))
 #define LZO1X_MEM_COMPRESS	LZO1X_1_MEM_COMPRESS
 
-#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)
+#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3 + 2)
 
 /* This requires 'wrkmem' of size LZO1X_1_MEM_COMPRESS */
 int lzo1x_1_compress(const unsigned char *src, size_t src_len,
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
index 82fb5571ce5e..fa8d4ff38531 100644
--- a/lib/lzo/lzo1x_compress.c
+++ b/lib/lzo/lzo1x_compress.c
@@ -20,7 +20,7 @@
 static noinline size_t
 lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 		    unsigned char *out, size_t *out_len,
-		    size_t ti, void *wrkmem)
+		    size_t ti, void *wrkmem, signed char *state_offset)
 {
 	const unsigned char *ip;
 	unsigned char *op;
@@ -38,24 +38,82 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 		const unsigned char *m_pos;
 		size_t t, m_len, m_off;
 		u32 dv;
+		u32 run_length = 0;
 literal:
 		ip += 1 + ((ip - ii) >> 5);
 next:
 		if (unlikely(ip >= ip_end))
 			break;
 		dv = get_unaligned_le32(ip);
-		t = ((dv * 0x1824429d) >> (32 - D_BITS)) & D_MASK;
-		m_pos = in + dict[t];
-		dict[t] = (lzo_dict_t) (ip - in);
-		if (unlikely(dv != get_unaligned_le32(m_pos)))
-			goto literal;
+
+		if (dv == 0) {
+			const unsigned char *ir = ip + 4;
+			const unsigned char *limit = ip_end
+				< (ip + MAX_ZERO_RUN_LENGTH + 1)
+				? ip_end : ip + MAX_ZERO_RUN_LENGTH + 1;
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && \
+	defined(LZO_FAST_64BIT_MEMORY_ACCESS)
+			u64 dv64;
+
+			for (; (ir + 32) <= limit; ir += 32) {
+				dv64 = get_unaligned((u64 *)ir);
+				dv64 |= get_unaligned((u64 *)ir + 1);
+				dv64 |= get_unaligned((u64 *)ir + 2);
+				dv64 |= get_unaligned((u64 *)ir + 3);
+				if (dv64)
+					break;
+			}
+			for (; (ir + 8) <= limit; ir += 8) {
+				dv64 = get_unaligned((u64 *)ir);
+				if (dv64) {
+#  if defined(__LITTLE_ENDIAN)
+					ir += __builtin_ctzll(dv64) >> 3;
+#  elif defined(__BIG_ENDIAN)
+					ir += __builtin_clzll(dv64) >> 3;
+#  else
+#    error "missing endian definition"
+#  endif
+					break;
+				}
+			}
+#else
+			while ((ir < (const unsigned char *)
+					ALIGN((uintptr_t)ir, 4)) &&
+					(ir < limit) && (*ir == 0))
+				ir++;
+			for (; (ir + 4) <= limit; ir += 4) {
+				dv = *((u32 *)ir);
+				if (dv) {
+#  if defined(__LITTLE_ENDIAN)
+					ir += __builtin_ctz(dv) >> 3;
+#  elif defined(__BIG_ENDIAN)
+					ir += __builtin_clz(dv) >> 3;
+#  else
+#    error "missing endian definition"
+#  endif
+					break;
+				}
+			}
+#endif
+			while (likely(ir < limit) && unlikely(*ir == 0))
+				ir++;
+			run_length = ir - ip;
+			if (run_length > MAX_ZERO_RUN_LENGTH)
+				run_length = MAX_ZERO_RUN_LENGTH;
+		} else {
+			t = ((dv * 0x1824429d) >> (32 - D_BITS)) & D_MASK;
+			m_pos = in + dict[t];
+			dict[t] = (lzo_dict_t) (ip - in);
+			if (unlikely(dv != get_unaligned_le32(m_pos)))
+				goto literal;
+		}
 
 		ii -= ti;
 		ti = 0;
 		t = ip - ii;
 		if (t != 0) {
 			if (t <= 3) {
-				op[-2] |= t;
+				op[*state_offset] |= t;
 				COPY4(op, ii);
 				op += t;
 			} else if (t <= 16) {
@@ -86,6 +144,17 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 			}
 		}
 
+		if (unlikely(run_length)) {
+			ip += run_length;
+			run_length -= MIN_ZERO_RUN_LENGTH;
+			put_unaligned_le32((run_length << 21) | 0xfffc18
+					   | (run_length & 0x7), op);
+			op += 4;
+			run_length = 0;
+			*state_offset = -3;
+			goto finished_writing_instruction;
+		}
+
 		m_len = 4;
 		{
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ64)
@@ -168,7 +237,6 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 
 		m_off = ip - m_pos;
 		ip += m_len;
-		ii = ip;
 		if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) {
 			m_off -= 1;
 			*op++ = (((m_len - 1) << 5) | ((m_off & 7) << 2));
@@ -205,6 +273,9 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 			*op++ = (m_off << 2);
 			*op++ = (m_off >> 6);
 		}
+		*state_offset = -2;
+finished_writing_instruction:
+		ii = ip;
 		goto next;
 	}
 	*out_len = op - out;
@@ -219,6 +290,12 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len,
 	unsigned char *op = out;
 	size_t l = in_len;
 	size_t t = 0;
+	signed char state_offset = -2;
+
+	// LZO v0 will never write 17 as first byte,
+	// so this is used to version the bitstream
+	*op++ = 17;
+	*op++ = LZO_VERSION;
 
 	while (l > 20) {
 		size_t ll = l <= (M4_MAX_OFFSET + 1) ? l : (M4_MAX_OFFSET + 1);
@@ -227,7 +304,8 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len,
 			break;
 		BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS);
 		memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t));
-		t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem);
+		t = lzo1x_1_do_compress(ip, ll, op, out_len,
+					t, wrkmem, &state_offset);
 		ip += ll;
 		op += *out_len;
 		l  -= ll;
@@ -240,7 +318,7 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len,
 		if (op == out && t <= 238) {
 			*op++ = (17 + t);
 		} else if (t <= 3) {
-			op[-2] |= t;
+			op[state_offset] |= t;
 		} else if (t <= 18) {
 			*op++ = (t - 3);
 		} else {
diff --git a/lib/lzo/lzo1x_decompress_safe.c b/lib/lzo/lzo1x_decompress_safe.c
index aa95d3066b7d..b8f88d5ea3ff 100644
--- a/lib/lzo/lzo1x_decompress_safe.c
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -46,11 +46,23 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 	const unsigned char * const ip_end = in + in_len;
 	unsigned char * const op_end = out + *out_len;
 
+	unsigned char bitstream_version;
+
 	op = out;
 	ip = in;
 
 	if (unlikely(in_len < 3))
 		goto input_overrun;
+
+	if (likely(*ip == 17)) {
+		bitstream_version = ip[1];
+		ip += 2;
+		if (unlikely(in_len < 5))
+			goto input_overrun;
+	} else {
+		bitstream_version = 0;
+	}
+
 	if (*ip > 17) {
 		t = *ip++ - 17;
 		if (t < 4) {
@@ -151,32 +163,49 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 			m_pos -= next >> 2;
 			next &= 3;
 		} else {
-			m_pos = op;
-			m_pos -= (t & 8) << 11;
-			t = (t & 7) + (3 - 1);
-			if (unlikely(t == 2)) {
-				size_t offset;
-				const unsigned char *ip_last = ip;
+			NEED_IP(2);
+			next = get_unaligned_le16(ip);
+			if (((next & 0xfffc) == 0xfffc) &&
+			    ((t & 0xf8) == 0x18) &&
+			    likely(bitstream_version)) {
+				NEED_IP(3);
+				t &= 7;
+				t |= ip[2] << 3;
+				t += MIN_ZERO_RUN_LENGTH;
+				NEED_OP(t);
+				memset(op, 0, t);
+				op += t;
+				next &= 3;
+				ip += 3;
+				goto match_next;
+			} else {
+				m_pos = op;
+				m_pos -= (t & 8) << 11;
+				t = (t & 7) + (3 - 1);
+				if (unlikely(t == 2)) {
+					size_t offset;
+					const unsigned char *ip_last = ip;
 
-				while (unlikely(*ip == 0)) {
-					ip++;
-					NEED_IP(1);
-				}
-				offset = ip - ip_last;
-				if (unlikely(offset > MAX_255_COUNT))
-					return LZO_E_ERROR;
+					while (unlikely(*ip == 0)) {
+						ip++;
+						NEED_IP(1);
+					}
+					offset = ip - ip_last;
+					if (unlikely(offset > MAX_255_COUNT))
+						return LZO_E_ERROR;
 
-				offset = (offset << 8) - offset;
-				t += offset + 7 + *ip++;
-				NEED_IP(2);
+					offset = (offset << 8) - offset;
+					t += offset + 7 + *ip++;
+					NEED_IP(2);
+					next = get_unaligned_le16(ip);
+				}
+				ip += 2;
+				m_pos -= next >> 2;
+				next &= 3;
+				if (m_pos == op)
+					goto eof_found;
+				m_pos -= 0x4000;
 			}
-			next = get_unaligned_le16(ip);
-			ip += 2;
-			m_pos -= next >> 2;
-			next &= 3;
-			if (m_pos == op)
-				goto eof_found;
-			m_pos -= 0x4000;
 		}
 		TEST_LB(m_pos);
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index 06fa83a38e0a..682359058b3c 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -13,6 +13,12 @@
  */
 
 
+/* Version
+ * 0: original lzo version
+ * 1: lzo with support for RLE
+ */
+#define LZO_VERSION 1
+
 #define COPY4(dst, src)	\
 		put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
 #if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
@@ -31,6 +37,7 @@
 #elif defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
 #define LZO_USE_CTZ64	1
 #define LZO_USE_CTZ32	1
+#define LZO_FAST_64BIT_MEMORY_ACCESS
 #elif defined(CONFIG_X86) || defined(CONFIG_PPC)
 #define LZO_USE_CTZ32	1
 #elif defined(CONFIG_ARM)
@@ -45,7 +52,7 @@
 #define M1_MAX_OFFSET	0x0400
 #define M2_MAX_OFFSET	0x0800
 #define M3_MAX_OFFSET	0x4000
-#define M4_MAX_OFFSET	0xbfff
+#define M4_MAX_OFFSET	0xbffe
 
 #define M1_MIN_LEN	2
 #define M1_MAX_LEN	2
@@ -61,6 +68,9 @@
 #define M3_MARKER	32
 #define M4_MARKER	16
 
+#define MIN_ZERO_RUN_LENGTH	4
+#define MAX_ZERO_RUN_LENGTH	(2047 + MIN_ZERO_RUN_LENGTH)
+
 #define lzo_dict_t      unsigned short
 #define D_BITS		13
 #define D_SIZE		(1u << D_BITS)
-- 
2.16.4


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

* [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
                   ` (5 preceding siblings ...)
  2018-11-27 16:19 ` [PATCH 6/7] lib/lzo: implement run-length encoding Dave Rodgman
@ 2018-11-27 16:19 ` Dave Rodgman
  2018-11-29  4:43   ` Sergey Senozhatsky
  2018-11-29  4:46 ` [PATCH v2 0/7] lib/lzo: performance improvements Sergey Senozhatsky
  7 siblings, 1 reply; 19+ messages in thread
From: Dave Rodgman @ 2018-11-27 16:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: nd, herbert, davem, Matt Sealey, nitingupta910, rpurdie, markus,
	minchan, sergey.senozhatsky.work, sonnyrao, gregkh, akpm

To prevent any issues with persistent data, separate lzo-rle
from lzo so that it is treated as a separate algorithm, and
lzo is still available.

Use lzo-rle as the default algorithm for
zram.

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
---
 Documentation/lzo.txt         |  12 ++-
 crypto/Makefile               |   2 +-
 crypto/lzo-rle.c              | 175 ++++++++++++++++++++++++++++++++++++++++++
 crypto/tcrypt.c               |   4 +-
 drivers/block/zram/zcomp.c    |   1 +
 drivers/block/zram/zram_drv.c |   2 +-
 include/linux/lzo.h           |   4 +
 lib/lzo/lzo1x_compress.c      |  42 +++++++---
 lib/lzo/lzodefs.h             |   3 +-
 9 files changed, 227 insertions(+), 18 deletions(-)
 create mode 100644 crypto/lzo-rle.c

diff --git a/Documentation/lzo.txt b/Documentation/lzo.txt
index 306c60344ca7..f79934225d8d 100644
--- a/Documentation/lzo.txt
+++ b/Documentation/lzo.txt
@@ -88,6 +88,10 @@ length encoding. This improves speed for data with many zeros, which is a
 common case for zram. This modifies the bitstream in a backwards compatible way
 (v1 can correctly decompress v0 compressed data, but v0 cannot read v1 data).
 
+For maximum compatibility, both versions are available under different names
+(lzo and lzo-rle). Differences in the encoding are noted in this document with
+e.g.: version 1 only.
+
 Byte sequences
 ==============
 
@@ -99,8 +103,8 @@ Byte sequences
                 invalid at this place.
 
       17      : bitstream version. If the first byte is 17, the next byte
-                gives the bitstream version. If the first byte is not 17,
-                the bitstream version is 0.
+                gives the bitstream version (version 1 only). If the first byte
+                is not 17, the bitstream version is 0.
 
       18..21  : copy 0..3 literals
                 state = (byte - 17) = 0..3  [ copy <state> literals ]
@@ -154,8 +158,8 @@ Byte sequences
            state = S (copy S literals after this block)
            End of stream is reached if distance == 16384
 
-        In version 1, this instruction is also used to encode a run of zeros if
-        distance = 0xbfff, i.e. H = 1 and the D bits are all 1.
+        In version 1 only, this instruction is also used to encode a run of
+        zeros if distance = 0xbfff, i.e. H = 1 and the D bits are all 1.
            In this case, it is followed by a fourth byte, X.
            run length = ((X << 3) | (0 0 0 0 0 L L L)) + 4.
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 5e789dc2d4fd..23491b70e601 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -127,7 +127,7 @@ obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
-obj-$(CONFIG_CRYPTO_LZO) += lzo.o
+obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
 obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
 obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
 obj-$(CONFIG_CRYPTO_842) += 842.o
diff --git a/crypto/lzo-rle.c b/crypto/lzo-rle.c
new file mode 100644
index 000000000000..ea9c75b1db49
--- /dev/null
+++ b/crypto/lzo-rle.c
@@ -0,0 +1,175 @@
+/*
+ * Cryptographic API.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/lzo.h>
+#include <crypto/internal/scompress.h>
+
+struct lzorle_ctx {
+	void *lzorle_comp_mem;
+};
+
+static void *lzorle_alloc_ctx(struct crypto_scomp *tfm)
+{
+	void *ctx;
+
+	ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	return ctx;
+}
+
+static int lzorle_init(struct crypto_tfm *tfm)
+{
+	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->lzorle_comp_mem = lzorle_alloc_ctx(NULL);
+	if (IS_ERR(ctx->lzorle_comp_mem))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void lzorle_free_ctx(struct crypto_scomp *tfm, void *ctx)
+{
+	kvfree(ctx);
+}
+
+static void lzorle_exit(struct crypto_tfm *tfm)
+{
+	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	lzorle_free_ctx(NULL, ctx->lzorle_comp_mem);
+}
+
+static int __lzorle_compress(const u8 *src, unsigned int slen,
+			  u8 *dst, unsigned int *dlen, void *ctx)
+{
+	size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
+	int err;
+
+	err = lzorle1x_1_compress(src, slen, dst, &tmp_len, ctx);
+
+	if (err != LZO_E_OK)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return 0;
+}
+
+static int lzorle_compress(struct crypto_tfm *tfm, const u8 *src,
+			unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	return __lzorle_compress(src, slen, dst, dlen, ctx->lzorle_comp_mem);
+}
+
+static int lzorle_scompress(struct crypto_scomp *tfm, const u8 *src,
+			 unsigned int slen, u8 *dst, unsigned int *dlen,
+			 void *ctx)
+{
+	return __lzorle_compress(src, slen, dst, dlen, ctx);
+}
+
+static int __lzorle_decompress(const u8 *src, unsigned int slen,
+			    u8 *dst, unsigned int *dlen)
+{
+	int err;
+	size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
+
+	err = lzo1x_decompress_safe(src, slen, dst, &tmp_len);
+
+	if (err != LZO_E_OK)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return 0;
+}
+
+static int lzorle_decompress(struct crypto_tfm *tfm, const u8 *src,
+			  unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	return __lzorle_decompress(src, slen, dst, dlen);
+}
+
+static int lzorle_sdecompress(struct crypto_scomp *tfm, const u8 *src,
+			   unsigned int slen, u8 *dst, unsigned int *dlen,
+			   void *ctx)
+{
+	return __lzorle_decompress(src, slen, dst, dlen);
+}
+
+static struct crypto_alg alg = {
+	.cra_name		= "lzo-rle",
+	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
+	.cra_ctxsize		= sizeof(struct lzorle_ctx),
+	.cra_module		= THIS_MODULE,
+	.cra_init		= lzorle_init,
+	.cra_exit		= lzorle_exit,
+	.cra_u			= { .compress = {
+	.coa_compress		= lzorle_compress,
+	.coa_decompress		= lzorle_decompress } }
+};
+
+static struct scomp_alg scomp = {
+	.alloc_ctx		= lzorle_alloc_ctx,
+	.free_ctx		= lzorle_free_ctx,
+	.compress		= lzorle_scompress,
+	.decompress		= lzorle_sdecompress,
+	.base			= {
+		.cra_name	= "lzo-rle",
+		.cra_driver_name = "lzo-rle-scomp",
+		.cra_module	 = THIS_MODULE,
+	}
+};
+
+static int __init lzorle_mod_init(void)
+{
+	int ret;
+
+	ret = crypto_register_alg(&alg);
+	if (ret)
+		return ret;
+
+	ret = crypto_register_scomp(&scomp);
+	if (ret) {
+		crypto_unregister_alg(&alg);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void __exit lzorle_mod_fini(void)
+{
+	crypto_unregister_alg(&alg);
+	crypto_unregister_scomp(&scomp);
+}
+
+module_init(lzorle_mod_init);
+module_exit(lzorle_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO-RLE Compression Algorithm");
+MODULE_ALIAS_CRYPTO("lzo-rle");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 0590a9204562..c1c56c9771cf 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -76,8 +76,8 @@ static char *check[] = {
 	"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
 	"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
 	"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
-	"lzo", "cts", "sha3-224", "sha3-256", "sha3-384", "sha3-512",
-	"streebog256", "streebog512",
+	"lzo", "lzo-rle", "cts", "sha3-224", "sha3-256", "sha3-384",
+	"sha3-512", "streebog256", "streebog512",
 	NULL
 };
 
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 4ed0a78fdc09..4d9a38890965 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -20,6 +20,7 @@
 
 static const char * const backends[] = {
 	"lzo",
+	"lzo-rle",
 #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
 	"lz4",
 #endif
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 4879595200e1..984072868422 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
 static DEFINE_MUTEX(zram_index_mutex);
 
 static int zram_major;
-static const char *default_compressor = "lzo";
+static const char *default_compressor = "lzo-rle";
 
 /* Module params (documentation at end) */
 static unsigned int num_devices = 1;
diff --git a/include/linux/lzo.h b/include/linux/lzo.h
index 547a86c71e1b..e95c7d1092b2 100644
--- a/include/linux/lzo.h
+++ b/include/linux/lzo.h
@@ -24,6 +24,10 @@
 int lzo1x_1_compress(const unsigned char *src, size_t src_len,
 		     unsigned char *dst, size_t *dst_len, void *wrkmem);
 
+/* This requires 'wrkmem' of size LZO1X_1_MEM_COMPRESS */
+int lzorle1x_1_compress(const unsigned char *src, size_t src_len,
+		     unsigned char *dst, size_t *dst_len, void *wrkmem);
+
 /* safe decompression with overrun testing */
 int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
 			  unsigned char *dst, size_t *dst_len);
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
index fa8d4ff38531..1a1cd5e84391 100644
--- a/lib/lzo/lzo1x_compress.c
+++ b/lib/lzo/lzo1x_compress.c
@@ -20,7 +20,8 @@
 static noinline size_t
 lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 		    unsigned char *out, size_t *out_len,
-		    size_t ti, void *wrkmem, signed char *state_offset)
+		    size_t ti, void *wrkmem, signed char *state_offset,
+		    const unsigned char bitstream_version)
 {
 	const unsigned char *ip;
 	unsigned char *op;
@@ -46,7 +47,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 			break;
 		dv = get_unaligned_le32(ip);
 
-		if (dv == 0) {
+		if (dv == 0 && bitstream_version) {
 			const unsigned char *ir = ip + 4;
 			const unsigned char *limit = ip_end
 				< (ip + MAX_ZERO_RUN_LENGTH + 1)
@@ -282,30 +283,36 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
 	return in_end - (ii - ti);
 }
 
-int lzo1x_1_compress(const unsigned char *in, size_t in_len,
+int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
 		     unsigned char *out, size_t *out_len,
-		     void *wrkmem)
+		     void *wrkmem, const unsigned char bitstream_version)
 {
 	const unsigned char *ip = in;
 	unsigned char *op = out;
 	size_t l = in_len;
 	size_t t = 0;
 	signed char state_offset = -2;
+	unsigned int m4_max_offset;
 
 	// LZO v0 will never write 17 as first byte,
 	// so this is used to version the bitstream
-	*op++ = 17;
-	*op++ = LZO_VERSION;
+	if (bitstream_version > 0) {
+		*op++ = 17;
+		*op++ = bitstream_version;
+		m4_max_offset = M4_MAX_OFFSET_V1;
+	} else {
+		m4_max_offset = M4_MAX_OFFSET_V0;
+	}
 
 	while (l > 20) {
-		size_t ll = l <= (M4_MAX_OFFSET + 1) ? l : (M4_MAX_OFFSET + 1);
+		size_t ll = l <= (m4_max_offset + 1) ? l : (m4_max_offset + 1);
 		uintptr_t ll_end = (uintptr_t) ip + ll;
 		if ((ll_end + ((t + ll) >> 5)) <= ll_end)
 			break;
 		BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS);
 		memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t));
-		t = lzo1x_1_do_compress(ip, ll, op, out_len,
-					t, wrkmem, &state_offset);
+		t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem,
+					&state_offset, bitstream_version);
 		ip += ll;
 		op += *out_len;
 		l  -= ll;
@@ -348,7 +355,24 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len,
 	*out_len = op - out;
 	return LZO_E_OK;
 }
+
+int lzo1x_1_compress(const unsigned char *in, size_t in_len,
+		     unsigned char *out, size_t *out_len,
+		     void *wrkmem)
+{
+	return lzogeneric1x_1_compress(in, in_len, out, out_len, wrkmem, 0);
+}
+
+int lzorle1x_1_compress(const unsigned char *in, size_t in_len,
+		     unsigned char *out, size_t *out_len,
+		     void *wrkmem)
+{
+	return lzogeneric1x_1_compress(in, in_len, out, out_len,
+				       wrkmem, LZO_VERSION);
+}
+
 EXPORT_SYMBOL_GPL(lzo1x_1_compress);
+EXPORT_SYMBOL_GPL(lzorle1x_1_compress);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("LZO1X-1 Compressor");
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
index 682359058b3c..c0657441a35d 100644
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -52,7 +52,8 @@
 #define M1_MAX_OFFSET	0x0400
 #define M2_MAX_OFFSET	0x0800
 #define M3_MAX_OFFSET	0x4000
-#define M4_MAX_OFFSET	0xbffe
+#define M4_MAX_OFFSET_V0	0xbfff
+#define M4_MAX_OFFSET_V1	0xbffe
 
 #define M1_MIN_LEN	2
 #define M1_MAX_LEN	2
-- 
2.16.4


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

* Re: [PATCH 2/7] lib/lzo: clean-up by introducing COPY16
  2018-11-27 16:19 ` [PATCH 2/7] lib/lzo: clean-up by introducing COPY16 Dave Rodgman
@ 2018-11-27 22:50   ` Andrew Morton
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Morton @ 2018-11-27 22:50 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sergey.senozhatsky.work, sonnyrao,
	gregkh

On Tue, 27 Nov 2018 16:19:31 +0000 Dave Rodgman <dave.rodgman@arm.com> wrote:

> From: Matt Sealey <matt.sealey@arm.com>
> 
> ...
>
> Signed-off-by: Matt Sealey <matt.sealey@arm.com>

Several of the From:Matt patches were missing your Signed-off-by:.  I
added it.

[patch 5/7] had the signoffs in an inappropriate order - I switched
them.


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

* Re: [PATCH 6/7] lib/lzo: implement run-length encoding
  2018-11-27 16:19 ` [PATCH 6/7] lib/lzo: implement run-length encoding Dave Rodgman
@ 2018-11-29  3:08   ` Sergey Senozhatsky
  2018-11-29  3:11     ` Sergey Senozhatsky
  0 siblings, 1 reply; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-11-29  3:08 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sergey.senozhatsky.work, sonnyrao,
	gregkh, akpm

On (11/27/18 16:19), Dave Rodgman wrote:
>
> This modifies the bitstream in a way which is backwards compatible
> (i.e., we can decompress old bitstreams, but old versions of lzo
> cannot decompress new bitstreams).
>

Hmmm... Whoa. Help me understand this:

So a btrfs filesystem, compressed with the new lzo, say I run 4.21,
won't be readable at all once I reboot under 4.19?

What about compressed net traffic between servers running different
kernel version (one with new lzo, the other one with old lzo)?
XFRM can be compressed with lzo, can't it?

	-ss

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

* Re: [PATCH 6/7] lib/lzo: implement run-length encoding
  2018-11-29  3:08   ` Sergey Senozhatsky
@ 2018-11-29  3:11     ` Sergey Senozhatsky
  0 siblings, 0 replies; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-11-29  3:11 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sonnyrao, gregkh, akpm,
	Sergey Senozhatsky

On (11/29/18 12:08), Sergey Senozhatsky wrote:
> On (11/27/18 16:19), Dave Rodgman wrote:
> >
> > This modifies the bitstream in a way which is backwards compatible
> > (i.e., we can decompress old bitstreams, but old versions of lzo
> > cannot decompress new bitstreams).
> >
> 
> Hmmm... Whoa. Help me understand this:
> 
> So a btrfs filesystem, compressed with the new lzo, say I run 4.21,
> won't be readable at all once I reboot under 4.19?
> 
> What about compressed net traffic between servers running different
> kernel version (one with new lzo, the other one with old lzo)?
> XFRM can be compressed with lzo, can't it?

Ah, false alarm. Sorry for the noise!

You create a new lzo version in the next patch.

	-ss

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-27 16:19 ` [PATCH 7/7] lib/lzo: separate lzo-rle from lzo Dave Rodgman
@ 2018-11-29  4:43   ` Sergey Senozhatsky
  2018-11-29 10:21     ` Dave Rodgman
  2018-11-30 10:45     ` Dave Rodgman
  0 siblings, 2 replies; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-11-29  4:43 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sergey.senozhatsky.work, sonnyrao,
	gregkh, akpm

On (11/27/18 16:19), Dave Rodgman wrote:
>  Documentation/lzo.txt         |  12 ++-
>  crypto/Makefile               |   2 +-
>  crypto/lzo-rle.c              | 175 ++++++++++++++++++++++++++++++++++++++++++
>  crypto/tcrypt.c               |   4 +-
>  drivers/block/zram/zcomp.c    |   1 +
>  drivers/block/zram/zram_drv.c |   2 +-
>  include/linux/lzo.h           |   4 +
>  lib/lzo/lzo1x_compress.c      |  42 +++++++---
>  lib/lzo/lzodefs.h             |   3 +-
>  9 files changed, 227 insertions(+), 18 deletions(-)
>  create mode 100644 crypto/lzo-rle.c

[..]

> +static struct crypto_alg alg = {
> +	.cra_name		= "lzo-rle",
> +	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
> +	.cra_ctxsize		= sizeof(struct lzorle_ctx),
> +	.cra_module		= THIS_MODULE,
> +	.cra_init		= lzorle_init,
> +	.cra_exit		= lzorle_exit,
> +	.cra_u			= { .compress = {
> +	.coa_compress		= lzorle_compress,
> +	.coa_decompress		= lzorle_decompress } }
> +};

A nitpick:
  indentation for .compress assignment is a bit confusing, maybe.


[..]
> +++ b/drivers/block/zram/zcomp.c
> @@ -20,6 +20,7 @@
>  
>  static const char * const backends[] = {
>  	"lzo",
> +	"lzo-rle",
>  #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
>  	"lz4",
>  #endif

[..]

> +++ b/drivers/block/zram/zram_drv.c
> @@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
>  static DEFINE_MUTEX(zram_index_mutex);
>  
>  static int zram_major;
> -static const char *default_compressor = "lzo";
> +static const char *default_compressor = "lzo-rle";

OK, so it's not just "separate lzo-rle", it's also "switch zram to
a new compression algorithm by default". I'd say that usually I'd
expect this to be separate patches.

	-ss

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

* Re: [PATCH v2 0/7] lib/lzo: performance improvements
  2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
                   ` (6 preceding siblings ...)
  2018-11-27 16:19 ` [PATCH 7/7] lib/lzo: separate lzo-rle from lzo Dave Rodgman
@ 2018-11-29  4:46 ` Sergey Senozhatsky
  7 siblings, 0 replies; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-11-29  4:46 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sergey.senozhatsky.work, sonnyrao,
	gregkh, akpm

On (11/27/18 16:19), Dave Rodgman wrote:
> > Right. The number is data dependent. Not all swapped out pages can be
> > compressed; compressed pages that end up being >= zs_huge_class_size() are
> > considered incompressible and stored as it.
> > 
> > I'd say that on my setups around 50-60% of pages are incompressible.
> 
> So, just to give a bit more detail: the test setup was a Samsung
> Chromebook Pro, cycling through 80 tabs in Chrome. With lzo-rle, only
> 5% of pages increased in size, and 90% of pages compress to 75% of
> original size (or better). Mean compression ratio was 41%. Importantly
> for lzo-rle, there are a lot of low-entropy pages where it can do well:
> in total about 20% of the data is zeros forming part of a run of 4 or
> more bytes.
> 
> As a quick summary of the impact of these patches on bigger chunks of
> data, I've compared the performance of four different variants of lzo
> on two large (~40 MB) files. The numbers show round-trip throughput
> in MB/s:
> 
> Variant         | Low-entropy | High-entropy
> Current lzo     |  242        | 157
> Arm opts        |  290        | 159
> RLE             |  876        | 151
> Arm opts + RLE  | 1150        | 181
> 
> So both the Arm optimisations (8,16-byte copy & CTZ patches), and the
> RLE implementation make a significant contribution to the overall
> performance uplift.

Cool!

	-ss

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-29  4:43   ` Sergey Senozhatsky
@ 2018-11-29 10:21     ` Dave Rodgman
  2018-11-29 20:32       ` Andrew Morton
  2018-11-30  3:05       ` Sergey Senozhatsky
  2018-11-30 10:45     ` Dave Rodgman
  1 sibling, 2 replies; 19+ messages in thread
From: Dave Rodgman @ 2018-11-29 10:21 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: linux-kernel, nd, herbert, davem, Matt Sealey, nitingupta910,
	rpurdie, markus, minchan, sonnyrao, gregkh, akpm



On 29/11/2018 4:43 am, Sergey Senozhatsky wrote:
> On (11/27/18 16:19), Dave Rodgman wrote:
>>   Documentation/lzo.txt         |  12 ++-
>>   crypto/Makefile               |   2 +-
>>   crypto/lzo-rle.c              | 175 ++++++++++++++++++++++++++++++++++++++++++
>>   crypto/tcrypt.c               |   4 +-
>>   drivers/block/zram/zcomp.c    |   1 +
>>   drivers/block/zram/zram_drv.c |   2 +-
>>   include/linux/lzo.h           |   4 +
>>   lib/lzo/lzo1x_compress.c      |  42 +++++++---
>>   lib/lzo/lzodefs.h             |   3 +-
>>   9 files changed, 227 insertions(+), 18 deletions(-)
>>   create mode 100644 crypto/lzo-rle.c
> 
> [..]
> 
>> +static struct crypto_alg alg = {
>> +	.cra_name		= "lzo-rle",
>> +	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
>> +	.cra_ctxsize		= sizeof(struct lzorle_ctx),
>> +	.cra_module		= THIS_MODULE,
>> +	.cra_init		= lzorle_init,
>> +	.cra_exit		= lzorle_exit,
>> +	.cra_u			= { .compress = {
>> +	.coa_compress		= lzorle_compress,
>> +	.coa_decompress		= lzorle_decompress } }
>> +};
> 
> A nitpick:
>    indentation for .compress assignment is a bit confusing, maybe.

Agreed - I've copied this directly from crypto/lzo.c though, so I 
retained the same style. Cleanup could be a separate patch.

> [..]
>> +++ b/drivers/block/zram/zcomp.c
>> @@ -20,6 +20,7 @@
>>   
>>   static const char * const backends[] = {
>>   	"lzo",
>> +	"lzo-rle",
>>   #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
>>   	"lz4",
>>   #endif
> 
> [..]
> 
>> +++ b/drivers/block/zram/zram_drv.c
>> @@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
>>   static DEFINE_MUTEX(zram_index_mutex);
>>   
>>   static int zram_major;
>> -static const char *default_compressor = "lzo";
>> +static const char *default_compressor = "lzo-rle";
> 
> OK, so it's not just "separate lzo-rle", it's also "switch zram to
> a new compression algorithm by default". I'd say that usually I'd
> expect this to be separate patches.

Yes, fair point. akpm has picked this up now though, so probably a bit 
late to break it out into a separate patch?

Dave

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-29 10:21     ` Dave Rodgman
@ 2018-11-29 20:32       ` Andrew Morton
  2018-11-30  3:05       ` Sergey Senozhatsky
  1 sibling, 0 replies; 19+ messages in thread
From: Andrew Morton @ 2018-11-29 20:32 UTC (permalink / raw)
  To: Dave Rodgman
  Cc: Sergey Senozhatsky, linux-kernel, nd, herbert, davem,
	Matt Sealey, nitingupta910, rpurdie, markus, minchan, sonnyrao,
	gregkh

On Thu, 29 Nov 2018 10:21:53 +0000 Dave Rodgman <dave.rodgman@arm.com> wrote:

> >> @@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
> >>   static DEFINE_MUTEX(zram_index_mutex);
> >>   
> >>   static int zram_major;
> >> -static const char *default_compressor = "lzo";
> >> +static const char *default_compressor = "lzo-rle";
> > 
> > OK, so it's not just "separate lzo-rle", it's also "switch zram to
> > a new compression algorithm by default". I'd say that usually I'd
> > expect this to be separate patches.
> 
> Yes, fair point. akpm has picked this up now though, so probably a bit 
> late to break it out into a separate patch?

That's fine.  akpm is flexible ;)  Whatever produces the best overall
result in the permanent record, please.


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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-29 10:21     ` Dave Rodgman
  2018-11-29 20:32       ` Andrew Morton
@ 2018-11-30  3:05       ` Sergey Senozhatsky
  1 sibling, 0 replies; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-11-30  3:05 UTC (permalink / raw)
  To: Dave Rodgman, Minchan Kim
  Cc: Sergey Senozhatsky, linux-kernel, nd, herbert, davem,
	Matt Sealey, nitingupta910, rpurdie, markus, sonnyrao, gregkh,
	akpm

On (11/29/18 10:21), Dave Rodgman wrote:
> > [..]
> >> +++ b/drivers/block/zram/zcomp.c
> >> @@ -20,6 +20,7 @@
> >>   
> >>   static const char * const backends[] = {
> >>   	"lzo",
> >> +	"lzo-rle",
> >>   #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
> >>   	"lz4",
> >>   #endif
> > 
> > [..]
> > 
> >> +++ b/drivers/block/zram/zram_drv.c
> >> @@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
> >>   static DEFINE_MUTEX(zram_index_mutex);
> >>   
> >>   static int zram_major;
> >> -static const char *default_compressor = "lzo";
> >> +static const char *default_compressor = "lzo-rle";
> > 
> > OK, so it's not just "separate lzo-rle", it's also "switch zram to
> > a new compression algorithm by default". I'd say that usually I'd
> > expect this to be separate patches.
> 
> Yes, fair point. akpm has picked this up now though, so probably a bit
> late to break it out into a separate patch?

Andrew accepts patches to patches, and patches to patches to patches, etc.
He is very flexible :)

I don't have a very strong opinion. Would probably be better to split
it, tho. Let's hear from Minchan.

	-ss

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-29  4:43   ` Sergey Senozhatsky
  2018-11-29 10:21     ` Dave Rodgman
@ 2018-11-30 10:45     ` Dave Rodgman
  2018-12-03  2:40       ` Sergey Senozhatsky
  1 sibling, 1 reply; 19+ messages in thread
From: Dave Rodgman @ 2018-11-30 10:45 UTC (permalink / raw)
  To: Sergey Senozhatsky, herbert, linux-kernel, davem; +Cc: nd

On 29/11/2018 4:43 am, Sergey Senozhatsky wrote:
> On (11/27/18 16:19), Dave Rodgman wrote:> 
>> +static struct crypto_alg alg = {
>> +	.cra_name		= "lzo-rle",
>> +	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
>> +	.cra_ctxsize		= sizeof(struct lzorle_ctx),
>> +	.cra_module		= THIS_MODULE,
>> +	.cra_init		= lzorle_init,
>> +	.cra_exit		= lzorle_exit,
>> +	.cra_u			= { .compress = {
>> +	.coa_compress		= lzorle_compress,
>> +	.coa_decompress		= lzorle_decompress } }
>> +};
> 
> A nitpick:
>    indentation for .compress assignment is a bit confusing, maybe.

Looking a bit more closely, these structs are formatted fairly 
inconsistently in the crypto directory. So, lzo-rle is consistent with 
what lzo does... but various other files do it differently.

I'm happy to submit a whitespace cleanup patch if people would like, and 
get everything in that directory consistent (i.e. adopt a style similar 
to the example below)?

static struct scomp_alg scomp = {
         .alloc_ctx              = lzorle_alloc_ctx,
         .free_ctx               = lzorle_free_ctx,
         .compress               = lzorle_scompress,
         .decompress             = lzorle_sdecompress,
         .base                   = {
                 .cra_name               = "lzo-rle",
                 .cra_driver_name        = "lzo-rle-scomp",
                 .cra_module             = THIS_MODULE,
         }
};

Dave

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-11-30 10:45     ` Dave Rodgman
@ 2018-12-03  2:40       ` Sergey Senozhatsky
  2018-12-03  2:53         ` Herbert Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Sergey Senozhatsky @ 2018-12-03  2:40 UTC (permalink / raw)
  To: Dave Rodgman, Herbert Xu, David S. Miller
  Cc: Sergey Senozhatsky, linux-kernel, linux-crypto, nd

On (11/30/18 10:45), Dave Rodgman wrote:
> Looking a bit more closely, these structs are formatted fairly 
> inconsistently in the crypto directory. So, lzo-rle is consistent with 
> what lzo does... but various other files do it differently.
> 
> I'm happy to submit a whitespace cleanup patch if people would like, and 
> get everything in that directory consistent (i.e. adopt a style similar 
> to the example below)?

I'm not in any position to ask you to do this; white-space clean ups
are not very popular (it's OK for staging tree; not so much otherwise).
So we better ask David and Herbert.

> static struct scomp_alg scomp = {
>          .alloc_ctx              = lzorle_alloc_ctx,
>          .free_ctx               = lzorle_free_ctx,
>          .compress               = lzorle_scompress,
>          .decompress             = lzorle_sdecompress,
>          .base                   = {
>                  .cra_name               = "lzo-rle",
>                  .cra_driver_name        = "lzo-rle-scomp",
>                  .cra_module             = THIS_MODULE,
>          }
> };

Looks nice.

	-ss

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

* Re: [PATCH 7/7] lib/lzo: separate lzo-rle from lzo
  2018-12-03  2:40       ` Sergey Senozhatsky
@ 2018-12-03  2:53         ` Herbert Xu
  0 siblings, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2018-12-03  2:53 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Dave Rodgman, David S. Miller, linux-kernel, linux-crypto, nd

On Mon, Dec 03, 2018 at 11:40:19AM +0900, Sergey Senozhatsky wrote:
> 
> I'm not in any position to ask you to do this; white-space clean ups
> are not very popular (it's OK for staging tree; not so much otherwise).
> So we better ask David and Herbert.

I'm fine with white space cleanups.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

end of thread, other threads:[~2018-12-03  2:53 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-27 16:19 [PATCH v2 0/7] lib/lzo: performance improvements Dave Rodgman
2018-11-27 16:19 ` [PATCH 1/7] lib/lzo: tidy-up ifdefs Dave Rodgman
2018-11-27 16:19 ` [PATCH 2/7] lib/lzo: clean-up by introducing COPY16 Dave Rodgman
2018-11-27 22:50   ` Andrew Morton
2018-11-27 16:19 ` [PATCH 3/7] lib/lzo: enable 64-bit CTZ on Arm Dave Rodgman
2018-11-27 16:19 ` [PATCH 4/7] lib/lzo: 64-bit CTZ on arm64 Dave Rodgman
2018-11-27 16:19 ` [PATCH 5/7] lib/lzo: fast 8-byte copy " Dave Rodgman
2018-11-27 16:19 ` [PATCH 6/7] lib/lzo: implement run-length encoding Dave Rodgman
2018-11-29  3:08   ` Sergey Senozhatsky
2018-11-29  3:11     ` Sergey Senozhatsky
2018-11-27 16:19 ` [PATCH 7/7] lib/lzo: separate lzo-rle from lzo Dave Rodgman
2018-11-29  4:43   ` Sergey Senozhatsky
2018-11-29 10:21     ` Dave Rodgman
2018-11-29 20:32       ` Andrew Morton
2018-11-30  3:05       ` Sergey Senozhatsky
2018-11-30 10:45     ` Dave Rodgman
2018-12-03  2:40       ` Sergey Senozhatsky
2018-12-03  2:53         ` Herbert Xu
2018-11-29  4:46 ` [PATCH v2 0/7] lib/lzo: performance improvements Sergey Senozhatsky

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).