diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bebd263f582..d78cbc4fc51 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -154,6 +154,7 @@ enum trace_iterator_flags { | |||
154 | TRACE_ITER_SYM_ADDR = 0x04, | 154 | TRACE_ITER_SYM_ADDR = 0x04, |
155 | TRACE_ITER_VERBOSE = 0x08, | 155 | TRACE_ITER_VERBOSE = 0x08, |
156 | TRACE_ITER_RAW = 0x10, | 156 | TRACE_ITER_RAW = 0x10, |
157 | TRACE_ITER_BIN = 0x20, | ||
157 | }; | 158 | }; |
158 | 159 | ||
159 | #define TRACE_ITER_SYM_MASK \ | 160 | #define TRACE_ITER_SYM_MASK \ |
@@ -166,6 +167,7 @@ static const char *trace_options[] = { | |||
166 | "sym-addr", | 167 | "sym-addr", |
167 | "verbose", | 168 | "verbose", |
168 | "raw", | 169 | "raw", |
170 | "bin", | ||
169 | NULL | 171 | NULL |
170 | }; | 172 | }; |
171 | 173 | ||
@@ -275,6 +277,18 @@ trace_seq_putc(struct trace_seq *s, unsigned char c) | |||
275 | return 1; | 277 | return 1; |
276 | } | 278 | } |
277 | 279 | ||
280 | static notrace int | ||
281 | trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) | ||
282 | { | ||
283 | if (len > ((PAGE_SIZE - 1) - s->len)) | ||
284 | return 0; | ||
285 | |||
286 | memcpy(s->buffer + s->len, mem, len); | ||
287 | s->len += len; | ||
288 | |||
289 | return len; | ||
290 | } | ||
291 | |||
278 | static notrace void | 292 | static notrace void |
279 | trace_seq_reset(struct trace_seq *s) | 293 | trace_seq_reset(struct trace_seq *s) |
280 | { | 294 | { |
@@ -1261,6 +1275,39 @@ static notrace int print_raw_fmt(struct trace_iterator *iter) | |||
1261 | return 1; | 1275 | return 1; |
1262 | } | 1276 | } |
1263 | 1277 | ||
1278 | #define SEQ_PUT_FIELD_RET(s, x) \ | ||
1279 | do { \ | ||
1280 | if (!trace_seq_putmem(s, &(x), sizeof(x))) \ | ||
1281 | return 0; \ | ||
1282 | } while (0) | ||
1283 | |||
1284 | static notrace int print_bin_fmt(struct trace_iterator *iter) | ||
1285 | { | ||
1286 | struct trace_seq *s = &iter->seq; | ||
1287 | struct trace_entry *entry; | ||
1288 | |||
1289 | entry = iter->ent; | ||
1290 | |||
1291 | SEQ_PUT_FIELD_RET(s, entry->pid); | ||
1292 | SEQ_PUT_FIELD_RET(s, entry->cpu); | ||
1293 | SEQ_PUT_FIELD_RET(s, entry->t); | ||
1294 | |||
1295 | switch (entry->type) { | ||
1296 | case TRACE_FN: | ||
1297 | SEQ_PUT_FIELD_RET(s, entry->fn.ip); | ||
1298 | SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip); | ||
1299 | break; | ||
1300 | case TRACE_CTX: | ||
1301 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid); | ||
1302 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio); | ||
1303 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state); | ||
1304 | SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid); | ||
1305 | SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); | ||
1306 | break; | ||
1307 | } | ||
1308 | return 1; | ||
1309 | } | ||
1310 | |||
1264 | static int trace_empty(struct trace_iterator *iter) | 1311 | static int trace_empty(struct trace_iterator *iter) |
1265 | { | 1312 | { |
1266 | struct trace_array_cpu *data; | 1313 | struct trace_array_cpu *data; |
@@ -1279,6 +1326,9 @@ static int trace_empty(struct trace_iterator *iter) | |||
1279 | 1326 | ||
1280 | static int print_trace_line(struct trace_iterator *iter) | 1327 | static int print_trace_line(struct trace_iterator *iter) |
1281 | { | 1328 | { |
1329 | if (trace_flags & TRACE_ITER_BIN) | ||
1330 | return print_bin_fmt(iter); | ||
1331 | |||
1282 | if (trace_flags & TRACE_ITER_RAW) | 1332 | if (trace_flags & TRACE_ITER_RAW) |
1283 | return print_raw_fmt(iter); | 1333 | return print_raw_fmt(iter); |
1284 | 1334 | ||