Commit ddc1637a authored by Li Zefan's avatar Li Zefan Committed by Ingo Molnar

kmemtrace: Print binary output only if 'bin' option is set

Currently by default the output of kmemtrace is binary format instead
of human-readable output.

This patch makes the following changes:

  - We'll see human-readable output by default
  - We'll see binary output if 'bin' option is set

Note: you may probably need to explicitly disable context-info binary
      output:

	# echo 0 > options/context-info
	# echo 1 > options/bin
	# cat trace_pipe

v2:
- use %pF to print call_site
Signed-off-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
Acked-by: default avatarPekka Enberg <penberg@cs.helsinki.fi>
Acked-by: default avatarEduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A4DD0A0.5060500@cn.fujitsu.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 020e5f85
...@@ -239,12 +239,52 @@ struct kmemtrace_user_event_alloc { ...@@ -239,12 +239,52 @@ struct kmemtrace_user_event_alloc {
}; };
static enum print_line_t static enum print_line_t
kmemtrace_print_alloc_user(struct trace_iterator *iter, kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags)
struct kmemtrace_alloc_entry *entry) {
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
kmemtrace_print_free_user(struct trace_iterator *iter, int flags)
{ {
struct kmemtrace_user_event_alloc *ev_alloc;
struct trace_seq *s = &iter->seq; 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_user_bin(struct trace_iterator *iter, int flags)
{
struct trace_seq *s = &iter->seq;
struct kmemtrace_alloc_entry *entry;
struct kmemtrace_user_event *ev; 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)); ev = trace_seq_reserve(s, sizeof(*ev));
if (!ev) if (!ev)
...@@ -271,12 +311,14 @@ kmemtrace_print_alloc_user(struct trace_iterator *iter, ...@@ -271,12 +311,14 @@ kmemtrace_print_alloc_user(struct trace_iterator *iter,
} }
static enum print_line_t static enum print_line_t
kmemtrace_print_free_user(struct trace_iterator *iter, kmemtrace_print_free_user_bin(struct trace_iterator *iter, int flags)
struct kmemtrace_free_entry *entry)
{ {
struct trace_seq *s = &iter->seq; struct trace_seq *s = &iter->seq;
struct kmemtrace_free_entry *entry;
struct kmemtrace_user_event *ev; struct kmemtrace_user_event *ev;
trace_assign_type(entry, iter->ent);
ev = trace_seq_reserve(s, sizeof(*ev)); ev = trace_seq_reserve(s, sizeof(*ev));
if (!ev) if (!ev)
return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_PARTIAL_LINE;
...@@ -294,12 +336,14 @@ kmemtrace_print_free_user(struct trace_iterator *iter, ...@@ -294,12 +336,14 @@ kmemtrace_print_free_user(struct trace_iterator *iter,
/* The two other following provide a more minimalistic output */ /* The two other following provide a more minimalistic output */
static enum print_line_t static enum print_line_t
kmemtrace_print_alloc_compress(struct trace_iterator *iter, kmemtrace_print_alloc_compress(struct trace_iterator *iter)
struct kmemtrace_alloc_entry *entry)
{ {
struct kmemtrace_alloc_entry *entry;
struct trace_seq *s = &iter->seq; struct trace_seq *s = &iter->seq;
int ret; int ret;
trace_assign_type(entry, iter->ent);
/* Alloc entry */ /* Alloc entry */
ret = trace_seq_printf(s, " + "); ret = trace_seq_printf(s, " + ");
if (!ret) if (!ret)
...@@ -362,12 +406,14 @@ kmemtrace_print_alloc_compress(struct trace_iterator *iter, ...@@ -362,12 +406,14 @@ kmemtrace_print_alloc_compress(struct trace_iterator *iter,
} }
static enum print_line_t static enum print_line_t
kmemtrace_print_free_compress(struct trace_iterator *iter, kmemtrace_print_free_compress(struct trace_iterator *iter)
struct kmemtrace_free_entry *entry)
{ {
struct kmemtrace_free_entry *entry;
struct trace_seq *s = &iter->seq; struct trace_seq *s = &iter->seq;
int ret; int ret;
trace_assign_type(entry, iter->ent);
/* Free entry */ /* Free entry */
ret = trace_seq_printf(s, " - "); ret = trace_seq_printf(s, " - ");
if (!ret) if (!ret)
...@@ -421,32 +467,31 @@ static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter) ...@@ -421,32 +467,31 @@ static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter)
{ {
struct trace_entry *entry = iter->ent; struct trace_entry *entry = iter->ent;
switch (entry->type) { if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL))
case TRACE_KMEM_ALLOC: { return TRACE_TYPE_UNHANDLED;
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);
}
switch (entry->type) {
case TRACE_KMEM_ALLOC:
return kmemtrace_print_alloc_compress(iter);
case TRACE_KMEM_FREE:
return kmemtrace_print_free_compress(iter);
default: default:
return TRACE_TYPE_UNHANDLED; return TRACE_TYPE_UNHANDLED;
} }
} }
static struct trace_event kmem_trace_alloc = {
.type = TRACE_KMEM_ALLOC,
.trace = kmemtrace_print_alloc_user,
.binary = kmemtrace_print_alloc_user_bin,
};
static struct trace_event kmem_trace_free = {
.type = TRACE_KMEM_FREE,
.trace = kmemtrace_print_free_user,
.binary = kmemtrace_print_free_user_bin,
};
static struct tracer kmem_tracer __read_mostly = { static struct tracer kmem_tracer __read_mostly = {
.name = "kmemtrace", .name = "kmemtrace",
.init = kmem_trace_init, .init = kmem_trace_init,
...@@ -463,6 +508,21 @@ void kmemtrace_init(void) ...@@ -463,6 +508,21 @@ void kmemtrace_init(void)
static int __init init_kmem_tracer(void) static int __init init_kmem_tracer(void)
{ {
return register_tracer(&kmem_tracer); if (!register_ftrace_event(&kmem_trace_alloc)) {
pr_warning("Warning: could not register kmem events\n");
return 1;
}
if (!register_ftrace_event(&kmem_trace_free)) {
pr_warning("Warning: could not register kmem events\n");
return 1;
}
if (!register_tracer(&kmem_tracer)) {
pr_warning("Warning: could not register the kmem tracer\n");
return 1;
}
return 0;
} }
device_initcall(init_kmem_tracer); device_initcall(init_kmem_tracer);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment