diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace.c | 76 | ||||
-rw-r--r-- | kernel/trace/trace.h | 2 | ||||
-rw-r--r-- | kernel/trace/trace_entries.h | 23 | ||||
-rw-r--r-- | kernel/trace/trace_output.c | 75 | ||||
-rw-r--r-- | kernel/trace/trace_output.h | 2 |
5 files changed, 174 insertions, 4 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4021a5e66412..5043a0c4dde0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -350,6 +350,77 @@ void tracing_on(void) | |||
350 | } | 350 | } |
351 | EXPORT_SYMBOL_GPL(tracing_on); | 351 | EXPORT_SYMBOL_GPL(tracing_on); |
352 | 352 | ||
353 | /** | ||
354 | * __trace_puts - write a constant string into the trace buffer. | ||
355 | * @ip: The address of the caller | ||
356 | * @str: The constant string to write | ||
357 | * @size: The size of the string. | ||
358 | */ | ||
359 | int __trace_puts(unsigned long ip, const char *str, int size) | ||
360 | { | ||
361 | struct ring_buffer_event *event; | ||
362 | struct ring_buffer *buffer; | ||
363 | struct print_entry *entry; | ||
364 | unsigned long irq_flags; | ||
365 | int alloc; | ||
366 | |||
367 | alloc = sizeof(*entry) + size + 2; /* possible \n added */ | ||
368 | |||
369 | local_save_flags(irq_flags); | ||
370 | buffer = global_trace.trace_buffer.buffer; | ||
371 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, | ||
372 | irq_flags, preempt_count()); | ||
373 | if (!event) | ||
374 | return 0; | ||
375 | |||
376 | entry = ring_buffer_event_data(event); | ||
377 | entry->ip = ip; | ||
378 | |||
379 | memcpy(&entry->buf, str, size); | ||
380 | |||
381 | /* Add a newline if necessary */ | ||
382 | if (entry->buf[size - 1] != '\n') { | ||
383 | entry->buf[size] = '\n'; | ||
384 | entry->buf[size + 1] = '\0'; | ||
385 | } else | ||
386 | entry->buf[size] = '\0'; | ||
387 | |||
388 | __buffer_unlock_commit(buffer, event); | ||
389 | |||
390 | return size; | ||
391 | } | ||
392 | EXPORT_SYMBOL_GPL(__trace_puts); | ||
393 | |||
394 | /** | ||
395 | * __trace_bputs - write the pointer to a constant string into trace buffer | ||
396 | * @ip: The address of the caller | ||
397 | * @str: The constant string to write to the buffer to | ||
398 | */ | ||
399 | int __trace_bputs(unsigned long ip, const char *str) | ||
400 | { | ||
401 | struct ring_buffer_event *event; | ||
402 | struct ring_buffer *buffer; | ||
403 | struct bputs_entry *entry; | ||
404 | unsigned long irq_flags; | ||
405 | int size = sizeof(struct bputs_entry); | ||
406 | |||
407 | local_save_flags(irq_flags); | ||
408 | buffer = global_trace.trace_buffer.buffer; | ||
409 | event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, | ||
410 | irq_flags, preempt_count()); | ||
411 | if (!event) | ||
412 | return 0; | ||
413 | |||
414 | entry = ring_buffer_event_data(event); | ||
415 | entry->ip = ip; | ||
416 | entry->str = str; | ||
417 | |||
418 | __buffer_unlock_commit(buffer, event); | ||
419 | |||
420 | return 1; | ||
421 | } | ||
422 | EXPORT_SYMBOL_GPL(__trace_bputs); | ||
423 | |||
353 | #ifdef CONFIG_TRACER_SNAPSHOT | 424 | #ifdef CONFIG_TRACER_SNAPSHOT |
354 | /** | 425 | /** |
355 | * trace_snapshot - take a snapshot of the current buffer. | 426 | * trace_snapshot - take a snapshot of the current buffer. |
@@ -2475,6 +2546,11 @@ enum print_line_t print_trace_line(struct trace_iterator *iter) | |||
2475 | return ret; | 2546 | return ret; |
2476 | } | 2547 | } |
2477 | 2548 | ||
2549 | if (iter->ent->type == TRACE_BPUTS && | ||
2550 | trace_flags & TRACE_ITER_PRINTK && | ||
2551 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | ||
2552 | return trace_print_bputs_msg_only(iter); | ||
2553 | |||
2478 | if (iter->ent->type == TRACE_BPRINT && | 2554 | if (iter->ent->type == TRACE_BPRINT && |
2479 | trace_flags & TRACE_ITER_PRINTK && | 2555 | trace_flags & TRACE_ITER_PRINTK && |
2480 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | 2556 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 26bc71834041..d5764a8532e2 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -34,6 +34,7 @@ enum trace_type { | |||
34 | TRACE_GRAPH_ENT, | 34 | TRACE_GRAPH_ENT, |
35 | TRACE_USER_STACK, | 35 | TRACE_USER_STACK, |
36 | TRACE_BLK, | 36 | TRACE_BLK, |
37 | TRACE_BPUTS, | ||
37 | 38 | ||
38 | __TRACE_LAST_TYPE, | 39 | __TRACE_LAST_TYPE, |
39 | }; | 40 | }; |
@@ -277,6 +278,7 @@ extern void __ftrace_bad_type(void); | |||
277 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ | 278 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ |
278 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ | 279 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ |
279 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ | 280 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ |
281 | IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS); \ | ||
280 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ | 282 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ |
281 | TRACE_MMIO_RW); \ | 283 | TRACE_MMIO_RW); \ |
282 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ | 284 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ |
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 4108e1250ca2..e2d027ac66a2 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h | |||
@@ -223,8 +223,8 @@ FTRACE_ENTRY(bprint, bprint_entry, | |||
223 | __dynamic_array( u32, buf ) | 223 | __dynamic_array( u32, buf ) |
224 | ), | 224 | ), |
225 | 225 | ||
226 | F_printk("%08lx fmt:%p", | 226 | F_printk("%pf: %s", |
227 | __entry->ip, __entry->fmt), | 227 | (void *)__entry->ip, __entry->fmt), |
228 | 228 | ||
229 | FILTER_OTHER | 229 | FILTER_OTHER |
230 | ); | 230 | ); |
@@ -238,8 +238,23 @@ FTRACE_ENTRY(print, print_entry, | |||
238 | __dynamic_array( char, buf ) | 238 | __dynamic_array( char, buf ) |
239 | ), | 239 | ), |
240 | 240 | ||
241 | F_printk("%08lx %s", | 241 | F_printk("%pf: %s", |
242 | __entry->ip, __entry->buf), | 242 | (void *)__entry->ip, __entry->buf), |
243 | |||
244 | FILTER_OTHER | ||
245 | ); | ||
246 | |||
247 | FTRACE_ENTRY(bputs, bputs_entry, | ||
248 | |||
249 | TRACE_BPUTS, | ||
250 | |||
251 | F_STRUCT( | ||
252 | __field( unsigned long, ip ) | ||
253 | __field( const char *, str ) | ||
254 | ), | ||
255 | |||
256 | F_printk("%pf: %s", | ||
257 | (void *)__entry->ip, __entry->str), | ||
243 | 258 | ||
244 | FILTER_OTHER | 259 | FILTER_OTHER |
245 | ); | 260 | ); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 2edc7220d017..19f48e7edc39 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -37,6 +37,22 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s) | |||
37 | return ret; | 37 | return ret; |
38 | } | 38 | } |
39 | 39 | ||
40 | enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) | ||
41 | { | ||
42 | struct trace_seq *s = &iter->seq; | ||
43 | struct trace_entry *entry = iter->ent; | ||
44 | struct bputs_entry *field; | ||
45 | int ret; | ||
46 | |||
47 | trace_assign_type(field, entry); | ||
48 | |||
49 | ret = trace_seq_puts(s, field->str); | ||
50 | if (!ret) | ||
51 | return TRACE_TYPE_PARTIAL_LINE; | ||
52 | |||
53 | return TRACE_TYPE_HANDLED; | ||
54 | } | ||
55 | |||
40 | enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) | 56 | enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) |
41 | { | 57 | { |
42 | struct trace_seq *s = &iter->seq; | 58 | struct trace_seq *s = &iter->seq; |
@@ -1244,6 +1260,64 @@ static struct trace_event trace_user_stack_event = { | |||
1244 | .funcs = &trace_user_stack_funcs, | 1260 | .funcs = &trace_user_stack_funcs, |
1245 | }; | 1261 | }; |
1246 | 1262 | ||
1263 | /* TRACE_BPUTS */ | ||
1264 | static enum print_line_t | ||
1265 | trace_bputs_print(struct trace_iterator *iter, int flags, | ||
1266 | struct trace_event *event) | ||
1267 | { | ||
1268 | struct trace_entry *entry = iter->ent; | ||
1269 | struct trace_seq *s = &iter->seq; | ||
1270 | struct bputs_entry *field; | ||
1271 | |||
1272 | trace_assign_type(field, entry); | ||
1273 | |||
1274 | if (!seq_print_ip_sym(s, field->ip, flags)) | ||
1275 | goto partial; | ||
1276 | |||
1277 | if (!trace_seq_puts(s, ": ")) | ||
1278 | goto partial; | ||
1279 | |||
1280 | if (!trace_seq_puts(s, field->str)) | ||
1281 | goto partial; | ||
1282 | |||
1283 | return TRACE_TYPE_HANDLED; | ||
1284 | |||
1285 | partial: | ||
1286 | return TRACE_TYPE_PARTIAL_LINE; | ||
1287 | } | ||
1288 | |||
1289 | |||
1290 | static enum print_line_t | ||
1291 | trace_bputs_raw(struct trace_iterator *iter, int flags, | ||
1292 | struct trace_event *event) | ||
1293 | { | ||
1294 | struct bputs_entry *field; | ||
1295 | struct trace_seq *s = &iter->seq; | ||
1296 | |||
1297 | trace_assign_type(field, iter->ent); | ||
1298 | |||
1299 | if (!trace_seq_printf(s, ": %lx : ", field->ip)) | ||
1300 | goto partial; | ||
1301 | |||
1302 | if (!trace_seq_puts(s, field->str)) | ||
1303 | goto partial; | ||
1304 | |||
1305 | return TRACE_TYPE_HANDLED; | ||
1306 | |||
1307 | partial: | ||
1308 | return TRACE_TYPE_PARTIAL_LINE; | ||
1309 | } | ||
1310 | |||
1311 | static struct trace_event_functions trace_bputs_funcs = { | ||
1312 | .trace = trace_bputs_print, | ||
1313 | .raw = trace_bputs_raw, | ||
1314 | }; | ||
1315 | |||
1316 | static struct trace_event trace_bputs_event = { | ||
1317 | .type = TRACE_BPUTS, | ||
1318 | .funcs = &trace_bputs_funcs, | ||
1319 | }; | ||
1320 | |||
1247 | /* TRACE_BPRINT */ | 1321 | /* TRACE_BPRINT */ |
1248 | static enum print_line_t | 1322 | static enum print_line_t |
1249 | trace_bprint_print(struct trace_iterator *iter, int flags, | 1323 | trace_bprint_print(struct trace_iterator *iter, int flags, |
@@ -1356,6 +1430,7 @@ static struct trace_event *events[] __initdata = { | |||
1356 | &trace_wake_event, | 1430 | &trace_wake_event, |
1357 | &trace_stack_event, | 1431 | &trace_stack_event, |
1358 | &trace_user_stack_event, | 1432 | &trace_user_stack_event, |
1433 | &trace_bputs_event, | ||
1359 | &trace_bprint_event, | 1434 | &trace_bprint_event, |
1360 | &trace_print_event, | 1435 | &trace_print_event, |
1361 | NULL | 1436 | NULL |
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h index c038eba0492b..af77870de278 100644 --- a/kernel/trace/trace_output.h +++ b/kernel/trace/trace_output.h | |||
@@ -5,6 +5,8 @@ | |||
5 | #include "trace.h" | 5 | #include "trace.h" |
6 | 6 | ||
7 | extern enum print_line_t | 7 | extern enum print_line_t |
8 | trace_print_bputs_msg_only(struct trace_iterator *iter); | ||
9 | extern enum print_line_t | ||
8 | trace_print_bprintk_msg_only(struct trace_iterator *iter); | 10 | trace_print_bprintk_msg_only(struct trace_iterator *iter); |
9 | extern enum print_line_t | 11 | extern enum print_line_t |
10 | trace_print_printk_msg_only(struct trace_iterator *iter); | 12 | trace_print_printk_msg_only(struct trace_iterator *iter); |