static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; switch (entry->type) { case TRACE_KMEM_ALLOC: { struct kmemtrace_alloc_entry *field; trace_assign_type(field, entry); if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL) return kmemtrace_print_alloc_compress(iter, field); else return kmemtrace_print_alloc_user(iter, field); } case TRACE_KMEM_FREE: { struct kmemtrace_free_entry *field; trace_assign_type(field, entry); if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL) return kmemtrace_print_free_compress(iter, field); else return kmemtrace_print_free_user(iter, field); } default: return TRACE_TYPE_UNHANDLED; } }
static enum print_line_t power_print_line(struct trace_iterator *iter) { int ret = 0; struct trace_entry *entry = iter->ent; struct trace_power *field ; struct power_trace *it; struct trace_seq *s = &iter->seq; struct timespec stamp; struct timespec duration; trace_assign_type(field, entry); it = &field->state_data; stamp = ktime_to_timespec(it->stamp); duration = ktime_to_timespec(ktime_sub(it->end, it->stamp)); if (entry->type == TRACE_POWER) { if (it->type == POWER_CSTATE) ret = trace_seq_printf(s, "[%5ld.%09ld] CSTATE: Going to C%i on cpu %i for %ld.%09ld\n", stamp.tv_sec, stamp.tv_nsec, it->state, iter->cpu, duration.tv_sec, duration.tv_nsec); if (it->type == POWER_PSTATE) ret = trace_seq_printf(s, "[%5ld.%09ld] PSTATE: Going to P%i on cpu %i\n", stamp.tv_sec, stamp.tv_nsec, it->state, iter->cpu); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; } return TRACE_TYPE_UNHANDLED; }
static enum print_line_t kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags, struct trace_event *event) { struct trace_seq *s = &iter->seq; struct kmemtrace_alloc_entry *entry; struct kmemtrace_user_event *ev; struct kmemtrace_user_event_alloc *ev_alloc; trace_assign_type(entry, iter->ent); ev = trace_seq_reserve(s, sizeof(*ev)); if (!ev) return TRACE_TYPE_PARTIAL_LINE; ev->event_id = KMEMTRACE_USER_ALLOC; ev->type_id = entry->type_id; ev->event_size = sizeof(*ev) + sizeof(*ev_alloc); ev->cpu = iter->cpu; ev->timestamp = iter->ts; ev->call_site = entry->call_site; ev->ptr = (unsigned long)entry->ptr; ev_alloc = trace_seq_reserve(s, sizeof(*ev_alloc)); if (!ev_alloc) return TRACE_TYPE_PARTIAL_LINE; ev_alloc->bytes_req = entry->bytes_req; ev_alloc->bytes_alloc = entry->bytes_alloc; ev_alloc->gfp_flags = entry->gfp_flags; ev_alloc->node = entry->node; return TRACE_TYPE_HANDLED; }
static enum print_line_t kmemtrace_print_alloc_compress(struct trace_iterator *iter) { struct kmemtrace_alloc_entry *entry; struct trace_seq *s = &iter->seq; int ret; trace_assign_type(entry, iter->ent); ret = trace_seq_printf(s, " + "); if (!ret) return TRACE_TYPE_PARTIAL_LINE; switch (entry->type_id) { case KMEMTRACE_TYPE_KMALLOC: ret = trace_seq_printf(s, "K "); break; case KMEMTRACE_TYPE_CACHE: ret = trace_seq_printf(s, "C "); break; case KMEMTRACE_TYPE_PAGES: ret = trace_seq_printf(s, "P "); break; default: ret = trace_seq_printf(s, "? "); } if (!ret) return TRACE_TYPE_PARTIAL_LINE; ret = trace_seq_printf(s, "%4zu ", entry->bytes_req); if (!ret) return TRACE_TYPE_PARTIAL_LINE; ret = trace_seq_printf(s, "%4zu ", entry->bytes_alloc); if (!ret) return TRACE_TYPE_PARTIAL_LINE; ret = trace_seq_printf(s, "%08x ", entry->gfp_flags); if (!ret) return TRACE_TYPE_PARTIAL_LINE; ret = trace_seq_printf(s, "0x%tx ", (ptrdiff_t)entry->ptr); if (!ret) return TRACE_TYPE_PARTIAL_LINE; ret = trace_seq_printf(s, "%4d %pf\n", entry->node, (void *)entry->call_site); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }
static enum print_line_t initcall_ret_print_line(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; struct trace_seq *s = &iter->seq; struct trace_boot_ret *field; struct boot_trace_ret *init_ret; u64 ts; unsigned long nsec_rem; int ret; trace_assign_type(field, entry); init_ret = &field->boot_ret; ts = iter->ts; nsec_rem = do_div(ts, NSEC_PER_SEC); ret = trace_seq_printf(s, "[%5ld.%09ld] initcall %s " "returned %d after %llu msecs\n", (unsigned long) ts, nsec_rem, init_ret->func, init_ret->result, init_ret->duration); if (!ret) return TRACE_TYPE_PARTIAL_LINE; else return TRACE_TYPE_HANDLED; }
static enum print_line_t kmemtrace_print_free_compress(struct trace_iterator *iter) { struct kmemtrace_free_entry *entry; struct trace_seq *s = &iter->seq; int ret; trace_assign_type(entry, iter->ent); /* Free entry */ ret = trace_seq_printf(s, " - "); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Type */ switch (entry->type_id) { case KMEMTRACE_TYPE_KMALLOC: ret = trace_seq_printf(s, "K "); break; case KMEMTRACE_TYPE_CACHE: ret = trace_seq_printf(s, "C "); break; case KMEMTRACE_TYPE_PAGES: ret = trace_seq_printf(s, "P "); break; default: ret = trace_seq_printf(s, "? "); } if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Skip requested/allocated/flags */ ret = trace_seq_printf(s, " "); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Pointer to allocated */ ret = trace_seq_printf(s, "0x%tx ", (ptrdiff_t)entry->ptr); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Skip node and print call site*/ ret = trace_seq_printf(s, " %pf\n", (void *)entry->call_site); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }
static enum print_line_t trace_branch_print(struct trace_iterator *iter, int flags, struct trace_event *event) { struct trace_branch *field; trace_assign_type(field, iter->ent); trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n", field->correct ? " ok " : " MISS ", field->func, field->file, field->line); return trace_handle_return(&iter->seq); }
static enum print_line_t trace_branch_print(struct trace_iterator *iter, int flags, struct trace_event *event) { struct trace_branch *field; trace_assign_type(field, iter->ent); if (trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n", field->correct ? " ok " : " MISS ", field->func, field->file, field->line)) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }
static enum print_line_t kmemtrace_print_free(struct trace_iterator *iter, int flags) { struct trace_seq *s = &iter->seq; struct kmemtrace_free_entry *entry; int ret; trace_assign_type(entry, iter->ent); ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu\n", entry->type_id, (void *)entry->call_site, (unsigned long)entry->ptr); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }
static enum print_line_t kmemtrace_print_alloc(struct trace_iterator *iter, int flags) { struct trace_seq *s = &iter->seq; struct kmemtrace_alloc_entry *entry; int ret; trace_assign_type(entry, iter->ent); ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu " "bytes_req %lu bytes_alloc %lu gfp_flags %lu node %d\n", entry->type_id, (void *)entry->call_site, (unsigned long)entry->ptr, (unsigned long)entry->bytes_req, (unsigned long)entry->bytes_alloc, (unsigned long)entry->gfp_flags, entry->node); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }
static enum print_line_t bts_trace_print_line(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; struct trace_seq *seq = &iter->seq; struct hw_branch_entry *it; unsigned long symflags = TRACE_ITER_SYM_OFFSET; trace_assign_type(it, entry); if (entry->type == TRACE_HW_BRANCHES) { if (trace_seq_printf(seq, "%4d ", iter->cpu) && seq_print_ip_sym(seq, it->to, symflags) && trace_seq_printf(seq, "\t <- ") && seq_print_ip_sym(seq, it->from, symflags) && trace_seq_printf(seq, "\n")) return TRACE_TYPE_HANDLED; return TRACE_TYPE_PARTIAL_LINE;; } return TRACE_TYPE_UNHANDLED; }
static enum print_line_t bts_trace_print_line(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; struct trace_seq *seq = &iter->seq; struct hw_branch_entry *it; trace_assign_type(it, entry); if (entry->type == TRACE_HW_BRANCHES) { if (trace_seq_printf(seq, "%4d ", entry->cpu) && trace_seq_printf(seq, "0x%016llx -> 0x%016llx ", it->from, it->to) && (!it->from || seq_print_ip_sym(seq, it->from, /* sym_flags = */ 0)) && trace_seq_printf(seq, "\n")) return TRACE_TYPE_HANDLED; return TRACE_TYPE_PARTIAL_LINE;; } return TRACE_TYPE_UNHANDLED; }
static enum print_line_t kmemtrace_print_free_user(struct trace_iterator *iter, int flags) { struct trace_seq *s = &iter->seq; struct kmemtrace_free_entry *entry; struct kmemtrace_user_event *ev; trace_assign_type(entry, iter->ent); ev = trace_seq_reserve(s, sizeof(*ev)); if (!ev) return TRACE_TYPE_PARTIAL_LINE; ev->event_id = KMEMTRACE_USER_FREE; ev->type_id = entry->type_id; ev->event_size = sizeof(*ev); ev->cpu = iter->cpu; ev->timestamp = iter->ts; ev->call_site = entry->call_site; ev->ptr = (unsigned long)entry->ptr; return TRACE_TYPE_HANDLED; }
static enum print_line_t initcall_call_print_line(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; struct trace_seq *s = &iter->seq; struct trace_boot_call *field; struct boot_trace_call *call; u64 ts; unsigned long nsec_rem; int ret; trace_assign_type(field, entry); call = &field->boot_call; ts = iter->ts; nsec_rem = do_div(ts, NSEC_PER_SEC); ret = trace_seq_printf(s, "[%5ld.%09ld] calling %s @ %i\n", (unsigned long)ts, nsec_rem, call->func, call->caller); if (!ret) return TRACE_TYPE_PARTIAL_LINE; else return TRACE_TYPE_HANDLED; }
/* The two other following provide a more minimalistic output */ static enum print_line_t kmemtrace_print_alloc_compress(struct trace_iterator *iter) { struct kmemtrace_alloc_entry *entry; struct trace_seq *s = &iter->seq; int ret; trace_assign_type(entry, iter->ent); /* Alloc entry */ ret = trace_seq_printf(s, " + "); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Type */ switch (entry->type_id) { case KMEMTRACE_TYPE_KMALLOC: ret = trace_seq_printf(s, "K "); break; case KMEMTRACE_TYPE_CACHE: ret = trace_seq_printf(s, "C "); break; case KMEMTRACE_TYPE_PAGES: ret = trace_seq_printf(s, "P "); break; default: ret = trace_seq_printf(s, "? "); } if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Requested */ ret = trace_seq_printf(s, "%4zu ", entry->bytes_req); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Allocated */ ret = trace_seq_printf(s, "%4zu ", entry->bytes_alloc); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Flags * TODO: would be better to see the name of the GFP flag names */ ret = trace_seq_printf(s, "%08x ", entry->gfp_flags); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Pointer to allocated */ ret = trace_seq_printf(s, "0x%tx ", (ptrdiff_t)entry->ptr); if (!ret) return TRACE_TYPE_PARTIAL_LINE; /* Node and call site*/ ret = trace_seq_printf(s, "%4d %pf\n", entry->node, (void *)entry->call_site); if (!ret) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; }