Without this, buffers can be printed with __print_array macro that has no formatting options and can be hard to read. The other way is to mimic formatting capability with multiple calls of trace event with one call per row which gives performance impact and different timestamp in each row. Link: http://lkml.kernel.org/r/1573130738-29390-2-git-send-email-piotrx.maziarz@linux.intel.com
Unified · Split
| @@ -45,6 +45,11 @@ const char *trace_print_array_seq(struct trace_seq *p, · 44 unmodified lines | |||
| 45 | const void *buf, int count, | 45 | const void *buf, int count, |
| 46 | size_t el_size); | 46 | size_t el_size); |
| 47 | 47 | ||
| 48 | const char * | ||
| 49 | trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, | ||
| 50 | int prefix_type, int rowsize, int groupsize, | ||
| 51 | const void *buf, size_t len, bool ascii); | ||
| 52 | |||
| 48 | struct trace_iterator; | 53 | struct trace_iterator; |
| 49 | struct trace_event; | 54 | struct trace_event; |
| 50 | 55 | ||
| @@ -92,6 +92,10 @@ extern int trace_seq_path(struct trace_seq *s, const struct path *path); · 91 unmodified lines | |||
| 92 | extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, | 92 | extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, |
| 93 | int nmaskbits); | 93 | int nmaskbits); |
| 94 | 94 | ||
| 95 | extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, | ||
| 96 | int prefix_type, int rowsize, int groupsize, | ||
| 97 | const void *buf, size_t len, bool ascii); | ||
| 98 | |||
| 95 | #else /* CONFIG_TRACING */ | 99 | #else /* CONFIG_TRACING */ |
| 96 | static inline void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) | 100 | static inline void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) |
| 97 | { | 101 | { |
| @@ -340,6 +340,12 @@ TRACE_MAKE_SYSTEM_STR(); · 339 unmodified lines | |||
| 340 | trace_print_array_seq(p, array, count, el_size); \ | 340 | trace_print_array_seq(p, array, count, el_size); \ |
| 341 | }) | 341 | }) |
| 342 | 342 | ||
| 343 | #undef __print_hex_dump | ||
| 344 | #define __print_hex_dump(prefix_str, prefix_type, \ | ||
| 345 | rowsize, groupsize, buf, len, ascii) \ | ||
| 346 | trace_print_hex_dump_seq(p, prefix_str, prefix_type, \ | ||
| 347 | rowsize, groupsize, buf, len, ascii) | ||
| 348 | |||
| 343 | #undef DECLARE_EVENT_CLASS | 349 | #undef DECLARE_EVENT_CLASS |
| 344 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 350 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 345 | static notrace enum print_line_t \ | 351 | static notrace enum print_line_t \ |
| @@ -274,6 +274,21 @@ trace_print_array_seq(struct trace_seq *p, const void *buf, int count, · 273 unmodified lines | |||
| 274 | } | 274 | } |
| 275 | EXPORT_SYMBOL(trace_print_array_seq); | 275 | EXPORT_SYMBOL(trace_print_array_seq); |
| 276 | 276 | ||
| 277 | const char * | ||
| 278 | trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, | ||
| 279 | int prefix_type, int rowsize, int groupsize, | ||
| 280 | const void *buf, size_t len, bool ascii) | ||
| 281 | { | ||
| 282 | const char *ret = trace_seq_buffer_ptr(p); | ||
| 283 | |||
| 284 | trace_seq_putc(p, '\n'); | ||
| 285 | trace_seq_hex_dump(p, prefix_str, prefix_type, | ||
| 286 | rowsize, groupsize, buf, len, ascii); | ||
| 287 | trace_seq_putc(p, 0); | ||
| 288 | return ret; | ||
| 289 | } | ||
| 290 | EXPORT_SYMBOL(trace_print_hex_dump_seq); | ||
| 291 | |||
| 277 | int trace_raw_output_prep(struct trace_iterator *iter, | 292 | int trace_raw_output_prep(struct trace_iterator *iter, |
| 278 | struct trace_event *trace_event) | 293 | struct trace_event *trace_event) |
| 279 | { | 294 | { |
| @@ -376,3 +376,33 @@ int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) · 375 unmodified lines | |||
| 376 | return seq_buf_to_user(&s->seq, ubuf, cnt); | 376 | return seq_buf_to_user(&s->seq, ubuf, cnt); |
| 377 | } | 377 | } |
| 378 | EXPORT_SYMBOL_GPL(trace_seq_to_user); | 378 | EXPORT_SYMBOL_GPL(trace_seq_to_user); |
| 379 | |||
| 380 | int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, | ||
| 381 | int prefix_type, int rowsize, int groupsize, | ||
| 382 | const void *buf, size_t len, bool ascii) | ||
| 383 | { | ||
| 384 | unsigned int save_len = s->seq.len; | ||
| 385 | |||
| 386 | if (s->full) | ||
| 387 | return 0; | ||
| 388 | |||
| 389 | __trace_seq_init(s); | ||
| 390 | |||
| 391 | if (TRACE_SEQ_BUF_LEFT(s) < 1) { | ||
| 392 | s->full = 1; | ||
| 393 | return 0; | ||
| 394 | } | ||
| 395 | |||
| 396 | seq_buf_hex_dump(&(s->seq), prefix_str, | ||
| 397 | prefix_type, rowsize, groupsize, | ||
| 398 | buf, len, ascii); | ||
| 399 | |||
| 400 | if (unlikely(seq_buf_has_overflowed(&s->seq))) { | ||
| 401 | s->seq.len = save_len; | ||
| 402 | s->full = 1; | ||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | return 1; | ||
| 407 | } | ||
| 408 | EXPORT_SYMBOL(trace_seq_hex_dump); | ||