aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2008-09-16 15:02:27 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:37:14 -0400
commitfc5e27ae4b45a0619701a83f30d9b7fad7ed9400 (patch)
tree236b53e76430aae9f6b1abc37de9259ba95c38c6
parent9e57fb35d711331a9b1410c5c56ebeb3733428a0 (diff)
mmiotrace: handle TRACE_PRINT entries
Also make trace_seq_print_cont() non-static, and add a newline if the seq buffer can't hold all data. Signed-off-by: Pekka Paalanen <pq@iki.fi> Acked-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/trace/trace.c31
-rw-r--r--kernel/trace/trace.h19
-rw-r--r--kernel/trace/trace_mmiotrace.c23
3 files changed, 53 insertions, 20 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 406de9cf2820..7e7154f77009 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -200,23 +200,6 @@ unsigned long nsecs_to_usecs(unsigned long nsecs)
200} 200}
201 201
202/* 202/*
203 * trace_flag_type is an enumeration that holds different
204 * states when a trace occurs. These are:
205 * IRQS_OFF - interrupts were disabled
206 * NEED_RESCED - reschedule is requested
207 * HARDIRQ - inside an interrupt handler
208 * SOFTIRQ - inside a softirq handler
209 * CONT - multiple entries hold the trace item
210 */
211enum trace_flag_type {
212 TRACE_FLAG_IRQS_OFF = 0x01,
213 TRACE_FLAG_NEED_RESCHED = 0x02,
214 TRACE_FLAG_HARDIRQ = 0x04,
215 TRACE_FLAG_SOFTIRQ = 0x08,
216 TRACE_FLAG_CONT = 0x10,
217};
218
219/*
220 * TRACE_ITER_SYM_MASK masks the options in trace_flags that 203 * TRACE_ITER_SYM_MASK masks the options in trace_flags that
221 * control the output of kernel symbols. 204 * control the output of kernel symbols.
222 */ 205 */
@@ -1517,12 +1500,16 @@ lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
1517 1500
1518static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; 1501static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
1519 1502
1520static void 1503/*
1521trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter) 1504 * The message is supposed to contain an ending newline.
1505 * If the printing stops prematurely, try to add a newline of our own.
1506 */
1507void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
1522{ 1508{
1523 struct trace_array *tr = iter->tr; 1509 struct trace_array *tr = iter->tr;
1524 struct trace_array_cpu *data = tr->data[iter->cpu]; 1510 struct trace_array_cpu *data = tr->data[iter->cpu];
1525 struct trace_entry *ent; 1511 struct trace_entry *ent;
1512 bool ok = true;
1526 1513
1527 ent = trace_entry_idx(tr, data, iter, iter->cpu); 1514 ent = trace_entry_idx(tr, data, iter, iter->cpu);
1528 if (!ent || ent->type != TRACE_CONT) { 1515 if (!ent || ent->type != TRACE_CONT) {
@@ -1531,10 +1518,14 @@ trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
1531 } 1518 }
1532 1519
1533 do { 1520 do {
1534 trace_seq_printf(s, "%s", ent->cont.buf); 1521 if (ok)
1522 ok = (trace_seq_printf(s, "%s", ent->cont.buf) > 0);
1535 __trace_iterator_increment(iter, iter->cpu); 1523 __trace_iterator_increment(iter, iter->cpu);
1536 ent = trace_entry_idx(tr, data, iter, iter->cpu); 1524 ent = trace_entry_idx(tr, data, iter, iter->cpu);
1537 } while (ent && ent->type == TRACE_CONT); 1525 } while (ent && ent->type == TRACE_CONT);
1526
1527 if (!ok)
1528 trace_seq_putc(s, '\n');
1538} 1529}
1539 1530
1540static int 1531static int
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index be3b3cf95f4b..648433d18ccb 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -72,6 +72,23 @@ struct print_entry {
72}; 72};
73 73
74/* 74/*
75 * trace_flag_type is an enumeration that holds different
76 * states when a trace occurs. These are:
77 * IRQS_OFF - interrupts were disabled
78 * NEED_RESCED - reschedule is requested
79 * HARDIRQ - inside an interrupt handler
80 * SOFTIRQ - inside a softirq handler
81 * CONT - multiple entries hold the trace item
82 */
83enum trace_flag_type {
84 TRACE_FLAG_IRQS_OFF = 0x01,
85 TRACE_FLAG_NEED_RESCHED = 0x02,
86 TRACE_FLAG_HARDIRQ = 0x04,
87 TRACE_FLAG_SOFTIRQ = 0x08,
88 TRACE_FLAG_CONT = 0x10,
89};
90
91/*
75 * The trace field - the most basic unit of tracing. This is what 92 * The trace field - the most basic unit of tracing. This is what
76 * is printed in the end as a single line in the trace output, such as: 93 * is printed in the end as a single line in the trace output, such as:
77 * 94 *
@@ -330,6 +347,8 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace,
330 347
331extern void *head_page(struct trace_array_cpu *data); 348extern void *head_page(struct trace_array_cpu *data);
332extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); 349extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
350extern void trace_seq_print_cont(struct trace_seq *s,
351 struct trace_iterator *iter);
333extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, 352extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
334 size_t cnt); 353 size_t cnt);
335extern long ns2usecs(cycle_t nsec); 354extern long ns2usecs(cycle_t nsec);
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 767d1faf56e5..a108c326f36e 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -245,6 +245,27 @@ static int mmio_print_map(struct trace_iterator *iter)
245 return 0; 245 return 0;
246} 246}
247 247
248static int mmio_print_mark(struct trace_iterator *iter)
249{
250 struct trace_entry *entry = iter->ent;
251 const char *msg = entry->field.print.buf;
252 struct trace_seq *s = &iter->seq;
253 unsigned long long t = ns2usecs(entry->field.t);
254 unsigned long usec_rem = do_div(t, 1000000ULL);
255 unsigned secs = (unsigned long)t;
256 int ret;
257
258 /* The trailing newline must be in the message. */
259 ret = trace_seq_printf(s, "MARK %lu.%06lu %s", secs, usec_rem, msg);
260 if (!ret)
261 return 0;
262
263 if (entry->field.flags & TRACE_FLAG_CONT)
264 trace_seq_print_cont(s, iter);
265
266 return 1;
267}
268
248/* return 0 to abort printing without consuming current entry in pipe mode */ 269/* return 0 to abort printing without consuming current entry in pipe mode */
249static int mmio_print_line(struct trace_iterator *iter) 270static int mmio_print_line(struct trace_iterator *iter)
250{ 271{
@@ -253,6 +274,8 @@ static int mmio_print_line(struct trace_iterator *iter)
253 return mmio_print_rw(iter); 274 return mmio_print_rw(iter);
254 case TRACE_MMIO_MAP: 275 case TRACE_MMIO_MAP:
255 return mmio_print_map(iter); 276 return mmio_print_map(iter);
277 case TRACE_PRINT:
278 return mmio_print_mark(iter);
256 default: 279 default:
257 return 1; /* ignore unknown entries */ 280 return 1; /* ignore unknown entries */
258 } 281 }