2023-08-11 08:29:50

by Leizhen (ThunderTown)

[permalink] [raw]
Subject: [PATCH v3 0/2] hexdump: minimize the output width of address and offset

From: Zhen Lei <[email protected]>

v2 --> v3:
Replace DUMP_PREFIX_ADDRESS_LOW16 with DUMP_PREFIX_CUSTOM. Let the user to
specify the format string.

v1 --> v2:
1. Move the code for calculating the output width of the offset into
the case DUMP_PREFIX_OFFSET.
2. Add Reviewed-by: Randy Dunlap <[email protected]>

v1:
The dump prefix is added to facilitate the reading of the dumped memory.
However, if the prefix content is too repeated or redundant, the readability
is reduced, and the ring buffer becomes full quickly and other prints are
overwritten.

For example: (DUMP_PREFIX_OFFSET)
Before:
dump_size=36:
00000000: c0 ba 8c 80 00 80 ff ff 6c 93 ee 2f ee bf ff ff
00000010: 00 50 1e 98 ff 27 ff ff 01 00 00 00 00 00 00 00
00000020: 80 ca 2f 98

After:
dump_size=36:
00: c0 3a 91 80 00 80 ff ff 6c 93 ae 76 30 ce ff ff
10: 00 60 cd 60 7d 4e ff ff 01 00 00 00 00 00 00 00
20: 40 9e 29 40


Zhen Lei (2):
hexdump: minimize the output width of the offset
hexdump: add a new dump prefix DUMP_PREFIX_CUSTOM

include/linux/printk.h | 3 ++-
lib/hexdump.c | 28 ++++++++++++++++++++++++++--
2 files changed, 28 insertions(+), 3 deletions(-)

--
2.34.1



2023-08-11 08:31:12

by Leizhen (ThunderTown)

[permalink] [raw]
Subject: [PATCH v3 1/2] hexdump: minimize the output width of the offset

From: Zhen Lei <[email protected]>

The offset of case DUMP_PREFIX_OFFSET always starts from 0. Currently,
the output width is fixed to 8. But we usually dump only tens or hundreds
of bytes, occasionally thousands of bytes. Therefore, the output offset
value always has a number of leading zeros, which increases the number of
bytes printed and reduces readability. Let's minimize the output width of
the offset based on the number of significant bits of its maximum value.

Before:
dump_size=36:
00000000: c0 ba 8c 80 00 80 ff ff 6c 93 ee 2f ee bf ff ff
00000010: 00 50 1e 98 ff 27 ff ff 01 00 00 00 00 00 00 00
00000020: 80 ca 2f 98

After:
dump_size=8:
0: c0 ba 89 80 00 80 ff ff

dump_size=36:
00: c0 3a 91 80 00 80 ff ff 6c 93 ae 76 30 ce ff ff
10: 00 60 cd 60 7d 4e ff ff 01 00 00 00 00 00 00 00
20: 40 9e 29 40

dump_size=300:
000: c0 ba 8d 80 00 80 ff ff 6c 93 ce d4 78 a7 ff ff
010: 00 00 16 18 0c 40 ff ff 01 00 00 00 00 00 00 00
020: 01 00 00 00 00 00 00 00 e8 bc 8d 80 00 80 ff ff
... ...
110: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120: 00 08 12 01 0c 40 ff ff 00 00 01 00

Signed-off-by: Zhen Lei <[email protected]>
Reviewed-by: Randy Dunlap <[email protected]>
---
lib/hexdump.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 06833d404398d74..1064706d57c15ed 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -263,7 +263,7 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
const void *buf, size_t len, bool ascii)
{
const u8 *ptr = buf;
- int i, linelen, remaining = len;
+ int i, linelen, width = 0, remaining = len;
unsigned char linebuf[32 * 3 + 2 + 32 + 1];

if (rowsize != 16 && rowsize != 32)
@@ -282,7 +282,15 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
level, prefix_str, ptr + i, linebuf);
break;
case DUMP_PREFIX_OFFSET:
- printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
+ if (!width) {
+ unsigned long tmp = len - 1; /* offset start from 0, so minus 1 */
+
+ do {
+ width++;
+ tmp >>= 4;
+ } while (tmp);
+ }
+ printk("%s%s%0*x: %s\n", level, prefix_str, width, i, linebuf);
break;
default:
printk("%s%s%s\n", level, prefix_str, linebuf);
--
2.34.1