trace_marker_raw currently records its bytes in TRACE_RAW_DATA events, but the event output path derives the byte count from the padded record size in the ring buffer. As a result, the printed raw-data payload is rounded up and small writes do not preserve their true length.
Keep the true payload length in the TRACE_RAW_DATA event itself and use that field when printing the bytes. This leaves the ring buffer record size semantics unchanged while letting trace_marker_raw report the exact payload that was written. Signed-off-by: Cao Ruichuang <[email protected]> --- kernel/trace/trace.c | 11 ++++++----- kernel/trace/trace_entries.h | 1 + kernel/trace/trace_output.c | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a626211ce..d9cb643b8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6906,11 +6906,13 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr, struct ring_buffer_event *event; struct trace_buffer *buffer; struct raw_data_entry *entry; + size_t payload_len; ssize_t written; size_t size; /* cnt includes both the entry->id and the data behind it. */ - size = struct_offset(entry, id) + cnt; + payload_len = cnt - sizeof(entry->id); + size = struct_offset(entry, buf) + payload_len; buffer = tr->array_buffer.buffer; @@ -6924,10 +6926,9 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr, return -EBADF; entry = ring_buffer_event_data(event); - unsafe_memcpy(&entry->id, buf, cnt, - "id and content already reserved on ring buffer" - "'buf' includes the 'id' and the data." - "'entry' was allocated with cnt from 'id'."); + memcpy(&entry->id, buf, sizeof(entry->id)); + entry->len = payload_len; + memcpy(entry->buf, buf + sizeof(entry->id), payload_len); written = cnt; __buffer_unlock_commit(buffer, event); diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 54417468f..5f867a144 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -288,6 +288,7 @@ FTRACE_ENTRY(raw_data, raw_data_entry, F_STRUCT( __field( unsigned int, id ) + __field(unsigned int, len) __dynamic_array( char, buf ) ), diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 1996d7aba..4e1edfa05 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -1817,13 +1817,13 @@ static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags, struct trace_event *event) { struct raw_data_entry *field; - int i; + unsigned int i; trace_assign_type(field, iter->ent); trace_seq_printf(&iter->seq, "# %x buf:", field->id); - for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++) + for (i = 0; i < field->len; i++) trace_seq_printf(&iter->seq, " %02x", (unsigned char)field->buf[i]); -- 2.39.5 (Apple Git-154)
