aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-08-01 12:26:40 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:35:15 -0400
commit2e2ca155cd2213b4f398031180fb3d399d5b7db9 (patch)
tree027295832950e23ac4edc84e43550d02e9a1acc6 /kernel
parentfed1939c64d2288938fdc1c367d49082da65e195 (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.c267
-rw-r--r--kernel/trace/trace.h17
-rw-r--r--kernel/trace/trace_mmiotrace.c12
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)
1422static void 1423static void
1423lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) 1424lat_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 */
69struct trace_entry { 69struct 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
85struct trace_field_cont {
86 char buf[sizeof(struct trace_field)];
87};
88
89struct 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:
174static int mmio_print_rw(struct trace_iterator *iter) 174static 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)
216static int mmio_print_map(struct trace_iterator *iter) 216static 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",