linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper
@ 2014-09-04 14:26 Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 01/12] hexdump: introduce test suite Andy Shevchenko
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

This introduces a new helper and switches current users to use it. All are
compiled tested, hexdump and kmemleak are tested by their test suits.

Changelog v4:
- hexdump is amended to return value from which we can check an overflow
 (patches 1/12 - 4/12)
- seq_hex_dump pushes bytes directly to buffer and returns an error in case of
  overflow (addresses Al Viro's comment)
- append Acked-by for patches 8/12 and 9/12
- convert more users (patches 10/12 - 12/12)

Changelog v3:
- append Mauro's Ack
- rebase on top of recent linux-next

Changelog v2:
- append Acked-by and Reviewed-by tags
- update commit messages in patches 3/5. and 5/5
- update line size to be 32 bytes instead of 16 in patch 3/5
- Joe found that output is changed in patch 4/5, thus I update commit message
  there

Andy Shevchenko (12):
  hexdump: introduce test suite
  hexdump: fix ascii column for the tail of a dump
  hexdump: do few calculations ahead
  hexdump: makes it return amount of bytes placed in buffer
  seq_file: provide an analogue of print_hex_dump()
  saa7164: convert to seq_hex_dump()
  crypto: qat - use seq_hex_dump() to dump buffers
  parisc: use seq_hex_dump() to dump buffers
  [S390] zcrypt: use seq_hex_dump() to dump buffers
  staging: unisys: use seq_hex_dump() to dump buffers
  kmemleak: use seq_hex_dump() to dump buffers
  wil6210: use seq_hex_dump() to dump buffers

 .../crypto/qat/qat_common/adf_transport_debug.c    |  16 +-
 drivers/media/pci/saa7164/saa7164-core.c           |  31 +---
 drivers/net/wireless/ath/wil6210/debugfs.c         |  32 +---
 drivers/parisc/ccio-dma.c                          |  14 +-
 drivers/parisc/sba_iommu.c                         |  11 +-
 drivers/s390/crypto/zcrypt_api.c                   |  10 +-
 .../unisys/visorchannel/visorchannel_funcs.c       |  26 +--
 fs/seq_file.c                                      |  50 ++++++
 include/linux/printk.h                             |   6 +-
 include/linux/seq_file.h                           |   4 +
 lib/Kconfig.debug                                  |   3 +
 lib/Makefile                                       |   4 +-
 lib/hexdump.c                                      | 105 +++++++-----
 lib/test-hexdump.c                                 | 180 +++++++++++++++++++++
 mm/kmemleak.c                                      |  21 +--
 15 files changed, 337 insertions(+), 176 deletions(-)
 create mode 100644 lib/test-hexdump.c

-- 
2.1.0


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

* [PATCH v4 01/12] hexdump: introduce test suite
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-05  9:37   ` Geert Uytterhoeven
  2014-09-04 14:26 ` [PATCH v4 02/12] hexdump: fix ascii column for the tail of a dump Andy Shevchenko
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Test different scenarios of function calls located in lib/hexdump.c.

Currently hex_dump_to_buffer() is only tested and test data is provided for
little endian CPUs.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/Kconfig.debug  |   3 ++
 lib/Makefile       |   4 +-
 lib/test-hexdump.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 lib/test-hexdump.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2870e2e..abcbf88 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1563,6 +1563,9 @@ config ASYNC_RAID6_TEST
 
 	  If unsure, say N.
 
+config TEST_HEXDUMP
+	tristate "Test functions located in the hexdump module at runtime"
+
 config TEST_STRING_HELPERS
 	tristate "Test functions located in the string_helpers module at runtime"
 
diff --git a/lib/Makefile b/lib/Makefile
index b73c3c3..06bd377 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -23,12 +23,14 @@ lib-y	+= kobject.o klist.o
 obj-y	+= lockref.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
-	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
+	 bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \
 	 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
 	 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
 	 percpu-refcount.o percpu_ida.o hash.o rhashtable.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
+obj-y += hexdump.o
+obj-$(CONFIG_TEST_HEXDUMP) += test-hexdump.o
 obj-y += kstrtox.o
 obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
 obj-$(CONFIG_TEST_MODULE) += test_module.o
diff --git a/lib/test-hexdump.c b/lib/test-hexdump.c
new file mode 100644
index 0000000..9d3bd1e
--- /dev/null
+++ b/lib/test-hexdump.c
@@ -0,0 +1,135 @@
+/*
+ * Test cases for lib/hexdump.c module.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/string.h>
+
+static const unsigned char data_b[] = {
+	'\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2',	/* 00 - 07 */
+	'\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b',	/* 08 - 0f */
+	'\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9',	/* 10 - 17 */
+	'\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c',	/* 18 - 1f */
+};
+
+static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
+
+static const char *test_data_1_le[] __initconst = {
+	"be", "32", "db", "7b", "0a", "18", "93", "b2",
+	"70", "ba", "c4", "24", "7d", "83", "34", "9b",
+	"a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
+	"4c", "d1", "19", "99", "43", "b1", "af", "0c",
+};
+
+static const char *test_data_2_le[] __initconst = {
+	"32be", "7bdb", "180a", "b293",
+	"ba70", "24c4", "837d", "9b34",
+	"9ca6", "ad31", "0f9c", "e9ac",
+	"d14c", "9919", "b143", "0caf",
+};
+
+static const char *test_data_4_le[] __initconst = {
+	"7bdb32be", "b293180a", "24c4ba70", "9b34837d",
+	"ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
+};
+
+static const char *test_data_8_le[] __initconst = {
+	"b293180a7bdb32be", "9b34837d24c4ba70",
+	"e9ac0f9cad319ca6", "0cafb1439919d14c",
+};
+
+static void __init test_hexdump(size_t len, int rowsize, int groupsize,
+				bool ascii)
+{
+	char test[32 * 3 + 2 + 32 + 1];
+	char real[32 * 3 + 2 + 32 + 1];
+	char *p;
+	const char **result;
+	size_t l = len;
+	int gs = groupsize, rs = rowsize;
+	unsigned int i;
+
+	hex_dump_to_buffer(data_b, l, rs, gs, real, sizeof(real), ascii);
+
+	if (rs != 16 && rs != 32)
+		rs = 16;
+
+	if (l > rs)
+		l = rs;
+
+	if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
+		gs = 1;
+
+	if (gs == 8)
+		result = test_data_8_le;
+	else if (gs == 4)
+		result = test_data_4_le;
+	else if (gs == 2)
+		result = test_data_2_le;
+	else
+		result = test_data_1_le;
+
+	memset(test, ' ', sizeof(test));
+
+	/* hex dump */
+	p = test;
+	for (i = 0; i < l / gs; i++) {
+		const char *q = *result++;
+		size_t amount = strlen(q);
+
+		strncpy(p, q, amount);
+		p += amount + 1;
+	}
+	if (i)
+		p--;
+
+	/* ASCII part */
+	if (ascii) {
+		p = test + rs * 2 + rs / gs + 1;
+		strncpy(p, data_a, l);
+		p += l;
+	}
+
+	*p = '\0';
+
+	if (strcmp(test, real)) {
+		pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
+		pr_err("Result: '%s'\n", real);
+		pr_err("Expect: '%s'\n", test);
+	}
+}
+
+static void __init test_hexdump_set(int rowsize, bool ascii)
+{
+	size_t d = min_t(size_t, sizeof(data_b), rowsize);
+	size_t len = get_random_int() % d + 1;
+
+	test_hexdump(len, rowsize, 4, ascii);
+	test_hexdump(len, rowsize, 2, ascii);
+	test_hexdump(len, rowsize, 8, ascii);
+	test_hexdump(len, rowsize, 1, ascii);
+}
+
+static int __init test_hexdump_init(void)
+{
+	unsigned int i;
+	int rowsize;
+
+	pr_info("Running tests...\n");
+
+	rowsize = (get_random_int() % 2 + 1) * 16;
+	for (i = 0; i < 16; i++)
+		test_hexdump_set(rowsize, false);
+
+	rowsize = (get_random_int() % 2 + 1) * 16;
+	for (i = 0; i < 16; i++)
+		test_hexdump_set(rowsize, true);
+
+	return -EINVAL;
+}
+module_init(test_hexdump_init);
+MODULE_LICENSE("Dual BSD/GPL");
-- 
2.1.0


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

* [PATCH v4 02/12] hexdump: fix ascii column for the tail of a dump
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 01/12] hexdump: introduce test suite Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 03/12] hexdump: do few calculations ahead Andy Shevchenko
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

In current implementation we have floating ascii column in the tail of the
dump.

For example, for row size equal to 16 the ascii column as in following table

group size \ length	8	12	16
	1		50	50	50
	2		22	32	42
	4		20	29	38
	8		19	-	36

This patch makes it the same independently of amount of bytes dumped.

The change is safe since all current users, which use ASCII part of the dump,
rely on the group size equal to 1. The patch doesn't change behaviour for such
group size (see the table above).

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/hexdump.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 8499c81..4677070 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -110,7 +110,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%16.16llx", j ? " " : "",
 					(unsigned long long)*(ptr8 + j));
-		ascii_column = 17 * ngroups + 2;
+		ascii_column = rowsize * 2 + rowsize / 8 + 2;
 		break;
 	}
 
@@ -121,7 +121,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 		for (j = 0; j < ngroups; j++)
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%8.8x", j ? " " : "", *(ptr4 + j));
-		ascii_column = 9 * ngroups + 2;
+		ascii_column = rowsize * 2 + rowsize / 4 + 2;
 		break;
 	}
 
@@ -132,7 +132,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 		for (j = 0; j < ngroups; j++)
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%4.4x", j ? " " : "", *(ptr2 + j));
-		ascii_column = 5 * ngroups + 2;
+		ascii_column = rowsize * 2 + rowsize / 2 + 2;
 		break;
 	}
 
-- 
2.1.0


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

* [PATCH v4 03/12] hexdump: do few calculations ahead
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 01/12] hexdump: introduce test suite Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 02/12] hexdump: fix ascii column for the tail of a dump Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 04/12] hexdump: makes it return amount of bytes placed in buffer Andy Shevchenko
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of doing calculations in each case of different groupsize let's do them
beforehand. While here, change the switch by if-else-if construction.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/hexdump.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 4677070..b82418f 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -87,6 +87,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 			bool ascii)
 {
 	const u8 *ptr = buf;
+	int ngroups;
 	u8 ch;
 	int j, lx = 0;
 	int ascii_column;
@@ -98,45 +99,33 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 		goto nil;
 	if (len > rowsize)		/* limit to one line at a time */
 		len = rowsize;
+	if (!is_power_of_2(groupsize) || groupsize > 8)
+		groupsize = 1;
 	if ((len % groupsize) != 0)	/* no mixed size output */
 		groupsize = 1;
 
-	switch (groupsize) {
-	case 8: {
+	ngroups = len / groupsize;
+	ascii_column = rowsize * 2 + rowsize / groupsize + 1;
+	if (groupsize == 8) {
 		const u64 *ptr8 = buf;
-		int ngroups = len / groupsize;
 
 		for (j = 0; j < ngroups; j++)
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%16.16llx", j ? " " : "",
 					(unsigned long long)*(ptr8 + j));
-		ascii_column = rowsize * 2 + rowsize / 8 + 2;
-		break;
-	}
-
-	case 4: {
+	} else if (groupsize == 4) {
 		const u32 *ptr4 = buf;
-		int ngroups = len / groupsize;
 
 		for (j = 0; j < ngroups; j++)
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%8.8x", j ? " " : "", *(ptr4 + j));
-		ascii_column = rowsize * 2 + rowsize / 4 + 2;
-		break;
-	}
-
-	case 2: {
+	} else if (groupsize == 2) {
 		const u16 *ptr2 = buf;
-		int ngroups = len / groupsize;
 
 		for (j = 0; j < ngroups; j++)
 			lx += scnprintf(linebuf + lx, linebuflen - lx,
 					"%s%4.4x", j ? " " : "", *(ptr2 + j));
-		ascii_column = rowsize * 2 + rowsize / 2 + 2;
-		break;
-	}
-
-	default:
+	} else {
 		for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
 			ch = ptr[j];
 			linebuf[lx++] = hex_asc_hi(ch);
@@ -145,14 +134,11 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 		}
 		if (j)
 			lx--;
-
-		ascii_column = 3 * rowsize + 2;
-		break;
 	}
 	if (!ascii)
 		goto nil;
 
-	while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
+	while (lx < (linebuflen - 1) && lx < ascii_column)
 		linebuf[lx++] = ' ';
 	for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) {
 		ch = ptr[j];
-- 
2.1.0


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

* [PATCH v4 04/12] hexdump: makes it return amount of bytes placed in buffer
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (2 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 03/12] hexdump: do few calculations ahead Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump() Andy Shevchenko
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

This patch makes hexdump to return amount of bytes placed in the buffer
excluding trailing NUL. In case of overflow it returns desired amount of bytes
to place entire dump. Thus, it mimics snprintf().

This will be useful for users that would like to repeat with bigger buffer.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/printk.h |  6 ++---
 lib/hexdump.c          | 73 +++++++++++++++++++++++++++++++++++++-------------
 lib/test-hexdump.c     | 45 +++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+), 21 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d78125f..a6c2771 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -407,9 +407,9 @@ enum {
 	DUMP_PREFIX_ADDRESS,
 	DUMP_PREFIX_OFFSET
 };
-extern void hex_dump_to_buffer(const void *buf, size_t len,
-			       int rowsize, int groupsize,
-			       char *linebuf, size_t linebuflen, bool ascii);
+extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
+			      int groupsize, char *linebuf, size_t linebuflen,
+			      bool ascii);
 #ifdef CONFIG_PRINTK
 extern void print_hex_dump(const char *level, const char *prefix_str,
 			   int prefix_type, int rowsize, int groupsize,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index b82418f..45eba39 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -81,22 +81,26 @@ EXPORT_SYMBOL(hex2bin);
  *
  * example output buffer:
  * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
+ *
+ * Return:
+ * The amount of bytes placed in the buffer without terminating NUL. If the
+ * output was truncated, then the return value is the number of bytes
+ * (excluding the terminating NUL) which would have been written to the final
+ * string if enough space had been available.
  */
-void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
-			int groupsize, char *linebuf, size_t linebuflen,
-			bool ascii)
+int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
+		       char *linebuf, size_t linebuflen, bool ascii)
 {
 	const u8 *ptr = buf;
 	int ngroups;
 	u8 ch;
 	int j, lx = 0;
 	int ascii_column;
+	int ret;
 
 	if (rowsize != 16 && rowsize != 32)
 		rowsize = 16;
 
-	if (!len)
-		goto nil;
 	if (len > rowsize)		/* limit to one line at a time */
 		len = rowsize;
 	if (!is_power_of_2(groupsize) || groupsize > 8)
@@ -106,27 +110,50 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 
 	ngroups = len / groupsize;
 	ascii_column = rowsize * 2 + rowsize / groupsize + 1;
+
+	if (!linebuflen)
+		goto overflow1;
+
+	if (!len)
+		goto nil;
+
 	if (groupsize == 8) {
 		const u64 *ptr8 = buf;
 
-		for (j = 0; j < ngroups; j++)
-			lx += scnprintf(linebuf + lx, linebuflen - lx,
-					"%s%16.16llx", j ? " " : "",
-					(unsigned long long)*(ptr8 + j));
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%16.16llx", j ? " " : "",
+				       (unsigned long long)*(ptr8 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
 	} else if (groupsize == 4) {
 		const u32 *ptr4 = buf;
 
-		for (j = 0; j < ngroups; j++)
-			lx += scnprintf(linebuf + lx, linebuflen - lx,
-					"%s%8.8x", j ? " " : "", *(ptr4 + j));
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%8.8x", j ? " " : "",
+				       *(ptr4 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
 	} else if (groupsize == 2) {
 		const u16 *ptr2 = buf;
 
-		for (j = 0; j < ngroups; j++)
-			lx += scnprintf(linebuf + lx, linebuflen - lx,
-					"%s%4.4x", j ? " " : "", *(ptr2 + j));
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%4.4x", j ? " " : "",
+				       *(ptr2 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
 	} else {
-		for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
+		for (j = 0; j < len; j++) {
+			if (linebuflen < lx + 3)
+				goto overflow2;
 			ch = ptr[j];
 			linebuf[lx++] = hex_asc_hi(ch);
 			linebuf[lx++] = hex_asc_lo(ch);
@@ -138,14 +165,24 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
 	if (!ascii)
 		goto nil;
 
-	while (lx < (linebuflen - 1) && lx < ascii_column)
+	while (lx < ascii_column) {
+		if (linebuflen < lx + 2)
+			goto overflow2;
 		linebuf[lx++] = ' ';
-	for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) {
+	}
+	for (j = 0; j < len; j++) {
+		if (linebuflen < lx + 2)
+			goto overflow2;
 		ch = ptr[j];
 		linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
 	}
 nil:
+	linebuf[lx] = '\0';
+	return lx;
+overflow2:
 	linebuf[lx++] = '\0';
+overflow1:
+	return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1;
 }
 EXPORT_SYMBOL(hex_dump_to_buffer);
 
diff --git a/lib/test-hexdump.c b/lib/test-hexdump.c
index 9d3bd1e..d10f90b 100644
--- a/lib/test-hexdump.c
+++ b/lib/test-hexdump.c
@@ -114,6 +114,45 @@ static void __init test_hexdump_set(int rowsize, bool ascii)
 	test_hexdump(len, rowsize, 1, ascii);
 }
 
+static void __init test_hexdump_overflow(bool ascii)
+{
+	char buf[56];
+	const char *t = test_data_1_le[0];
+	size_t l = get_random_int() % sizeof(buf);
+	bool a;
+	int e, r;
+
+	memset(buf, ' ', sizeof(buf));
+
+	r = hex_dump_to_buffer(data_b, 1, 16, 1, buf, l, ascii);
+
+	if (ascii)
+		e = 50;
+	else
+		e = 2;
+	buf[e + 2] = '\0';
+
+	if (!l) {
+		a = r == e && buf[0] == ' ';
+	} else if (l < 3) {
+		a = r == e && buf[0] == '\0';
+	} else if (l < 4) {
+		a = r == e && !strcmp(buf, t);
+	} else if (ascii) {
+		if (l < 51)
+			a = r == e && buf[l - 1] == '\0' && buf[l - 2] == ' ';
+		else
+			a = r == e && buf[50] == '\0' && buf[49] == '.';
+	} else {
+		a = r == e && buf[e] == '\0';
+	}
+
+	if (!a) {
+		pr_err("Len: %zu rc: %zu strlen: %zu\n", l, r, strlen(buf));
+		pr_err("Result: '%s'\n", buf);
+	}
+}
+
 static int __init test_hexdump_init(void)
 {
 	unsigned int i;
@@ -129,6 +168,12 @@ static int __init test_hexdump_init(void)
 	for (i = 0; i < 16; i++)
 		test_hexdump_set(rowsize, true);
 
+	for (i = 0; i < 16; i++)
+		test_hexdump_overflow(false);
+
+	for (i = 0; i < 16; i++)
+		test_hexdump_overflow(true);
+
 	return -EINVAL;
 }
 module_init(test_hexdump_init);
-- 
2.1.0


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

* [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump()
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (3 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 04/12] hexdump: makes it return amount of bytes placed in buffer Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-16  7:11   ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 06/12] saa7164: convert to seq_hex_dump() Andy Shevchenko
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

The new seq_hex_dump() is a complete analogue of print_hex_dump().

We have few users of this functionality already. It allows to reduce their
codebase.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 fs/seq_file.c            | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/seq_file.h |  4 ++++
 2 files changed, 54 insertions(+)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 3857b72..66c721f4 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/cred.h>
 #include <linux/mm.h>
+#include <linux/printk.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -794,6 +795,55 @@ void seq_pad(struct seq_file *m, char c)
 }
 EXPORT_SYMBOL(seq_pad);
 
+/* Analogue of print_hex_dump() */
+int seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
+		 int rowsize, int groupsize, const void *buf, size_t len,
+		 bool ascii)
+{
+	const u8 *ptr = buf;
+	int i, linelen, remaining = len;
+	int ret;
+
+	if (rowsize != 16 && rowsize != 32)
+		rowsize = 16;
+
+	for (i = 0; i < len; i += rowsize) {
+		linelen = min(remaining, rowsize);
+		remaining -= rowsize;
+
+		/* Prefix string */
+		ret = seq_printf(m, "%s", prefix_str);
+		if (ret < 0)
+			return ret;
+
+		/* Counter if asked */
+		if (prefix_type == DUMP_PREFIX_ADDRESS)
+			ret = seq_printf(m, "%p: ", ptr + i);
+		else if (prefix_type == DUMP_PREFIX_OFFSET)
+			ret = seq_printf(m, "%.8x: ", i);
+		if (ret < 0)
+			return ret;
+
+		/* Hex dump */
+		ret = hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
+					 m->buf + m->count, m->size - m->count,
+					 ascii);
+		if (m->count + ret >= m->size) {
+			seq_set_overflow(m);
+			return -1;
+		}
+		m->count += ret;
+
+		/* EOL */
+		ret = seq_putc(m, '\n');
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(seq_hex_dump);
+
 struct list_head *seq_list_start(struct list_head *head, loff_t pos)
 {
 	struct list_head *lh;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 52e0097..5de290c 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -107,6 +107,10 @@ int seq_write(struct seq_file *seq, const void *data, size_t len);
 __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
 __printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
 
+int seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
+		 int rowsize, int groupsize, const void *buf, size_t len,
+		 bool ascii);
+
 int seq_path(struct seq_file *, const struct path *, const char *);
 int seq_dentry(struct seq_file *, struct dentry *, const char *);
 int seq_path_root(struct seq_file *m, const struct path *path,
-- 
2.1.0


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

* [PATCH v4 06/12] saa7164: convert to seq_hex_dump()
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (4 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump() Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 07/12] crypto: qat - use seq_hex_dump() to dump buffers Andy Shevchenko
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently added seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Steven Toth <stoth@kernellabs.com>
Acked-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/pci/saa7164/saa7164-core.c | 31 ++++---------------------------
 1 file changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 1bf0697..6f81584 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1065,7 +1065,6 @@ static int saa7164_proc_show(struct seq_file *m, void *v)
 	struct saa7164_dev *dev;
 	struct tmComResBusInfo *b;
 	struct list_head *list;
-	int i, c;
 
 	if (saa7164_devcount == 0)
 		return 0;
@@ -1089,35 +1088,13 @@ static int saa7164_proc_show(struct seq_file *m, void *v)
 
 		seq_printf(m, " .m_pdwGetReadPos  = 0x%x (0x%08x)\n",
 			b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
-		c = 0;
 		seq_printf(m, "\n  Set Ring:\n");
-		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-		for (i = 0; i < b->m_dwSizeSetRing; i++) {
-			if (c == 0)
-				seq_printf(m, " %04x:", i);
+		seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 16, 1,
+			     b->m_pdwSetRing, b->m_dwSizeSetRing, false);
 
-			seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
-
-			if (++c == 16) {
-				seq_printf(m, "\n");
-				c = 0;
-			}
-		}
-
-		c = 0;
 		seq_printf(m, "\n  Get Ring:\n");
-		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-		for (i = 0; i < b->m_dwSizeGetRing; i++) {
-			if (c == 0)
-				seq_printf(m, " %04x:", i);
-
-			seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
-
-			if (++c == 16) {
-				seq_printf(m, "\n");
-				c = 0;
-			}
-		}
+		seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 16, 1,
+			     b->m_pdwGetRing, b->m_dwSizeGetRing, false);
 
 		mutex_unlock(&b->lock);
 
-- 
2.1.0


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

* [PATCH v4 07/12] crypto: qat - use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (5 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 06/12] saa7164: convert to seq_hex_dump() Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 08/12] parisc: " Andy Shevchenko
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 drivers/crypto/qat/qat_common/adf_transport_debug.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_transport_debug.c b/drivers/crypto/qat/qat_common/adf_transport_debug.c
index 6b69745..5f438a1 100644
--- a/drivers/crypto/qat/qat_common/adf_transport_debug.c
+++ b/drivers/crypto/qat/qat_common/adf_transport_debug.c
@@ -86,9 +86,7 @@ static int adf_ring_show(struct seq_file *sfile, void *v)
 {
 	struct adf_etr_ring_data *ring = sfile->private;
 	struct adf_etr_bank_data *bank = ring->bank;
-	uint32_t *msg = v;
 	void __iomem *csr = ring->bank->csr_addr;
-	int i, x;
 
 	if (v == SEQ_START_TOKEN) {
 		int head, tail, empty;
@@ -111,18 +109,8 @@ static int adf_ring_show(struct seq_file *sfile, void *v)
 		seq_puts(sfile, "----------- Ring data ------------\n");
 		return 0;
 	}
-	seq_printf(sfile, "%p:", msg);
-	x = 0;
-	i = 0;
-	for (; i < (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) >> 2); i++) {
-		seq_printf(sfile, " %08X", *(msg + i));
-		if ((ADF_MSG_SIZE_TO_BYTES(ring->msg_size) >> 2) != i + 1 &&
-		    (++x == 8)) {
-			seq_printf(sfile, "\n%p:", msg + i + 1);
-			x = 0;
-		}
-	}
-	seq_puts(sfile, "\n");
+	seq_hex_dump(sfile, "", DUMP_PREFIX_ADDRESS, 32, 4,
+		     v, ADF_MSG_SIZE_TO_BYTES(ring->msg_size), false);
 	return 0;
 }
 
-- 
2.1.0


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

* [PATCH v4 08/12] parisc: use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (6 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 07/12] crypto: qat - use seq_hex_dump() to dump buffers Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 09/12] [S390] zcrypt: " Andy Shevchenko
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

In one case it changes the output from
	1111111122222222333333334444444455555555666666667777777788888888
to
	11111111 22222222 33333333 44444444 55555555 66666666 77777777 88888888

though it seems it prints same data (by meaning) in both cases. I decide to
choose to use the space divided one.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Helge Deller <deller@gmx.de>
---
 drivers/parisc/ccio-dma.c  | 14 +++-----------
 drivers/parisc/sba_iommu.c | 11 +++--------
 2 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 8b490d7..9d353d2 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1101,20 +1101,12 @@ static const struct file_operations ccio_proc_info_fops = {
 
 static int ccio_proc_bitmap_info(struct seq_file *m, void *p)
 {
-	int len = 0;
 	struct ioc *ioc = ioc_list;
 
 	while (ioc != NULL) {
-		u32 *res_ptr = (u32 *)ioc->res_map;
-		int j;
-
-		for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {
-			if ((j & 7) == 0)
-				len += seq_puts(m, "\n   ");
-			len += seq_printf(m, "%08x", *res_ptr);
-			res_ptr++;
-		}
-		len += seq_puts(m, "\n\n");
+		seq_hex_dump(m, "   ", DUMP_PREFIX_NONE, 32, 4, ioc->res_map,
+			     ioc->res_size, false);
+		seq_putc(m, '\n');
 		ioc = ioc->next;
 		break; /* XXX - remove me */
 	}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 1ff1b67..fbc4db9 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1857,15 +1857,10 @@ sba_proc_bitmap_info(struct seq_file *m, void *p)
 {
 	struct sba_device *sba_dev = sba_list;
 	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Multi-IOC support! */
-	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
-	int i, len = 0;
 
-	for (i = 0; i < (ioc->res_size/sizeof(unsigned int)); ++i, ++res_ptr) {
-		if ((i & 7) == 0)
-			len += seq_printf(m, "\n   ");
-		len += seq_printf(m, " %08x", *res_ptr);
-	}
-	len += seq_printf(m, "\n");
+	seq_hex_dump(m, "   ", DUMP_PREFIX_NONE, 32, 4, ioc->res_map,
+		     ioc->res_size, false);
+	seq_printf(m, "\n");
 
 	return 0;
 }
-- 
2.1.0


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

* [PATCH v4 09/12] [S390] zcrypt: use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (7 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 08/12] parisc: " Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 10/12] staging: unisys: " Andy Shevchenko
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
---
 drivers/s390/crypto/zcrypt_api.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 0e18c5d..d1f9983 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -1203,16 +1203,8 @@ static void sprinthx(unsigned char *title, struct seq_file *m,
 static void sprinthx4(unsigned char *title, struct seq_file *m,
 		      unsigned int *array, unsigned int len)
 {
-	int r;
-
 	seq_printf(m, "\n%s\n", title);
-	for (r = 0; r < len; r++) {
-		if ((r % 8) == 0)
-			seq_printf(m, "    ");
-		seq_printf(m, "%08X ", array[r]);
-		if ((r % 8) == 7)
-			seq_putc(m, '\n');
-	}
+	seq_hex_dump(m, "    ", DUMP_PREFIX_NONE, 32, 4, array, len, false);
 	seq_putc(m, '\n');
 }
 
-- 
2.1.0


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

* [PATCH v4 10/12] staging: unisys: use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (8 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 09/12] [S390] zcrypt: " Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 11/12] kmemleak: " Andy Shevchenko
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 .../unisys/visorchannel/visorchannel_funcs.c       | 26 ++++------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
index 947b23c..d8345a6 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
+++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
@@ -633,15 +633,11 @@ void
 visorchannel_dump_section(VISORCHANNEL *chan, char *s,
 			  int off, int len, struct seq_file *seq)
 {
-	char *buf, *tbuf, *fmtbuf;
-	int fmtbufsize = 0;
-	int i;
+	char *buf;
 	int errcode = 0;
 
-	fmtbufsize = 100 * COVQ(len, 16);
 	buf = kmalloc(len, GFP_KERNEL|__GFP_NORETRY);
-	fmtbuf = kmalloc(fmtbufsize, GFP_KERNEL|__GFP_NORETRY);
-	if (buf == NULL || fmtbuf == NULL)
+	if (buf == NULL)
 		goto Away;
 
 	errcode = visorchannel_read(chan, off, buf, len);
@@ -651,23 +647,9 @@ visorchannel_dump_section(VISORCHANNEL *chan, char *s,
 		goto Away;
 	}
 	seq_printf(seq, "channel %s:\n", s);
-	tbuf = buf;
-	while (len > 0) {
-		i = (len < 16) ? len : 16;
-		hex_dump_to_buffer(tbuf, i, 16, 1, fmtbuf, fmtbufsize, TRUE);
-		seq_printf(seq, "%s\n", fmtbuf);
-		tbuf += 16;
-		len -= 16;
-	}
+	seq_hex_dump(seq, "", DUMP_PREFIX_NONE, 16, 1, buf, len, true);
 
 Away:
-	if (buf != NULL) {
-		kfree(buf);
-		buf = NULL;
-	}
-	if (fmtbuf != NULL) {
-		kfree(fmtbuf);
-		fmtbuf = NULL;
-	}
+	kfree(buf);
 }
 EXPORT_SYMBOL_GPL(visorchannel_dump_section);
-- 
2.1.0


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

* [PATCH v4 11/12] kmemleak: use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (9 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 10/12] staging: unisys: " Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-09-04 14:26 ` [PATCH v4 12/12] wil6210: " Andy Shevchenko
  2014-10-22 15:48 ` [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 mm/kmemleak.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 3cda50c..bc14fdc 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -291,23 +291,14 @@ static void hex_dump_object(struct seq_file *seq,
 			    struct kmemleak_object *object)
 {
 	const u8 *ptr = (const u8 *)object->pointer;
-	int i, len, remaining;
-	unsigned char linebuf[HEX_ROW_SIZE * 5];
+	size_t len;
 
 	/* limit the number of lines to HEX_MAX_LINES */
-	remaining = len =
-		min(object->size, (size_t)(HEX_MAX_LINES * HEX_ROW_SIZE));
-
-	seq_printf(seq, "  hex dump (first %d bytes):\n", len);
-	for (i = 0; i < len; i += HEX_ROW_SIZE) {
-		int linelen = min(remaining, HEX_ROW_SIZE);
-
-		remaining -= HEX_ROW_SIZE;
-		hex_dump_to_buffer(ptr + i, linelen, HEX_ROW_SIZE,
-				   HEX_GROUP_SIZE, linebuf, sizeof(linebuf),
-				   HEX_ASCII);
-		seq_printf(seq, "    %s\n", linebuf);
-	}
+	len = min(object->size, (size_t)(HEX_MAX_LINES * HEX_ROW_SIZE));
+
+	seq_printf(seq, "  hex dump (first %zu bytes):\n", len);
+	seq_hex_dump(seq, "    ", DUMP_PREFIX_NONE, HEX_ROW_SIZE,
+		     HEX_GROUP_SIZE, ptr, len, HEX_ASCII);
 }
 
 /*
-- 
2.1.0


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

* [PATCH v4 12/12] wil6210: use seq_hex_dump() to dump buffers
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (10 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 11/12] kmemleak: " Andy Shevchenko
@ 2014-09-04 14:26 ` Andy Shevchenko
  2014-10-22 15:48 ` [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-04 14:26 UTC (permalink / raw)
  To: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap
  Cc: Andy Shevchenko

Instead of custom approach let's use recently introduced seq_hex_dump() helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/net/wireless/ath/wil6210/debugfs.c | 32 +++++++-----------------------
 1 file changed, 7 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index b1c6a72..9b28edd 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -131,6 +131,12 @@ static const struct file_operations fops_vring = {
 	.llseek		= seq_lseek,
 };
 
+static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
+			    const char *prefix)
+{
+	seq_hex_dump(s, prefix, DUMP_PREFIX_NONE, 16, 1, p, len, false);
+}
+
 static void wil_print_ring(struct seq_file *s, const char *prefix,
 			   void __iomem *off)
 {
@@ -186,8 +192,6 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
 				   le16_to_cpu(hdr.seq), len,
 				   le16_to_cpu(hdr.type), hdr.flags);
 			if (len <= MAX_MBOXITEM_SIZE) {
-				int n = 0;
-				char printbuf[16 * 3 + 2];
 				unsigned char databuf[MAX_MBOXITEM_SIZE];
 				void __iomem *src = wmi_buffer(wil, d.addr) +
 					sizeof(struct wil6210_mbox_hdr);
@@ -197,15 +201,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
 				 * reading header
 				 */
 				wil_memcpy_fromio_32(databuf, src, len);
-				while (n < len) {
-					int l = min(len - n, 16);
-					hex_dump_to_buffer(databuf + n, l,
-							   16, 1, printbuf,
-							   sizeof(printbuf),
-							   false);
-					seq_printf(s, "      : %s\n", printbuf);
-					n += l;
-				}
+				wil_seq_hexdump(s, databuf, len, "      : ");
 			}
 		} else {
 			seq_printf(s, "\n");
@@ -620,20 +616,6 @@ static const struct file_operations fops_wmi = {
 	.open  = simple_open,
 };
 
-static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
-			    const char *prefix)
-{
-	char printbuf[16 * 3 + 2];
-	int i = 0;
-	while (i < len) {
-		int l = min(len - i, 16);
-		hex_dump_to_buffer(p + i, l, 16, 1, printbuf,
-				   sizeof(printbuf), false);
-		seq_printf(s, "%s%s\n", prefix, printbuf);
-		i += l;
-	}
-}
-
 static void wil_seq_print_skb(struct seq_file *s, struct sk_buff *skb)
 {
 	int i = 0;
-- 
2.1.0


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

* Re: [PATCH v4 01/12] hexdump: introduce test suite
  2014-09-04 14:26 ` [PATCH v4 01/12] hexdump: introduce test suite Andy Shevchenko
@ 2014-09-05  9:37   ` Geert Uytterhoeven
  2014-09-05 12:39     ` Andy Shevchenko
  0 siblings, 1 reply; 17+ messages in thread
From: Geert Uytterhoeven @ 2014-09-05  9:37 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Vladimir Kondratiev, Benjamin Romer,
	Catalin Marinas, Randy Dunlap, Chen Gang

On Thu, Sep 4, 2014 at 4:26 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> Test different scenarios of function calls located in lib/hexdump.c.
>
> Currently hex_dump_to_buffer() is only tested and test data is provided for
> little endian CPUs.

That's a nice one to be amended using Chen's
"arch: Kconfig: Let all little endian architectures define
CPU_LITTLE_ENDIAN explicitly".

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 01/12] hexdump: introduce test suite
  2014-09-05  9:37   ` Geert Uytterhoeven
@ 2014-09-05 12:39     ` Andy Shevchenko
  0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-05 12:39 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Tadeusz Struk, Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Vladimir Kondratiev, Benjamin Romer,
	Catalin Marinas, Randy Dunlap, Chen Gang

On Fri, 2014-09-05 at 11:37 +0200, Geert Uytterhoeven wrote:
> On Thu, Sep 4, 2014 at 4:26 PM, Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > Test different scenarios of function calls located in lib/hexdump.c.
> >
> > Currently hex_dump_to_buffer() is only tested and test data is provided for
> > little endian CPUs.
> 
> That's a nice one to be amended using Chen's
> "arch: Kconfig: Let all little endian architectures define
> CPU_LITTLE_ENDIAN explicitly".

I don't see it in the upstream yet, right? Thus, I wouldn't like to
depend on it now.


-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy


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

* Re: [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump()
  2014-09-04 14:26 ` [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump() Andy Shevchenko
@ 2014-09-16  7:11   ` Andy Shevchenko
  0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-09-16  7:11 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap

On Thu, 2014-09-04 at 17:26 +0300, Andy Shevchenko wrote:
> The new seq_hex_dump() is a complete analogue of print_hex_dump().
> 
> We have few users of this functionality already. It allows to reduce their
> codebase.

Al, what do you think about this version?

> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  fs/seq_file.c            | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/seq_file.h |  4 ++++
>  2 files changed, 54 insertions(+)
> 
> diff --git a/fs/seq_file.c b/fs/seq_file.c
> index 3857b72..66c721f4 100644
> --- a/fs/seq_file.c
> +++ b/fs/seq_file.c
> @@ -12,6 +12,7 @@
>  #include <linux/slab.h>
>  #include <linux/cred.h>
>  #include <linux/mm.h>
> +#include <linux/printk.h>
>  
>  #include <asm/uaccess.h>
>  #include <asm/page.h>
> @@ -794,6 +795,55 @@ void seq_pad(struct seq_file *m, char c)
>  }
>  EXPORT_SYMBOL(seq_pad);
>  
> +/* Analogue of print_hex_dump() */
> +int seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
> +		 int rowsize, int groupsize, const void *buf, size_t len,
> +		 bool ascii)
> +{
> +	const u8 *ptr = buf;
> +	int i, linelen, remaining = len;
> +	int ret;
> +
> +	if (rowsize != 16 && rowsize != 32)
> +		rowsize = 16;
> +
> +	for (i = 0; i < len; i += rowsize) {
> +		linelen = min(remaining, rowsize);
> +		remaining -= rowsize;
> +
> +		/* Prefix string */
> +		ret = seq_printf(m, "%s", prefix_str);
> +		if (ret < 0)
> +			return ret;
> +
> +		/* Counter if asked */
> +		if (prefix_type == DUMP_PREFIX_ADDRESS)
> +			ret = seq_printf(m, "%p: ", ptr + i);
> +		else if (prefix_type == DUMP_PREFIX_OFFSET)
> +			ret = seq_printf(m, "%.8x: ", i);
> +		if (ret < 0)
> +			return ret;
> +
> +		/* Hex dump */
> +		ret = hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
> +					 m->buf + m->count, m->size - m->count,
> +					 ascii);
> +		if (m->count + ret >= m->size) {
> +			seq_set_overflow(m);
> +			return -1;
> +		}
> +		m->count += ret;
> +
> +		/* EOL */
> +		ret = seq_putc(m, '\n');
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(seq_hex_dump);
> +
>  struct list_head *seq_list_start(struct list_head *head, loff_t pos)
>  {
>  	struct list_head *lh;
> diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
> index 52e0097..5de290c 100644
> --- a/include/linux/seq_file.h
> +++ b/include/linux/seq_file.h
> @@ -107,6 +107,10 @@ int seq_write(struct seq_file *seq, const void *data, size_t len);
>  __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
>  __printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
>  
> +int seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
> +		 int rowsize, int groupsize, const void *buf, size_t len,
> +		 bool ascii);
> +
>  int seq_path(struct seq_file *, const struct path *, const char *);
>  int seq_dentry(struct seq_file *, struct dentry *, const char *);
>  int seq_path_root(struct seq_file *m, const struct path *path,


-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy


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

* Re: [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper
  2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
                   ` (11 preceding siblings ...)
  2014-09-04 14:26 ` [PATCH v4 12/12] wil6210: " Andy Shevchenko
@ 2014-10-22 15:48 ` Andy Shevchenko
  12 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2014-10-22 15:48 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Herbert Xu, Mauro Carvalho Chehab, Helge Deller,
	Ingo Tuchscherer, Alexander Viro, linux-kernel, Joe Perches,
	Marek Vasut, Geert Uytterhoeven, Vladimir Kondratiev,
	Benjamin Romer, Catalin Marinas, Randy Dunlap

On Thu, 2014-09-04 at 17:26 +0300, Andy Shevchenko wrote:
> This introduces a new helper and switches current users to use it. All are
> compiled tested, hexdump and kmemleak are tested by their test suits.
> 

Gently ping on this series.
Any comments?

> Changelog v4:
> - hexdump is amended to return value from which we can check an overflow
>  (patches 1/12 - 4/12)
> - seq_hex_dump pushes bytes directly to buffer and returns an error in case of
>   overflow (addresses Al Viro's comment)
> - append Acked-by for patches 8/12 and 9/12
> - convert more users (patches 10/12 - 12/12)
> 
> Changelog v3:
> - append Mauro's Ack
> - rebase on top of recent linux-next
> 
> Changelog v2:
> - append Acked-by and Reviewed-by tags
> - update commit messages in patches 3/5. and 5/5
> - update line size to be 32 bytes instead of 16 in patch 3/5
> - Joe found that output is changed in patch 4/5, thus I update commit message
>   there
> 
> Andy Shevchenko (12):
>   hexdump: introduce test suite
>   hexdump: fix ascii column for the tail of a dump
>   hexdump: do few calculations ahead
>   hexdump: makes it return amount of bytes placed in buffer
>   seq_file: provide an analogue of print_hex_dump()
>   saa7164: convert to seq_hex_dump()
>   crypto: qat - use seq_hex_dump() to dump buffers
>   parisc: use seq_hex_dump() to dump buffers
>   [S390] zcrypt: use seq_hex_dump() to dump buffers
>   staging: unisys: use seq_hex_dump() to dump buffers
>   kmemleak: use seq_hex_dump() to dump buffers
>   wil6210: use seq_hex_dump() to dump buffers
> 
>  .../crypto/qat/qat_common/adf_transport_debug.c    |  16 +-
>  drivers/media/pci/saa7164/saa7164-core.c           |  31 +---
>  drivers/net/wireless/ath/wil6210/debugfs.c         |  32 +---
>  drivers/parisc/ccio-dma.c                          |  14 +-
>  drivers/parisc/sba_iommu.c                         |  11 +-
>  drivers/s390/crypto/zcrypt_api.c                   |  10 +-
>  .../unisys/visorchannel/visorchannel_funcs.c       |  26 +--
>  fs/seq_file.c                                      |  50 ++++++
>  include/linux/printk.h                             |   6 +-
>  include/linux/seq_file.h                           |   4 +
>  lib/Kconfig.debug                                  |   3 +
>  lib/Makefile                                       |   4 +-
>  lib/hexdump.c                                      | 105 +++++++-----
>  lib/test-hexdump.c                                 | 180 +++++++++++++++++++++
>  mm/kmemleak.c                                      |  21 +--
>  15 files changed, 337 insertions(+), 176 deletions(-)
>  create mode 100644 lib/test-hexdump.c
> 


-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy


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

end of thread, other threads:[~2014-10-22 15:48 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-04 14:26 [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 01/12] hexdump: introduce test suite Andy Shevchenko
2014-09-05  9:37   ` Geert Uytterhoeven
2014-09-05 12:39     ` Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 02/12] hexdump: fix ascii column for the tail of a dump Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 03/12] hexdump: do few calculations ahead Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 04/12] hexdump: makes it return amount of bytes placed in buffer Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 05/12] seq_file: provide an analogue of print_hex_dump() Andy Shevchenko
2014-09-16  7:11   ` Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 06/12] saa7164: convert to seq_hex_dump() Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 07/12] crypto: qat - use seq_hex_dump() to dump buffers Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 08/12] parisc: " Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 09/12] [S390] zcrypt: " Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 10/12] staging: unisys: " Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 11/12] kmemleak: " Andy Shevchenko
2014-09-04 14:26 ` [PATCH v4 12/12] wil6210: " Andy Shevchenko
2014-10-22 15:48 ` [PATCH v4 00/12] fs/seq_file: introduce seq_hex_dump() helper Andy Shevchenko

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