diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2008-08-01 12:26:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-14 04:35:15 -0400 |
commit | 2e2ca155cd2213b4f398031180fb3d399d5b7db9 (patch) | |
tree | 027295832950e23ac4edc84e43550d02e9a1acc6 /kernel | |
parent | fed1939c64d2288938fdc1c367d49082da65e195 (diff) |
ftrace: new continue entry - separate out from trace_entry
Some tracers will need to work with more than one entry. In order to do this
the trace_entry structure was split into two fields. One for the start of
all entries, and one to continue an existing entry.
The trace_entry structure now has a "field" entry that consists of the previous
content of the trace_entry, and a "cont" entry that is just a string buffer
the size of the "field" entry.
Thanks to Andrew Morton for suggesting this idea.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace.c | 267 | ||||
-rw-r--r-- | kernel/trace/trace.h | 17 | ||||
-rw-r--r-- | kernel/trace/trace_mmiotrace.c | 12 |
3 files changed, 160 insertions, 136 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8f3fb3db61c3..76dfe6d2466c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -817,10 +817,11 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) | |||
817 | 817 | ||
818 | pc = preempt_count(); | 818 | pc = preempt_count(); |
819 | 819 | ||
820 | entry->preempt_count = pc & 0xff; | 820 | entry->field.preempt_count = pc & 0xff; |
821 | entry->pid = (tsk) ? tsk->pid : 0; | 821 | entry->field.pid = (tsk) ? tsk->pid : 0; |
822 | entry->t = ftrace_now(raw_smp_processor_id()); | 822 | entry->field.t = ftrace_now(raw_smp_processor_id()); |
823 | entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | | 823 | entry->field.flags = |
824 | (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | | ||
824 | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | | 825 | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | |
825 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | | 826 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | |
826 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); | 827 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); |
@@ -835,11 +836,11 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, | |||
835 | 836 | ||
836 | raw_local_irq_save(irq_flags); | 837 | raw_local_irq_save(irq_flags); |
837 | __raw_spin_lock(&data->lock); | 838 | __raw_spin_lock(&data->lock); |
838 | entry = tracing_get_trace_entry(tr, data); | 839 | entry = tracing_get_trace_entry(tr, data); |
839 | tracing_generic_entry_update(entry, flags); | 840 | tracing_generic_entry_update(entry, flags); |
840 | entry->type = TRACE_FN; | 841 | entry->type = TRACE_FN; |
841 | entry->fn.ip = ip; | 842 | entry->field.fn.ip = ip; |
842 | entry->fn.parent_ip = parent_ip; | 843 | entry->field.fn.parent_ip = parent_ip; |
843 | __raw_spin_unlock(&data->lock); | 844 | __raw_spin_unlock(&data->lock); |
844 | raw_local_irq_restore(irq_flags); | 845 | raw_local_irq_restore(irq_flags); |
845 | } | 846 | } |
@@ -862,10 +863,10 @@ void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data, | |||
862 | raw_local_irq_save(irq_flags); | 863 | raw_local_irq_save(irq_flags); |
863 | __raw_spin_lock(&data->lock); | 864 | __raw_spin_lock(&data->lock); |
864 | 865 | ||
865 | entry = tracing_get_trace_entry(tr, data); | 866 | entry = tracing_get_trace_entry(tr, data); |
866 | tracing_generic_entry_update(entry, 0); | 867 | tracing_generic_entry_update(entry, 0); |
867 | entry->type = TRACE_MMIO_RW; | 868 | entry->type = TRACE_MMIO_RW; |
868 | entry->mmiorw = *rw; | 869 | entry->field.mmiorw = *rw; |
869 | 870 | ||
870 | __raw_spin_unlock(&data->lock); | 871 | __raw_spin_unlock(&data->lock); |
871 | raw_local_irq_restore(irq_flags); | 872 | raw_local_irq_restore(irq_flags); |
@@ -882,10 +883,10 @@ void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data, | |||
882 | raw_local_irq_save(irq_flags); | 883 | raw_local_irq_save(irq_flags); |
883 | __raw_spin_lock(&data->lock); | 884 | __raw_spin_lock(&data->lock); |
884 | 885 | ||
885 | entry = tracing_get_trace_entry(tr, data); | 886 | entry = tracing_get_trace_entry(tr, data); |
886 | tracing_generic_entry_update(entry, 0); | 887 | tracing_generic_entry_update(entry, 0); |
887 | entry->type = TRACE_MMIO_MAP; | 888 | entry->type = TRACE_MMIO_MAP; |
888 | entry->mmiomap = *map; | 889 | entry->field.mmiomap = *map; |
889 | 890 | ||
890 | __raw_spin_unlock(&data->lock); | 891 | __raw_spin_unlock(&data->lock); |
891 | raw_local_irq_restore(irq_flags); | 892 | raw_local_irq_restore(irq_flags); |
@@ -909,12 +910,12 @@ void __trace_stack(struct trace_array *tr, | |||
909 | tracing_generic_entry_update(entry, flags); | 910 | tracing_generic_entry_update(entry, flags); |
910 | entry->type = TRACE_STACK; | 911 | entry->type = TRACE_STACK; |
911 | 912 | ||
912 | memset(&entry->stack, 0, sizeof(entry->stack)); | 913 | memset(&entry->field.stack, 0, sizeof(entry->field.stack)); |
913 | 914 | ||
914 | trace.nr_entries = 0; | 915 | trace.nr_entries = 0; |
915 | trace.max_entries = FTRACE_STACK_ENTRIES; | 916 | trace.max_entries = FTRACE_STACK_ENTRIES; |
916 | trace.skip = skip; | 917 | trace.skip = skip; |
917 | trace.entries = entry->stack.caller; | 918 | trace.entries = entry->field.stack.caller; |
918 | 919 | ||
919 | save_stack_trace(&trace); | 920 | save_stack_trace(&trace); |
920 | } | 921 | } |
@@ -930,12 +931,12 @@ __trace_special(void *__tr, void *__data, | |||
930 | 931 | ||
931 | raw_local_irq_save(irq_flags); | 932 | raw_local_irq_save(irq_flags); |
932 | __raw_spin_lock(&data->lock); | 933 | __raw_spin_lock(&data->lock); |
933 | entry = tracing_get_trace_entry(tr, data); | 934 | entry = tracing_get_trace_entry(tr, data); |
934 | tracing_generic_entry_update(entry, 0); | 935 | tracing_generic_entry_update(entry, 0); |
935 | entry->type = TRACE_SPECIAL; | 936 | entry->type = TRACE_SPECIAL; |
936 | entry->special.arg1 = arg1; | 937 | entry->field.special.arg1 = arg1; |
937 | entry->special.arg2 = arg2; | 938 | entry->field.special.arg2 = arg2; |
938 | entry->special.arg3 = arg3; | 939 | entry->field.special.arg3 = arg3; |
939 | __trace_stack(tr, data, irq_flags, 4); | 940 | __trace_stack(tr, data, irq_flags, 4); |
940 | __raw_spin_unlock(&data->lock); | 941 | __raw_spin_unlock(&data->lock); |
941 | raw_local_irq_restore(irq_flags); | 942 | raw_local_irq_restore(irq_flags); |
@@ -955,15 +956,15 @@ tracing_sched_switch_trace(struct trace_array *tr, | |||
955 | 956 | ||
956 | raw_local_irq_save(irq_flags); | 957 | raw_local_irq_save(irq_flags); |
957 | __raw_spin_lock(&data->lock); | 958 | __raw_spin_lock(&data->lock); |
958 | entry = tracing_get_trace_entry(tr, data); | 959 | entry = tracing_get_trace_entry(tr, data); |
959 | tracing_generic_entry_update(entry, flags); | 960 | tracing_generic_entry_update(entry, flags); |
960 | entry->type = TRACE_CTX; | 961 | entry->type = TRACE_CTX; |
961 | entry->ctx.prev_pid = prev->pid; | 962 | entry->field.ctx.prev_pid = prev->pid; |
962 | entry->ctx.prev_prio = prev->prio; | 963 | entry->field.ctx.prev_prio = prev->prio; |
963 | entry->ctx.prev_state = prev->state; | 964 | entry->field.ctx.prev_state = prev->state; |
964 | entry->ctx.next_pid = next->pid; | 965 | entry->field.ctx.next_pid = next->pid; |
965 | entry->ctx.next_prio = next->prio; | 966 | entry->field.ctx.next_prio = next->prio; |
966 | entry->ctx.next_state = next->state; | 967 | entry->field.ctx.next_state = next->state; |
967 | __trace_stack(tr, data, flags, 5); | 968 | __trace_stack(tr, data, flags, 5); |
968 | __raw_spin_unlock(&data->lock); | 969 | __raw_spin_unlock(&data->lock); |
969 | raw_local_irq_restore(irq_flags); | 970 | raw_local_irq_restore(irq_flags); |
@@ -984,12 +985,12 @@ tracing_sched_wakeup_trace(struct trace_array *tr, | |||
984 | entry = tracing_get_trace_entry(tr, data); | 985 | entry = tracing_get_trace_entry(tr, data); |
985 | tracing_generic_entry_update(entry, flags); | 986 | tracing_generic_entry_update(entry, flags); |
986 | entry->type = TRACE_WAKE; | 987 | entry->type = TRACE_WAKE; |
987 | entry->ctx.prev_pid = curr->pid; | 988 | entry->field.ctx.prev_pid = curr->pid; |
988 | entry->ctx.prev_prio = curr->prio; | 989 | entry->field.ctx.prev_prio = curr->prio; |
989 | entry->ctx.prev_state = curr->state; | 990 | entry->field.ctx.prev_state = curr->state; |
990 | entry->ctx.next_pid = wakee->pid; | 991 | entry->field.ctx.next_pid = wakee->pid; |
991 | entry->ctx.next_prio = wakee->prio; | 992 | entry->field.ctx.next_prio = wakee->prio; |
992 | entry->ctx.next_state = wakee->state; | 993 | entry->field.ctx.next_state = wakee->state; |
993 | __trace_stack(tr, data, flags, 6); | 994 | __trace_stack(tr, data, flags, 6); |
994 | __raw_spin_unlock(&data->lock); | 995 | __raw_spin_unlock(&data->lock); |
995 | raw_local_irq_restore(irq_flags); | 996 | raw_local_irq_restore(irq_flags); |
@@ -1118,7 +1119,7 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) | |||
1118 | /* | 1119 | /* |
1119 | * Pick the entry with the smallest timestamp: | 1120 | * Pick the entry with the smallest timestamp: |
1120 | */ | 1121 | */ |
1121 | if (ent && (!next || ent->t < next->t)) { | 1122 | if (ent && (!next || ent->field.t < next->field.t)) { |
1122 | next = ent; | 1123 | next = ent; |
1123 | next_cpu = cpu; | 1124 | next_cpu = cpu; |
1124 | } | 1125 | } |
@@ -1422,19 +1423,20 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) | |||
1422 | static void | 1423 | static void |
1423 | lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) | 1424 | lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) |
1424 | { | 1425 | { |
1426 | struct trace_field *field = &entry->field; | ||
1425 | int hardirq, softirq; | 1427 | int hardirq, softirq; |
1426 | char *comm; | 1428 | char *comm; |
1427 | 1429 | ||
1428 | comm = trace_find_cmdline(entry->pid); | 1430 | comm = trace_find_cmdline(field->pid); |
1429 | 1431 | ||
1430 | trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid); | 1432 | trace_seq_printf(s, "%8.8s-%-5d ", comm, field->pid); |
1431 | trace_seq_printf(s, "%d", cpu); | 1433 | trace_seq_printf(s, "%d", cpu); |
1432 | trace_seq_printf(s, "%c%c", | 1434 | trace_seq_printf(s, "%c%c", |
1433 | (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', | 1435 | (field->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', |
1434 | ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.')); | 1436 | ((field->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.')); |
1435 | 1437 | ||
1436 | hardirq = entry->flags & TRACE_FLAG_HARDIRQ; | 1438 | hardirq = field->flags & TRACE_FLAG_HARDIRQ; |
1437 | softirq = entry->flags & TRACE_FLAG_SOFTIRQ; | 1439 | softirq = field->flags & TRACE_FLAG_SOFTIRQ; |
1438 | if (hardirq && softirq) { | 1440 | if (hardirq && softirq) { |
1439 | trace_seq_putc(s, 'H'); | 1441 | trace_seq_putc(s, 'H'); |
1440 | } else { | 1442 | } else { |
@@ -1448,8 +1450,8 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) | |||
1448 | } | 1450 | } |
1449 | } | 1451 | } |
1450 | 1452 | ||
1451 | if (entry->preempt_count) | 1453 | if (field->preempt_count) |
1452 | trace_seq_printf(s, "%x", entry->preempt_count); | 1454 | trace_seq_printf(s, "%x", field->preempt_count); |
1453 | else | 1455 | else |
1454 | trace_seq_puts(s, "."); | 1456 | trace_seq_puts(s, "."); |
1455 | } | 1457 | } |
@@ -1479,6 +1481,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) | |||
1479 | struct trace_entry *next_entry = find_next_entry(iter, NULL); | 1481 | struct trace_entry *next_entry = find_next_entry(iter, NULL); |
1480 | unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); | 1482 | unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); |
1481 | struct trace_entry *entry = iter->ent; | 1483 | struct trace_entry *entry = iter->ent; |
1484 | struct trace_field *field = &entry->field; | ||
1482 | unsigned long abs_usecs; | 1485 | unsigned long abs_usecs; |
1483 | unsigned long rel_usecs; | 1486 | unsigned long rel_usecs; |
1484 | char *comm; | 1487 | char *comm; |
@@ -1488,17 +1491,17 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) | |||
1488 | 1491 | ||
1489 | if (!next_entry) | 1492 | if (!next_entry) |
1490 | next_entry = entry; | 1493 | next_entry = entry; |
1491 | rel_usecs = ns2usecs(next_entry->t - entry->t); | 1494 | rel_usecs = ns2usecs(next_entry->field.t - entry->field.t); |
1492 | abs_usecs = ns2usecs(entry->t - iter->tr->time_start); | 1495 | abs_usecs = ns2usecs(entry->field.t - iter->tr->time_start); |
1493 | 1496 | ||
1494 | if (verbose) { | 1497 | if (verbose) { |
1495 | comm = trace_find_cmdline(entry->pid); | 1498 | comm = trace_find_cmdline(field->pid); |
1496 | trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]" | 1499 | trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]" |
1497 | " %ld.%03ldms (+%ld.%03ldms): ", | 1500 | " %ld.%03ldms (+%ld.%03ldms): ", |
1498 | comm, | 1501 | comm, |
1499 | entry->pid, cpu, entry->flags, | 1502 | field->pid, cpu, field->flags, |
1500 | entry->preempt_count, trace_idx, | 1503 | field->preempt_count, trace_idx, |
1501 | ns2usecs(entry->t), | 1504 | ns2usecs(field->t), |
1502 | abs_usecs/1000, | 1505 | abs_usecs/1000, |
1503 | abs_usecs % 1000, rel_usecs/1000, | 1506 | abs_usecs % 1000, rel_usecs/1000, |
1504 | rel_usecs % 1000); | 1507 | rel_usecs % 1000); |
@@ -1508,41 +1511,42 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) | |||
1508 | } | 1511 | } |
1509 | switch (entry->type) { | 1512 | switch (entry->type) { |
1510 | case TRACE_FN: | 1513 | case TRACE_FN: |
1511 | seq_print_ip_sym(s, entry->fn.ip, sym_flags); | 1514 | seq_print_ip_sym(s, field->fn.ip, sym_flags); |
1512 | trace_seq_puts(s, " ("); | 1515 | trace_seq_puts(s, " ("); |
1513 | if (kretprobed(entry->fn.parent_ip)) | 1516 | if (kretprobed(field->fn.parent_ip)) |
1514 | trace_seq_puts(s, KRETPROBE_MSG); | 1517 | trace_seq_puts(s, KRETPROBE_MSG); |
1515 | else | 1518 | else |
1516 | seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); | 1519 | seq_print_ip_sym(s, field->fn.parent_ip, sym_flags); |
1517 | trace_seq_puts(s, ")\n"); | 1520 | trace_seq_puts(s, ")\n"); |
1518 | break; | 1521 | break; |
1519 | case TRACE_CTX: | 1522 | case TRACE_CTX: |
1520 | case TRACE_WAKE: | 1523 | case TRACE_WAKE: |
1521 | T = entry->ctx.next_state < sizeof(state_to_char) ? | 1524 | T = field->ctx.next_state < sizeof(state_to_char) ? |
1522 | state_to_char[entry->ctx.next_state] : 'X'; | 1525 | state_to_char[field->ctx.next_state] : 'X'; |
1523 | 1526 | ||
1524 | state = entry->ctx.prev_state ? __ffs(entry->ctx.prev_state) + 1 : 0; | 1527 | state = field->ctx.prev_state ? |
1528 | __ffs(field->ctx.prev_state) + 1 : 0; | ||
1525 | S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X'; | 1529 | S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X'; |
1526 | comm = trace_find_cmdline(entry->ctx.next_pid); | 1530 | comm = trace_find_cmdline(field->ctx.next_pid); |
1527 | trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n", | 1531 | trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n", |
1528 | entry->ctx.prev_pid, | 1532 | field->ctx.prev_pid, |
1529 | entry->ctx.prev_prio, | 1533 | field->ctx.prev_prio, |
1530 | S, entry->type == TRACE_CTX ? "==>" : " +", | 1534 | S, entry->type == TRACE_CTX ? "==>" : " +", |
1531 | entry->ctx.next_pid, | 1535 | field->ctx.next_pid, |
1532 | entry->ctx.next_prio, | 1536 | field->ctx.next_prio, |
1533 | T, comm); | 1537 | T, comm); |
1534 | break; | 1538 | break; |
1535 | case TRACE_SPECIAL: | 1539 | case TRACE_SPECIAL: |
1536 | trace_seq_printf(s, "# %ld %ld %ld\n", | 1540 | trace_seq_printf(s, "# %ld %ld %ld\n", |
1537 | entry->special.arg1, | 1541 | field->special.arg1, |
1538 | entry->special.arg2, | 1542 | field->special.arg2, |
1539 | entry->special.arg3); | 1543 | field->special.arg3); |
1540 | break; | 1544 | break; |
1541 | case TRACE_STACK: | 1545 | case TRACE_STACK: |
1542 | for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { | 1546 | for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { |
1543 | if (i) | 1547 | if (i) |
1544 | trace_seq_puts(s, " <= "); | 1548 | trace_seq_puts(s, " <= "); |
1545 | seq_print_ip_sym(s, entry->stack.caller[i], sym_flags); | 1549 | seq_print_ip_sym(s, field->stack.caller[i], sym_flags); |
1546 | } | 1550 | } |
1547 | trace_seq_puts(s, "\n"); | 1551 | trace_seq_puts(s, "\n"); |
1548 | break; | 1552 | break; |
@@ -1557,6 +1561,7 @@ static int print_trace_fmt(struct trace_iterator *iter) | |||
1557 | struct trace_seq *s = &iter->seq; | 1561 | struct trace_seq *s = &iter->seq; |
1558 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); | 1562 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); |
1559 | struct trace_entry *entry; | 1563 | struct trace_entry *entry; |
1564 | struct trace_field *field; | ||
1560 | unsigned long usec_rem; | 1565 | unsigned long usec_rem; |
1561 | unsigned long long t; | 1566 | unsigned long long t; |
1562 | unsigned long secs; | 1567 | unsigned long secs; |
@@ -1566,14 +1571,15 @@ static int print_trace_fmt(struct trace_iterator *iter) | |||
1566 | int i; | 1571 | int i; |
1567 | 1572 | ||
1568 | entry = iter->ent; | 1573 | entry = iter->ent; |
1574 | field = &entry->field; | ||
1569 | 1575 | ||
1570 | comm = trace_find_cmdline(iter->ent->pid); | 1576 | comm = trace_find_cmdline(iter->ent->field.pid); |
1571 | 1577 | ||
1572 | t = ns2usecs(entry->t); | 1578 | t = ns2usecs(field->t); |
1573 | usec_rem = do_div(t, 1000000ULL); | 1579 | usec_rem = do_div(t, 1000000ULL); |
1574 | secs = (unsigned long)t; | 1580 | secs = (unsigned long)t; |
1575 | 1581 | ||
1576 | ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); | 1582 | ret = trace_seq_printf(s, "%16s-%-5d ", comm, field->pid); |
1577 | if (!ret) | 1583 | if (!ret) |
1578 | return 0; | 1584 | return 0; |
1579 | ret = trace_seq_printf(s, "[%02d] ", iter->cpu); | 1585 | ret = trace_seq_printf(s, "[%02d] ", iter->cpu); |
@@ -1585,18 +1591,19 @@ static int print_trace_fmt(struct trace_iterator *iter) | |||
1585 | 1591 | ||
1586 | switch (entry->type) { | 1592 | switch (entry->type) { |
1587 | case TRACE_FN: | 1593 | case TRACE_FN: |
1588 | ret = seq_print_ip_sym(s, entry->fn.ip, sym_flags); | 1594 | ret = seq_print_ip_sym(s, field->fn.ip, sym_flags); |
1589 | if (!ret) | 1595 | if (!ret) |
1590 | return 0; | 1596 | return 0; |
1591 | if ((sym_flags & TRACE_ITER_PRINT_PARENT) && | 1597 | if ((sym_flags & TRACE_ITER_PRINT_PARENT) && |
1592 | entry->fn.parent_ip) { | 1598 | field->fn.parent_ip) { |
1593 | ret = trace_seq_printf(s, " <-"); | 1599 | ret = trace_seq_printf(s, " <-"); |
1594 | if (!ret) | 1600 | if (!ret) |
1595 | return 0; | 1601 | return 0; |
1596 | if (kretprobed(entry->fn.parent_ip)) | 1602 | if (kretprobed(field->fn.parent_ip)) |
1597 | ret = trace_seq_puts(s, KRETPROBE_MSG); | 1603 | ret = trace_seq_puts(s, KRETPROBE_MSG); |
1598 | else | 1604 | else |
1599 | ret = seq_print_ip_sym(s, entry->fn.parent_ip, | 1605 | ret = seq_print_ip_sym(s, |
1606 | field->fn.parent_ip, | ||
1600 | sym_flags); | 1607 | sym_flags); |
1601 | if (!ret) | 1608 | if (!ret) |
1602 | return 0; | 1609 | return 0; |
@@ -1607,26 +1614,26 @@ static int print_trace_fmt(struct trace_iterator *iter) | |||
1607 | break; | 1614 | break; |
1608 | case TRACE_CTX: | 1615 | case TRACE_CTX: |
1609 | case TRACE_WAKE: | 1616 | case TRACE_WAKE: |
1610 | S = entry->ctx.prev_state < sizeof(state_to_char) ? | 1617 | S = field->ctx.prev_state < sizeof(state_to_char) ? |
1611 | state_to_char[entry->ctx.prev_state] : 'X'; | 1618 | state_to_char[field->ctx.prev_state] : 'X'; |
1612 | T = entry->ctx.next_state < sizeof(state_to_char) ? | 1619 | T = field->ctx.next_state < sizeof(state_to_char) ? |
1613 | state_to_char[entry->ctx.next_state] : 'X'; | 1620 | state_to_char[field->ctx.next_state] : 'X'; |
1614 | ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n", | 1621 | ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n", |
1615 | entry->ctx.prev_pid, | 1622 | field->ctx.prev_pid, |
1616 | entry->ctx.prev_prio, | 1623 | field->ctx.prev_prio, |
1617 | S, | 1624 | S, |
1618 | entry->type == TRACE_CTX ? "==>" : " +", | 1625 | entry->type == TRACE_CTX ? "==>" : " +", |
1619 | entry->ctx.next_pid, | 1626 | field->ctx.next_pid, |
1620 | entry->ctx.next_prio, | 1627 | field->ctx.next_prio, |
1621 | T); | 1628 | T); |
1622 | if (!ret) | 1629 | if (!ret) |
1623 | return 0; | 1630 | return 0; |
1624 | break; | 1631 | break; |
1625 | case TRACE_SPECIAL: | 1632 | case TRACE_SPECIAL: |
1626 | ret = trace_seq_printf(s, "# %ld %ld %ld\n", | 1633 | ret = trace_seq_printf(s, "# %ld %ld %ld\n", |
1627 | entry->special.arg1, | 1634 | field->special.arg1, |
1628 | entry->special.arg2, | 1635 | field->special.arg2, |
1629 | entry->special.arg3); | 1636 | field->special.arg3); |
1630 | if (!ret) | 1637 | if (!ret) |
1631 | return 0; | 1638 | return 0; |
1632 | break; | 1639 | break; |
@@ -1637,7 +1644,7 @@ static int print_trace_fmt(struct trace_iterator *iter) | |||
1637 | if (!ret) | 1644 | if (!ret) |
1638 | return 0; | 1645 | return 0; |
1639 | } | 1646 | } |
1640 | ret = seq_print_ip_sym(s, entry->stack.caller[i], | 1647 | ret = seq_print_ip_sym(s, field->stack.caller[i], |
1641 | sym_flags); | 1648 | sym_flags); |
1642 | if (!ret) | 1649 | if (!ret) |
1643 | return 0; | 1650 | return 0; |
@@ -1654,37 +1661,40 @@ static int print_raw_fmt(struct trace_iterator *iter) | |||
1654 | { | 1661 | { |
1655 | struct trace_seq *s = &iter->seq; | 1662 | struct trace_seq *s = &iter->seq; |
1656 | struct trace_entry *entry; | 1663 | struct trace_entry *entry; |
1664 | struct trace_field *field; | ||
1657 | int ret; | 1665 | int ret; |
1658 | int S, T; | 1666 | int S, T; |
1659 | 1667 | ||
1660 | entry = iter->ent; | 1668 | entry = iter->ent; |
1669 | field = &entry->field; | ||
1661 | 1670 | ||
1662 | ret = trace_seq_printf(s, "%d %d %llu ", | 1671 | ret = trace_seq_printf(s, "%d %d %llu ", |
1663 | entry->pid, iter->cpu, entry->t); | 1672 | field->pid, iter->cpu, field->t); |
1664 | if (!ret) | 1673 | if (!ret) |
1665 | return 0; | 1674 | return 0; |
1666 | 1675 | ||
1667 | switch (entry->type) { | 1676 | switch (entry->type) { |
1668 | case TRACE_FN: | 1677 | case TRACE_FN: |
1669 | ret = trace_seq_printf(s, "%x %x\n", | 1678 | ret = trace_seq_printf(s, "%x %x\n", |
1670 | entry->fn.ip, entry->fn.parent_ip); | 1679 | field->fn.ip, |
1680 | field->fn.parent_ip); | ||
1671 | if (!ret) | 1681 | if (!ret) |
1672 | return 0; | 1682 | return 0; |
1673 | break; | 1683 | break; |
1674 | case TRACE_CTX: | 1684 | case TRACE_CTX: |
1675 | case TRACE_WAKE: | 1685 | case TRACE_WAKE: |
1676 | S = entry->ctx.prev_state < sizeof(state_to_char) ? | 1686 | S = field->ctx.prev_state < sizeof(state_to_char) ? |
1677 | state_to_char[entry->ctx.prev_state] : 'X'; | 1687 | state_to_char[field->ctx.prev_state] : 'X'; |
1678 | T = entry->ctx.next_state < sizeof(state_to_char) ? | 1688 | T = field->ctx.next_state < sizeof(state_to_char) ? |
1679 | state_to_char[entry->ctx.next_state] : 'X'; | 1689 | state_to_char[field->ctx.next_state] : 'X'; |
1680 | if (entry->type == TRACE_WAKE) | 1690 | if (entry->type == TRACE_WAKE) |
1681 | S = '+'; | 1691 | S = '+'; |
1682 | ret = trace_seq_printf(s, "%d %d %c %d %d %c\n", | 1692 | ret = trace_seq_printf(s, "%d %d %c %d %d %c\n", |
1683 | entry->ctx.prev_pid, | 1693 | field->ctx.prev_pid, |
1684 | entry->ctx.prev_prio, | 1694 | field->ctx.prev_prio, |
1685 | S, | 1695 | S, |
1686 | entry->ctx.next_pid, | 1696 | field->ctx.next_pid, |
1687 | entry->ctx.next_prio, | 1697 | field->ctx.next_prio, |
1688 | T); | 1698 | T); |
1689 | if (!ret) | 1699 | if (!ret) |
1690 | return 0; | 1700 | return 0; |
@@ -1692,9 +1702,9 @@ static int print_raw_fmt(struct trace_iterator *iter) | |||
1692 | case TRACE_SPECIAL: | 1702 | case TRACE_SPECIAL: |
1693 | case TRACE_STACK: | 1703 | case TRACE_STACK: |
1694 | ret = trace_seq_printf(s, "# %ld %ld %ld\n", | 1704 | ret = trace_seq_printf(s, "# %ld %ld %ld\n", |
1695 | entry->special.arg1, | 1705 | field->special.arg1, |
1696 | entry->special.arg2, | 1706 | field->special.arg2, |
1697 | entry->special.arg3); | 1707 | field->special.arg3); |
1698 | if (!ret) | 1708 | if (!ret) |
1699 | return 0; | 1709 | return 0; |
1700 | break; | 1710 | break; |
@@ -1719,40 +1729,41 @@ static int print_hex_fmt(struct trace_iterator *iter) | |||
1719 | struct trace_seq *s = &iter->seq; | 1729 | struct trace_seq *s = &iter->seq; |
1720 | unsigned char newline = '\n'; | 1730 | unsigned char newline = '\n'; |
1721 | struct trace_entry *entry; | 1731 | struct trace_entry *entry; |
1732 | struct trace_field *field; | ||
1722 | int S, T; | 1733 | int S, T; |
1723 | 1734 | ||
1724 | entry = iter->ent; | 1735 | entry = iter->ent; |
1736 | field = &entry->field; | ||
1725 | 1737 | ||
1726 | SEQ_PUT_HEX_FIELD_RET(s, entry->pid); | 1738 | SEQ_PUT_HEX_FIELD_RET(s, field->pid); |
1727 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); | 1739 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); |
1728 | SEQ_PUT_HEX_FIELD_RET(s, entry->t); | 1740 | SEQ_PUT_HEX_FIELD_RET(s, field->t); |
1729 | 1741 | ||
1730 | switch (entry->type) { | 1742 | switch (entry->type) { |
1731 | case TRACE_FN: | 1743 | case TRACE_FN: |
1732 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.ip); | 1744 | SEQ_PUT_HEX_FIELD_RET(s, field->fn.ip); |
1733 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); | 1745 | SEQ_PUT_HEX_FIELD_RET(s, field->fn.parent_ip); |
1734 | break; | 1746 | break; |
1735 | case TRACE_CTX: | 1747 | case TRACE_CTX: |
1736 | case TRACE_WAKE: | 1748 | case TRACE_WAKE: |
1737 | S = entry->ctx.prev_state < sizeof(state_to_char) ? | 1749 | S = field->ctx.prev_state < sizeof(state_to_char) ? |
1738 | state_to_char[entry->ctx.prev_state] : 'X'; | 1750 | state_to_char[field->ctx.prev_state] : 'X'; |
1739 | T = entry->ctx.next_state < sizeof(state_to_char) ? | 1751 | T = field->ctx.next_state < sizeof(state_to_char) ? |
1740 | state_to_char[entry->ctx.next_state] : 'X'; | 1752 | state_to_char[field->ctx.next_state] : 'X'; |
1741 | if (entry->type == TRACE_WAKE) | 1753 | if (entry->type == TRACE_WAKE) |
1742 | S = '+'; | 1754 | S = '+'; |
1743 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); | 1755 | SEQ_PUT_HEX_FIELD_RET(s, field->ctx.prev_pid); |
1744 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio); | 1756 | SEQ_PUT_HEX_FIELD_RET(s, field->ctx.prev_prio); |
1745 | SEQ_PUT_HEX_FIELD_RET(s, S); | 1757 | SEQ_PUT_HEX_FIELD_RET(s, S); |
1746 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid); | 1758 | SEQ_PUT_HEX_FIELD_RET(s, field->ctx.next_pid); |
1747 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio); | 1759 | SEQ_PUT_HEX_FIELD_RET(s, field->ctx.next_prio); |
1748 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); | ||
1749 | SEQ_PUT_HEX_FIELD_RET(s, T); | 1760 | SEQ_PUT_HEX_FIELD_RET(s, T); |
1750 | break; | 1761 | break; |
1751 | case TRACE_SPECIAL: | 1762 | case TRACE_SPECIAL: |
1752 | case TRACE_STACK: | 1763 | case TRACE_STACK: |
1753 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1); | 1764 | SEQ_PUT_HEX_FIELD_RET(s, field->special.arg1); |
1754 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2); | 1765 | SEQ_PUT_HEX_FIELD_RET(s, field->special.arg2); |
1755 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3); | 1766 | SEQ_PUT_HEX_FIELD_RET(s, field->special.arg3); |
1756 | break; | 1767 | break; |
1757 | } | 1768 | } |
1758 | SEQ_PUT_FIELD_RET(s, newline); | 1769 | SEQ_PUT_FIELD_RET(s, newline); |
@@ -1764,31 +1775,33 @@ static int print_bin_fmt(struct trace_iterator *iter) | |||
1764 | { | 1775 | { |
1765 | struct trace_seq *s = &iter->seq; | 1776 | struct trace_seq *s = &iter->seq; |
1766 | struct trace_entry *entry; | 1777 | struct trace_entry *entry; |
1778 | struct trace_field *field; | ||
1767 | 1779 | ||
1768 | entry = iter->ent; | 1780 | entry = iter->ent; |
1781 | field = &entry->field; | ||
1769 | 1782 | ||
1770 | SEQ_PUT_FIELD_RET(s, entry->pid); | 1783 | SEQ_PUT_FIELD_RET(s, field->pid); |
1771 | SEQ_PUT_FIELD_RET(s, entry->cpu); | 1784 | SEQ_PUT_FIELD_RET(s, field->cpu); |
1772 | SEQ_PUT_FIELD_RET(s, entry->t); | 1785 | SEQ_PUT_FIELD_RET(s, field->t); |
1773 | 1786 | ||
1774 | switch (entry->type) { | 1787 | switch (entry->type) { |
1775 | case TRACE_FN: | 1788 | case TRACE_FN: |
1776 | SEQ_PUT_FIELD_RET(s, entry->fn.ip); | 1789 | SEQ_PUT_FIELD_RET(s, field->fn.ip); |
1777 | SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip); | 1790 | SEQ_PUT_FIELD_RET(s, field->fn.parent_ip); |
1778 | break; | 1791 | break; |
1779 | case TRACE_CTX: | 1792 | case TRACE_CTX: |
1780 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid); | 1793 | SEQ_PUT_FIELD_RET(s, field->ctx.prev_pid); |
1781 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio); | 1794 | SEQ_PUT_FIELD_RET(s, field->ctx.prev_prio); |
1782 | SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state); | 1795 | SEQ_PUT_FIELD_RET(s, field->ctx.prev_state); |
1783 | SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid); | 1796 | SEQ_PUT_FIELD_RET(s, field->ctx.next_pid); |
1784 | SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); | 1797 | SEQ_PUT_FIELD_RET(s, field->ctx.next_prio); |
1785 | SEQ_PUT_FIELD_RET(s, entry->ctx.next_state); | 1798 | SEQ_PUT_FIELD_RET(s, field->ctx.next_state); |
1786 | break; | 1799 | break; |
1787 | case TRACE_SPECIAL: | 1800 | case TRACE_SPECIAL: |
1788 | case TRACE_STACK: | 1801 | case TRACE_STACK: |
1789 | SEQ_PUT_FIELD_RET(s, entry->special.arg1); | 1802 | SEQ_PUT_FIELD_RET(s, field->special.arg1); |
1790 | SEQ_PUT_FIELD_RET(s, entry->special.arg2); | 1803 | SEQ_PUT_FIELD_RET(s, field->special.arg2); |
1791 | SEQ_PUT_FIELD_RET(s, entry->special.arg3); | 1804 | SEQ_PUT_FIELD_RET(s, field->special.arg3); |
1792 | break; | 1805 | break; |
1793 | } | 1806 | } |
1794 | return 1; | 1807 | return 1; |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f69f86788c2b..6ddd6a6556cf 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -61,13 +61,12 @@ struct stack_entry { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * The trace entry - the most basic unit of tracing. This is what | 64 | * The trace field - the most basic unit of tracing. This is what |
65 | * is printed in the end as a single line in the trace output, such as: | 65 | * is printed in the end as a single line in the trace output, such as: |
66 | * | 66 | * |
67 | * bash-15816 [01] 235.197585: idle_cpu <- irq_enter | 67 | * bash-15816 [01] 235.197585: idle_cpu <- irq_enter |
68 | */ | 68 | */ |
69 | struct trace_entry { | 69 | struct trace_field { |
70 | char type; | ||
71 | char cpu; | 70 | char cpu; |
72 | char flags; | 71 | char flags; |
73 | char preempt_count; | 72 | char preempt_count; |
@@ -83,6 +82,18 @@ struct trace_entry { | |||
83 | }; | 82 | }; |
84 | }; | 83 | }; |
85 | 84 | ||
85 | struct trace_field_cont { | ||
86 | char buf[sizeof(struct trace_field)]; | ||
87 | }; | ||
88 | |||
89 | struct trace_entry { | ||
90 | char type; | ||
91 | union { | ||
92 | struct trace_field field; | ||
93 | struct trace_field_cont cont; | ||
94 | }; | ||
95 | }; | ||
96 | |||
86 | #define TRACE_ENTRY_SIZE sizeof(struct trace_entry) | 97 | #define TRACE_ENTRY_SIZE sizeof(struct trace_entry) |
87 | 98 | ||
88 | /* | 99 | /* |
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index b13dc19dcbb4..9b7a936f4b1f 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c | |||
@@ -174,14 +174,14 @@ print_out: | |||
174 | static int mmio_print_rw(struct trace_iterator *iter) | 174 | static int mmio_print_rw(struct trace_iterator *iter) |
175 | { | 175 | { |
176 | struct trace_entry *entry = iter->ent; | 176 | struct trace_entry *entry = iter->ent; |
177 | struct mmiotrace_rw *rw = &entry->mmiorw; | 177 | struct mmiotrace_rw *rw = &entry->field.mmiorw; |
178 | struct trace_seq *s = &iter->seq; | 178 | struct trace_seq *s = &iter->seq; |
179 | unsigned long long t = ns2usecs(entry->t); | 179 | unsigned long long t = ns2usecs(entry->field.t); |
180 | unsigned long usec_rem = do_div(t, 1000000ULL); | 180 | unsigned long usec_rem = do_div(t, 1000000ULL); |
181 | unsigned secs = (unsigned long)t; | 181 | unsigned secs = (unsigned long)t; |
182 | int ret = 1; | 182 | int ret = 1; |
183 | 183 | ||
184 | switch (entry->mmiorw.opcode) { | 184 | switch (entry->field.mmiorw.opcode) { |
185 | case MMIO_READ: | 185 | case MMIO_READ: |
186 | ret = trace_seq_printf(s, | 186 | ret = trace_seq_printf(s, |
187 | "R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", | 187 | "R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", |
@@ -216,14 +216,14 @@ static int mmio_print_rw(struct trace_iterator *iter) | |||
216 | static int mmio_print_map(struct trace_iterator *iter) | 216 | static int mmio_print_map(struct trace_iterator *iter) |
217 | { | 217 | { |
218 | struct trace_entry *entry = iter->ent; | 218 | struct trace_entry *entry = iter->ent; |
219 | struct mmiotrace_map *m = &entry->mmiomap; | 219 | struct mmiotrace_map *m = &entry->field.mmiomap; |
220 | struct trace_seq *s = &iter->seq; | 220 | struct trace_seq *s = &iter->seq; |
221 | unsigned long long t = ns2usecs(entry->t); | 221 | unsigned long long t = ns2usecs(entry->field.t); |
222 | unsigned long usec_rem = do_div(t, 1000000ULL); | 222 | unsigned long usec_rem = do_div(t, 1000000ULL); |
223 | unsigned secs = (unsigned long)t; | 223 | unsigned secs = (unsigned long)t; |
224 | int ret = 1; | 224 | int ret = 1; |
225 | 225 | ||
226 | switch (entry->mmiorw.opcode) { | 226 | switch (entry->field.mmiorw.opcode) { |
227 | case MMIO_PROBE: | 227 | case MMIO_PROBE: |
228 | ret = trace_seq_printf(s, | 228 | ret = trace_seq_printf(s, |
229 | "MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", | 229 | "MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", |