aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-03-12 13:24:49 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-12 21:15:00 -0400
commit48ead02030f849d011259244bb4ea9b985479006 (patch)
tree4500f27dc7eb6567ca79dd03fa94fe9e56fbc316 /kernel/trace/trace.c
parentdb526ca329f855510e8ce672332eba3304aed590 (diff)
tracing/core: bring back raw trace_printk for dynamic formats strings
Impact: fix callsites with dynamic format strings Since its new binary implementation, trace_printk() internally uses static containers for the format strings on each callsites. But the value is assigned once at build time, which means that it can't take dynamic formats. So this patch unearthes the raw trace_printk implementation for the callers that will need trace_printk to be able to carry these dynamic format strings. The trace_printk() macro will use the appropriate implementation for each callsite. Most of the time however, the binary implementation will still be used. The other impact of this patch is that mmiotrace_printk() will use the old implementation because it calls the low level trace_vprintk and we can't guess here whether the format passed in it is dynamic or not. Some parts of this patch have been written by Steven Rostedt (most notably the part that chooses the appropriate implementation for each callsites). Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c85
1 files changed, 80 insertions, 5 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 62a63b2b33dd..dbb077d8a172 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1179,10 +1179,10 @@ void trace_graph_return(struct ftrace_graph_ret *trace)
1179 1179
1180 1180
1181/** 1181/**
1182 * trace_vprintk - write binary msg to tracing buffer 1182 * trace_vbprintk - write binary msg to tracing buffer
1183 * 1183 *
1184 */ 1184 */
1185int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) 1185int trace_vbprintk(unsigned long ip, int depth, const char *fmt, va_list args)
1186{ 1186{
1187 static raw_spinlock_t trace_buf_lock = 1187 static raw_spinlock_t trace_buf_lock =
1188 (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; 1188 (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
@@ -1191,7 +1191,7 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
1191 struct ring_buffer_event *event; 1191 struct ring_buffer_event *event;
1192 struct trace_array *tr = &global_trace; 1192 struct trace_array *tr = &global_trace;
1193 struct trace_array_cpu *data; 1193 struct trace_array_cpu *data;
1194 struct print_entry *entry; 1194 struct bprint_entry *entry;
1195 unsigned long flags; 1195 unsigned long flags;
1196 int resched; 1196 int resched;
1197 int cpu, len = 0, size, pc; 1197 int cpu, len = 0, size, pc;
@@ -1219,7 +1219,7 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
1219 goto out_unlock; 1219 goto out_unlock;
1220 1220
1221 size = sizeof(*entry) + sizeof(u32) * len; 1221 size = sizeof(*entry) + sizeof(u32) * len;
1222 event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, flags, pc); 1222 event = trace_buffer_lock_reserve(tr, TRACE_BPRINT, size, flags, pc);
1223 if (!event) 1223 if (!event)
1224 goto out_unlock; 1224 goto out_unlock;
1225 entry = ring_buffer_event_data(event); 1225 entry = ring_buffer_event_data(event);
@@ -1240,6 +1240,60 @@ out:
1240 1240
1241 return len; 1241 return len;
1242} 1242}
1243EXPORT_SYMBOL_GPL(trace_vbprintk);
1244
1245int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
1246{
1247 static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED;
1248 static char trace_buf[TRACE_BUF_SIZE];
1249
1250 struct ring_buffer_event *event;
1251 struct trace_array *tr = &global_trace;
1252 struct trace_array_cpu *data;
1253 int cpu, len = 0, size, pc;
1254 struct print_entry *entry;
1255 unsigned long irq_flags;
1256
1257 if (tracing_disabled || tracing_selftest_running)
1258 return 0;
1259
1260 pc = preempt_count();
1261 preempt_disable_notrace();
1262 cpu = raw_smp_processor_id();
1263 data = tr->data[cpu];
1264
1265 if (unlikely(atomic_read(&data->disabled)))
1266 goto out;
1267
1268 pause_graph_tracing();
1269 raw_local_irq_save(irq_flags);
1270 __raw_spin_lock(&trace_buf_lock);
1271 len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
1272
1273 len = min(len, TRACE_BUF_SIZE-1);
1274 trace_buf[len] = 0;
1275
1276 size = sizeof(*entry) + len + 1;
1277 event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc);
1278 if (!event)
1279 goto out_unlock;
1280 entry = ring_buffer_event_data(event);
1281 entry->ip = ip;
1282 entry->depth = depth;
1283
1284 memcpy(&entry->buf, trace_buf, len);
1285 entry->buf[len] = 0;
1286 ring_buffer_unlock_commit(tr->buffer, event);
1287
1288 out_unlock:
1289 __raw_spin_unlock(&trace_buf_lock);
1290 raw_local_irq_restore(irq_flags);
1291 unpause_graph_tracing();
1292 out:
1293 preempt_enable_notrace();
1294
1295 return len;
1296}
1243EXPORT_SYMBOL_GPL(trace_vprintk); 1297EXPORT_SYMBOL_GPL(trace_vprintk);
1244 1298
1245enum trace_file_type { 1299enum trace_file_type {
@@ -1628,6 +1682,22 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter)
1628 return TRACE_TYPE_HANDLED; 1682 return TRACE_TYPE_HANDLED;
1629} 1683}
1630 1684
1685static enum print_line_t print_bprintk_msg_only(struct trace_iterator *iter)
1686{
1687 struct trace_seq *s = &iter->seq;
1688 struct trace_entry *entry = iter->ent;
1689 struct bprint_entry *field;
1690 int ret;
1691
1692 trace_assign_type(field, entry);
1693
1694 ret = trace_seq_bprintf(s, field->fmt, field->buf);
1695 if (!ret)
1696 return TRACE_TYPE_PARTIAL_LINE;
1697
1698 return TRACE_TYPE_HANDLED;
1699}
1700
1631static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) 1701static enum print_line_t print_printk_msg_only(struct trace_iterator *iter)
1632{ 1702{
1633 struct trace_seq *s = &iter->seq; 1703 struct trace_seq *s = &iter->seq;
@@ -1637,7 +1707,7 @@ static enum print_line_t print_printk_msg_only(struct trace_iterator *iter)
1637 1707
1638 trace_assign_type(field, entry); 1708 trace_assign_type(field, entry);
1639 1709
1640 ret = trace_seq_bprintf(s, field->fmt, field->buf); 1710 ret = trace_seq_printf(s, "%s", field->buf);
1641 if (!ret) 1711 if (!ret)
1642 return TRACE_TYPE_PARTIAL_LINE; 1712 return TRACE_TYPE_PARTIAL_LINE;
1643 1713
@@ -1702,6 +1772,11 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
1702 return ret; 1772 return ret;
1703 } 1773 }
1704 1774
1775 if (iter->ent->type == TRACE_BPRINT &&
1776 trace_flags & TRACE_ITER_PRINTK &&
1777 trace_flags & TRACE_ITER_PRINTK_MSGONLY)
1778 return print_bprintk_msg_only(iter);
1779
1705 if (iter->ent->type == TRACE_PRINT && 1780 if (iter->ent->type == TRACE_PRINT &&
1706 trace_flags & TRACE_ITER_PRINTK && 1781 trace_flags & TRACE_ITER_PRINTK &&
1707 trace_flags & TRACE_ITER_PRINTK_MSGONLY) 1782 trace_flags & TRACE_ITER_PRINTK_MSGONLY)