diff options
| -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", |
