Skip to content

Commit 86bcd81

Browse files
committed
Merge branch 'cxl/for-6.12/printf' into cxl-for-next
Add support for adding a printf specifier '$pra' to emit 'struct range' content.
2 parents 9474d58 + bdd7c35 commit 86bcd81

File tree

5 files changed

+141
-11
lines changed

5 files changed

+141
-11
lines changed

Documentation/core-api/printk-formats.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,17 @@ Struct Resources
209209
::
210210

211211
%pr [mem 0x60000000-0x6fffffff flags 0x2200] or
212+
[mem 0x60000000 flags 0x2200] or
212213
[mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
214+
[mem 0x0000000060000000 flags 0x2200]
213215
%pR [mem 0x60000000-0x6fffffff pref] or
216+
[mem 0x60000000 pref] or
214217
[mem 0x0000000060000000-0x000000006fffffff pref]
218+
[mem 0x0000000060000000 pref]
215219

216220
For printing struct resources. The ``R`` and ``r`` specifiers result in a
217-
printed resource with (R) or without (r) a decoded flags member.
221+
printed resource with (R) or without (r) a decoded flags member. If start is
222+
equal to end only print the start value.
218223

219224
Passed by reference.
220225

@@ -231,6 +236,19 @@ width of the CPU data path.
231236

232237
Passed by reference.
233238

239+
Struct Range
240+
------------
241+
242+
::
243+
244+
%pra [range 0x0000000060000000-0x000000006fffffff] or
245+
[range 0x0000000060000000]
246+
247+
For printing struct range. struct range holds an arbitrary range of u64
248+
values. If start is equal to end only print the start value.
249+
250+
Passed by reference.
251+
234252
DMA address types dma_addr_t
235253
----------------------------
236254

drivers/cxl/core/cdat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
247247
dpa_perf->dpa_range = dent->dpa_range;
248248
dpa_perf->qos_class = dent->qos_class;
249249
dev_dbg(dev,
250-
"DSMAS: dpa: %#llx qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
251-
dent->dpa_range.start, dpa_perf->qos_class,
250+
"DSMAS: dpa: %pra qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
251+
&dent->dpa_range, dpa_perf->qos_class,
252252
dent->coord[ACCESS_COORDINATE_CPU].read_bandwidth,
253253
dent->coord[ACCESS_COORDINATE_CPU].write_bandwidth,
254254
dent->coord[ACCESS_COORDINATE_CPU].read_latency,
@@ -279,8 +279,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
279279
range_contains(&pmem_range, &dent->dpa_range))
280280
update_perf_entry(dev, dent, &mds->pmem_perf);
281281
else
282-
dev_dbg(dev, "no partition for dsmas dpa: %#llx\n",
283-
dent->dpa_range.start);
282+
dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
283+
&dent->dpa_range);
284284
}
285285
}
286286

include/linux/range.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@ int clean_sort_range(struct range *range, int az);
3232

3333
void sort_range(struct range *range, int nr_range);
3434

35+
#define DEFINE_RANGE(_start, _end) \
36+
(struct range) { \
37+
.start = (_start), \
38+
.end = (_end), \
39+
}
40+
3541
#endif

lib/test_printf.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,66 @@ kernel_ptr(void)
386386
static void __init
387387
struct_resource(void)
388388
{
389+
struct resource test_resource = {
390+
.start = 0xc0ffee00,
391+
.end = 0xc0ffee00,
392+
.flags = IORESOURCE_MEM,
393+
};
394+
395+
test("[mem 0xc0ffee00 flags 0x200]",
396+
"%pr", &test_resource);
397+
398+
test_resource = (struct resource) {
399+
.start = 0xc0ffee,
400+
.end = 0xba5eba11,
401+
.flags = IORESOURCE_MEM,
402+
};
403+
test("[mem 0x00c0ffee-0xba5eba11 flags 0x200]",
404+
"%pr", &test_resource);
405+
406+
test_resource = (struct resource) {
407+
.start = 0xba5eba11,
408+
.end = 0xc0ffee,
409+
.flags = IORESOURCE_MEM,
410+
};
411+
test("[mem 0xba5eba11-0x00c0ffee flags 0x200]",
412+
"%pr", &test_resource);
413+
414+
test_resource = (struct resource) {
415+
.start = 0xba5eba11,
416+
.end = 0xba5eca11,
417+
.flags = IORESOURCE_MEM,
418+
};
419+
420+
test("[mem 0xba5eba11-0xba5eca11 flags 0x200]",
421+
"%pr", &test_resource);
422+
423+
test_resource = (struct resource) {
424+
.start = 0xba11,
425+
.end = 0xca10,
426+
.flags = IORESOURCE_IO |
427+
IORESOURCE_DISABLED |
428+
IORESOURCE_UNSET,
429+
};
430+
431+
test("[io size 0x1000 disabled]",
432+
"%pR", &test_resource);
433+
}
434+
435+
static void __init
436+
struct_range(void)
437+
{
438+
struct range test_range = DEFINE_RANGE(0xc0ffee00ba5eba11,
439+
0xc0ffee00ba5eba11);
440+
test("[range 0xc0ffee00ba5eba11]", "%pra", &test_range);
441+
442+
test_range = DEFINE_RANGE(0xc0ffee, 0xba5eba11);
443+
test("[range 0x0000000000c0ffee-0x00000000ba5eba11]",
444+
"%pra", &test_range);
445+
446+
test_range = DEFINE_RANGE(0xba5eba11, 0xc0ffee);
447+
test("[range 0x00000000ba5eba11-0x0000000000c0ffee]",
448+
"%pra", &test_range);
389449
}
390450

391451
static void __init
@@ -763,6 +823,7 @@ test_pointer(void)
763823
symbol_ptr();
764824
kernel_ptr();
765825
struct_resource();
826+
struct_range();
766827
addr();
767828
escaped_str();
768829
hex_string();

lib/vsprintf.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,20 @@ static const struct printf_spec default_dec04_spec = {
10391039
.flags = ZEROPAD,
10401040
};
10411041

1042+
static noinline_for_stack
1043+
char *hex_range(char *buf, char *end, u64 start_val, u64 end_val,
1044+
struct printf_spec spec)
1045+
{
1046+
buf = number(buf, end, start_val, spec);
1047+
if (start_val == end_val)
1048+
return buf;
1049+
1050+
if (buf < end)
1051+
*buf = '-';
1052+
++buf;
1053+
return number(buf, end, end_val, spec);
1054+
}
1055+
10421056
static noinline_for_stack
10431057
char *resource_string(char *buf, char *end, struct resource *res,
10441058
struct printf_spec spec, const char *fmt)
@@ -1115,11 +1129,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
11151129
p = string_nocheck(p, pend, "size ", str_spec);
11161130
p = number(p, pend, resource_size(res), *specp);
11171131
} else {
1118-
p = number(p, pend, res->start, *specp);
1119-
if (res->start != res->end) {
1120-
*p++ = '-';
1121-
p = number(p, pend, res->end, *specp);
1122-
}
1132+
p = hex_range(p, pend, res->start, res->end, *specp);
11231133
}
11241134
if (decode) {
11251135
if (res->flags & IORESOURCE_MEM_64)
@@ -1140,6 +1150,31 @@ char *resource_string(char *buf, char *end, struct resource *res,
11401150
return string_nocheck(buf, end, sym, spec);
11411151
}
11421152

1153+
static noinline_for_stack
1154+
char *range_string(char *buf, char *end, const struct range *range,
1155+
struct printf_spec spec, const char *fmt)
1156+
{
1157+
char sym[sizeof("[range 0x0123456789abcdef-0x0123456789abcdef]")];
1158+
char *p = sym, *pend = sym + sizeof(sym);
1159+
1160+
struct printf_spec range_spec = {
1161+
.field_width = 2 + 2 * sizeof(range->start), /* 0x + 2 * 8 */
1162+
.flags = SPECIAL | SMALL | ZEROPAD,
1163+
.base = 16,
1164+
.precision = -1,
1165+
};
1166+
1167+
if (check_pointer(&buf, end, range, spec))
1168+
return buf;
1169+
1170+
p = string_nocheck(p, pend, "[range ", default_str_spec);
1171+
p = hex_range(p, pend, range->start, range->end, range_spec);
1172+
*p++ = ']';
1173+
*p = '\0';
1174+
1175+
return string_nocheck(buf, end, sym, spec);
1176+
}
1177+
11431178
static noinline_for_stack
11441179
char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
11451180
const char *fmt)
@@ -2229,6 +2264,15 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
22292264
return widen_string(buf, buf - buf_start, end, spec);
22302265
}
22312266

2267+
static noinline_for_stack
2268+
char *resource_or_range(const char *fmt, char *buf, char *end, void *ptr,
2269+
struct printf_spec spec)
2270+
{
2271+
if (*fmt == 'r' && fmt[1] == 'a')
2272+
return range_string(buf, end, ptr, spec, fmt);
2273+
return resource_string(buf, end, ptr, spec, fmt);
2274+
}
2275+
22322276
int __init no_hash_pointers_enable(char *str)
22332277
{
22342278
if (no_hash_pointers)
@@ -2277,6 +2321,7 @@ char *rust_fmt_argument(char *buf, char *end, void *ptr);
22772321
* - 'Bb' as above with module build ID (for use in backtraces)
22782322
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
22792323
* - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
2324+
* - 'ra' For struct ranges, e.g., [range 0x0000000000000000 - 0x00000000000000ff]
22802325
* - 'b[l]' For a bitmap, the number of bits is determined by the field
22812326
* width which must be explicitly specified either as part of the
22822327
* 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,
24012446
return symbol_string(buf, end, ptr, spec, fmt);
24022447
case 'R':
24032448
case 'r':
2404-
return resource_string(buf, end, ptr, spec, fmt);
2449+
return resource_or_range(fmt, buf, end, ptr, spec);
24052450
case 'h':
24062451
return hex_string(buf, end, ptr, spec, fmt);
24072452
case 'b':

0 commit comments

Comments
 (0)