From: Ira Weiny <ira.weiny@intel.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Petr Mladek <pmladek@suse.com>,
Steven Rostedt <rostedt@goodmis.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
Sergey Senozhatsky <senozhatsky@chromium.org>,
Jonathan Corbet <corbet@lwn.net>,
Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Dan Williams <dan.j.williams@intel.com>
Cc: Fan Ni <fan.ni@samsung.com>, Bagas Sanjaya <bagasdotme@gmail.com>,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
linux-cxl@vger.kernel.org, Ira Weiny <ira.weiny@intel.com>
Subject: [PATCH v2 3/4] printf: Add print format (%pra) for struct range
Date: Fri, 25 Oct 2024 19:46:55 -0500 [thread overview]
Message-ID: <20241025-cxl-pra-v2-3-123a825daba2@intel.com> (raw)
In-Reply-To: <20241025-cxl-pra-v2-0-123a825daba2@intel.com>
The use of struct range in the CXL subsystem is growing. In particular,
the addition of Dynamic Capacity devices uses struct range in a number
of places which are reported in debug and error messages.
To wit requiring the printing of the start/end fields in each print
became cumbersome. Dan Williams mentions in [1] that it might be time
to have a print specifier for struct range similar to struct resource
A few alternatives were considered including '%par', '%r', and '%pn'.
%pra follows that struct range is similar to struct resource (%p[rR])
but needs to be different. Based on discussions with Petr and Andy
'%pra' was chosen.[2]
Andy also suggested to keep the range prints similar to struct resource
though combined code. Add hex_range() to handle printing for both
pointer types.
Finally introduce DEFINE_RANGE() as a parallel to DEFINE_RES_*() and use
it in the tests.
Cc: Jonathan Corbet <corbet@lwn.net> (maintainer:DOCUMENTATION)
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org (open list)
Link: https://lore.kernel.org/all/663922b475e50_d54d72945b@dwillia2-xfh.jf.intel.com.notmuch/ [1]
Link: https://lore.kernel.org/all/66cea3bf3332f_f937b29424@iweiny-mobl.notmuch/ [2]
Suggested-by: "Dan Williams" <dan.j.williams@intel.com>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
Changes:
[Andy: s/resource_and_range/resource_or_range/]
---
Documentation/core-api/printk-formats.rst | 13 +++++++
include/linux/range.h | 6 ++++
lib/test_printf.c | 17 +++++++++
lib/vsprintf.c | 57 +++++++++++++++++++++++++++----
4 files changed, 87 insertions(+), 6 deletions(-)
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index 552f51046cf3..ecccc0473da9 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -236,6 +236,19 @@ width of the CPU data path.
Passed by reference.
+Struct Range
+------------
+
+::
+
+ %pra [range 0x0000000060000000-0x000000006fffffff] or
+ [range 0x0000000060000000]
+
+For printing struct range. struct range holds an arbitrary range of u64
+values. If start is equal to end only print the start value.
+
+Passed by reference.
+
DMA address types dma_addr_t
----------------------------
diff --git a/include/linux/range.h b/include/linux/range.h
index 6ad0b73cb7ad..1358d4b1807a 100644
--- a/include/linux/range.h
+++ b/include/linux/range.h
@@ -31,4 +31,10 @@ int clean_sort_range(struct range *range, int az);
void sort_range(struct range *range, int nr_range);
+#define DEFINE_RANGE(_start, _end) \
+(struct range) { \
+ .start = (_start), \
+ .end = (_end), \
+ }
+
#endif
diff --git a/lib/test_printf.c b/lib/test_printf.c
index 5afdf5efc627..59dbe4f9a4cb 100644
--- a/lib/test_printf.c
+++ b/lib/test_printf.c
@@ -432,6 +432,22 @@ struct_resource(void)
"%pR", &test_resource);
}
+static void __init
+struct_range(void)
+{
+ struct range test_range = DEFINE_RANGE(0xc0ffee00ba5eba11,
+ 0xc0ffee00ba5eba11);
+ test("[range 0xc0ffee00ba5eba11]", "%pra", &test_range);
+
+ test_range = DEFINE_RANGE(0xc0ffee, 0xba5eba11);
+ test("[range 0x0000000000c0ffee-0x00000000ba5eba11]",
+ "%pra", &test_range);
+
+ test_range = DEFINE_RANGE(0xba5eba11, 0xc0ffee);
+ test("[range 0x00000000ba5eba11-0x0000000000c0ffee]",
+ "%pra", &test_range);
+}
+
static void __init
addr(void)
{
@@ -807,6 +823,7 @@ test_pointer(void)
symbol_ptr();
kernel_ptr();
struct_resource();
+ struct_range();
addr();
escaped_str();
hex_string();
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 09f022ba1c05..9e76350bd77d 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1039,6 +1039,20 @@ static const struct printf_spec default_dec04_spec = {
.flags = ZEROPAD,
};
+static noinline_for_stack
+char *hex_range(char *buf, char *end, u64 start_val, u64 end_val,
+ struct printf_spec spec)
+{
+ buf = number(buf, end, start_val, spec);
+ if (start_val == end_val)
+ return buf;
+
+ if (buf < end)
+ *buf = '-';
+ ++buf;
+ return number(buf, end, end_val, spec);
+}
+
static noinline_for_stack
char *resource_string(char *buf, char *end, struct resource *res,
struct printf_spec spec, const char *fmt)
@@ -1115,11 +1129,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
p = string_nocheck(p, pend, "size ", str_spec);
p = number(p, pend, resource_size(res), *specp);
} else {
- p = number(p, pend, res->start, *specp);
- if (res->start != res->end) {
- *p++ = '-';
- p = number(p, pend, res->end, *specp);
- }
+ p = hex_range(p, pend, res->start, res->end, *specp);
}
if (decode) {
if (res->flags & IORESOURCE_MEM_64)
@@ -1140,6 +1150,31 @@ char *resource_string(char *buf, char *end, struct resource *res,
return string_nocheck(buf, end, sym, spec);
}
+static noinline_for_stack
+char *range_string(char *buf, char *end, const struct range *range,
+ struct printf_spec spec, const char *fmt)
+{
+ char sym[sizeof("[range 0x0123456789abcdef-0x0123456789abcdef]")];
+ char *p = sym, *pend = sym + sizeof(sym);
+
+ struct printf_spec range_spec = {
+ .field_width = 2 + 2 * sizeof(range->start), /* 0x + 2 * 8 */
+ .flags = SPECIAL | SMALL | ZEROPAD,
+ .base = 16,
+ .precision = -1,
+ };
+
+ if (check_pointer(&buf, end, range, spec))
+ return buf;
+
+ p = string_nocheck(p, pend, "[range ", default_str_spec);
+ p = hex_range(p, pend, range->start, range->end, range_spec);
+ *p++ = ']';
+ *p = '\0';
+
+ return string_nocheck(buf, end, sym, spec);
+}
+
static noinline_for_stack
char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
const char *fmt)
@@ -2229,6 +2264,15 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
return widen_string(buf, buf - buf_start, end, spec);
}
+static noinline_for_stack
+char *resource_or_range(const char *fmt, char *buf, char *end, void *ptr,
+ struct printf_spec spec)
+{
+ if (*fmt == 'r' && fmt[1] == 'a')
+ return range_string(buf, end, ptr, spec, fmt);
+ return resource_string(buf, end, ptr, spec, fmt);
+}
+
int __init no_hash_pointers_enable(char *str)
{
if (no_hash_pointers)
@@ -2277,6 +2321,7 @@ char *rust_fmt_argument(char *buf, char *end, void *ptr);
* - 'Bb' as above with module build ID (for use in backtraces)
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
* - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
+ * - 'ra' For struct ranges, e.g., [range 0x0000000000000000 - 0x00000000000000ff]
* - 'b[l]' For a bitmap, the number of bits is determined by the field
* width which must be explicitly specified either as part of the
* format string '%32b[l]' or through '%*b[l]', [l] selects
@@ -2401,7 +2446,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return symbol_string(buf, end, ptr, spec, fmt);
case 'R':
case 'r':
- return resource_string(buf, end, ptr, spec, fmt);
+ return resource_or_range(fmt, buf, end, ptr, spec);
case 'h':
return hex_string(buf, end, ptr, spec, fmt);
case 'b':
--
2.47.0
next prev parent reply other threads:[~2024-10-26 0:47 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-26 0:46 [PATCH v2 0/4] printf: Add struct range print specifier Ira Weiny
2024-10-26 0:46 ` [PATCH v2 1/4] test printf: Add very basic struct resource tests Ira Weiny
2024-10-28 9:07 ` Andy Shevchenko
2024-10-28 21:29 ` Ira Weiny
2024-10-26 0:46 ` [PATCH v2 2/4] Documentation/printf: struct resource add start == end special case Ira Weiny
2024-10-28 9:07 ` Andy Shevchenko
2024-10-29 15:19 ` Jonathan Cameron
2024-11-07 12:34 ` Petr Mladek
2024-10-26 0:46 ` Ira Weiny [this message]
2024-10-28 9:11 ` [PATCH v2 3/4] printf: Add print format (%pra) for struct range Andy Shevchenko
2024-11-07 14:24 ` Petr Mladek
2024-10-26 0:46 ` [PATCH v2 4/4] cxl/cdat: Use %pra for dpa range outputs Ira Weiny
2024-10-30 10:51 ` [PATCH v2 0/4] printf: Add struct range print specifier metux
2024-10-31 21:34 ` Ira Weiny
2024-11-07 14:43 ` Petr Mladek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241025-cxl-pra-v2-3-123a825daba2@intel.com \
--to=ira.weiny@intel.com \
--cc=akpm@linux-foundation.org \
--cc=alison.schofield@intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bagasdotme@gmail.com \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=fan.ni@samsung.com \
--cc=jonathan.cameron@huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=senozhatsky@chromium.org \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.