Skip to content

Commit 3c72059

Browse files
miklelappogregkh
authored andcommitted
stm class: sys-t: Improve ftrace source handling
Package messages from ftrace source with SyS-T Structured Binary Data (later SBD) header and 64-bit ID. This provides modification-free compatibility between ftrace and SyS-T arguments structure by applying 0xFFFF mask on message ID. This happens due to the fact that SBD and ftrace structures have the same principle of data storage: <header><args binary blob>. The headers are bit-to-bit compatible and both contain event/catalog ID with the exception, that ftrace header contains more fields within 64 bits which needs to be masked during encoding process, since SBD standard doesn't support mask of ID field. 0 15 16 23 24 31 32 39 40 63 ftrace: <event_id> <flags> <preempt> <-pid-> <----> SBD: <------- msg_id ------------------------------> Signed-off-by: Mikhail Lappo <[email protected]> Signed-off-by: Alexander Shishkin <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ee27f44 commit 3c72059

File tree

1 file changed

+83
-7
lines changed

1 file changed

+83
-7
lines changed

drivers/hwtracing/stm/p_sys-t.c

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum sys_t_message_type {
2020
MIPI_SYST_TYPE_RAW = 6,
2121
MIPI_SYST_TYPE_SHORT64,
2222
MIPI_SYST_TYPE_CLOCK,
23+
MIPI_SYST_TYPE_SBD,
2324
};
2425

2526
enum sys_t_message_severity {
@@ -53,6 +54,19 @@ enum sys_t_message_string_subtype {
5354
MIPI_SYST_STRING_PRINTF_64 = 12,
5455
};
5556

57+
/**
58+
* enum sys_t_message_sbd_subtype - SyS-T SBD message subtypes
59+
* @MIPI_SYST_SBD_ID32: SBD message with 32-bit message ID
60+
* @MIPI_SYST_SBD_ID64: SBD message with 64-bit message ID
61+
*
62+
* Structured Binary Data messages can send information of arbitrary length,
63+
* together with ID's that describe BLOB's content and layout.
64+
*/
65+
enum sys_t_message_sbd_subtype {
66+
MIPI_SYST_SBD_ID32 = 0,
67+
MIPI_SYST_SBD_ID64 = 1,
68+
};
69+
5670
#define MIPI_SYST_TYPE(t) ((u32)(MIPI_SYST_TYPE_ ## t))
5771
#define MIPI_SYST_SEVERITY(s) ((u32)(MIPI_SYST_SEVERITY_ ## s) << 4)
5872
#define MIPI_SYST_OPT_LOC BIT(8)
@@ -75,6 +89,20 @@ enum sys_t_message_string_subtype {
7589
#define CLOCK_SYNC_HEADER (MIPI_SYST_TYPES(CLOCK, TRANSPORT_SYNC) | \
7690
MIPI_SYST_SEVERITY(MAX))
7791

92+
/*
93+
* SyS-T and ftrace headers are compatible to an extent that ftrace event ID
94+
* and args can be treated as SyS-T SBD message with 64-bit ID and arguments
95+
* BLOB right behind the header without modification. Bits [16:63] coming
96+
* together with message ID from ftrace aren't used by SBD and must be zeroed.
97+
*
98+
* 0 15 16 23 24 31 32 39 40 63
99+
* ftrace: <event_id> <flags> <preempt> <-pid-> <----> <args>
100+
* SBD: <------- msg_id ------------------------------> <BLOB>
101+
*/
102+
#define SBD_HEADER (MIPI_SYST_TYPES(SBD, ID64) | \
103+
MIPI_SYST_SEVERITY(INFO) | \
104+
MIPI_SYST_OPT_GUID)
105+
78106
struct sys_t_policy_node {
79107
uuid_t uuid;
80108
bool do_len;
@@ -284,15 +312,67 @@ sys_t_clock_sync(struct stm_data *data, unsigned int m, unsigned int c)
284312
return sizeof(header) + sizeof(payload);
285313
}
286314

315+
static inline u32 sys_t_header(struct stm_source_data *source)
316+
{
317+
if (source && source->type == STM_FTRACE)
318+
return SBD_HEADER;
319+
return DATA_HEADER;
320+
}
321+
322+
static ssize_t sys_t_write_data(struct stm_data *data,
323+
struct stm_source_data *source,
324+
unsigned int master, unsigned int channel,
325+
bool ts_first, const void *buf, size_t count)
326+
{
327+
ssize_t sz;
328+
const unsigned char nil = 0;
329+
330+
/*
331+
* Ftrace is zero-copy compatible with SyS-T SBD, but requires
332+
* special handling of first 64 bits. Trim and send them separately
333+
* to avoid damage on original ftrace buffer.
334+
*/
335+
if (source && source->type == STM_FTRACE) {
336+
u64 compat_ftrace_header;
337+
ssize_t header_sz;
338+
ssize_t buf_sz;
339+
340+
if (count < sizeof(compat_ftrace_header))
341+
return -EINVAL;
342+
343+
/* SBD only makes use of low 16 bits (event ID) from ftrace event */
344+
compat_ftrace_header = *(u64 *)buf & 0xffff;
345+
header_sz = stm_data_write(data, master, channel, false,
346+
&compat_ftrace_header,
347+
sizeof(compat_ftrace_header));
348+
if (header_sz != sizeof(compat_ftrace_header))
349+
return header_sz;
350+
351+
buf_sz = stm_data_write(data, master, channel, false,
352+
buf + header_sz, count - header_sz);
353+
if (buf_sz != count - header_sz)
354+
return buf_sz;
355+
sz = header_sz + buf_sz;
356+
} else {
357+
sz = stm_data_write(data, master, channel, false, buf, count);
358+
}
359+
360+
if (sz <= 0)
361+
return sz;
362+
363+
data->packet(data, master, channel, STP_PACKET_FLAG, 0, 0, &nil);
364+
365+
return sz;
366+
}
367+
287368
static ssize_t sys_t_write(struct stm_data *data, struct stm_output *output,
288369
unsigned int chan, const char *buf, size_t count,
289370
struct stm_source_data *source)
290371
{
291372
struct sys_t_output *op = output->pdrv_private;
292373
unsigned int c = output->channel + chan;
293374
unsigned int m = output->master;
294-
const unsigned char nil = 0;
295-
u32 header = DATA_HEADER;
375+
u32 header = sys_t_header(source);
296376
u8 uuid[UUID_SIZE];
297377
ssize_t sz;
298378

@@ -349,11 +429,7 @@ static ssize_t sys_t_write(struct stm_data *data, struct stm_output *output,
349429
}
350430

351431
/* DATA */
352-
sz = stm_data_write(data, m, c, false, buf, count);
353-
if (sz > 0)
354-
data->packet(data, m, c, STP_PACKET_FLAG, 0, 0, &nil);
355-
356-
return sz;
432+
return sys_t_write_data(data, source, m, c, false, buf, count);
357433
}
358434

359435
static const struct stm_protocol_driver sys_t_pdrv = {

0 commit comments

Comments
 (0)