diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 85 |
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 | */ |
| 1185 | int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | 1185 | int 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 | } |
| 1243 | EXPORT_SYMBOL_GPL(trace_vbprintk); | ||
| 1244 | |||
| 1245 | int 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 | } | ||
| 1243 | EXPORT_SYMBOL_GPL(trace_vprintk); | 1297 | EXPORT_SYMBOL_GPL(trace_vprintk); |
| 1244 | 1298 | ||
| 1245 | enum trace_file_type { | 1299 | enum 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 | ||
| 1685 | static 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 | |||
| 1631 | static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) | 1701 | static 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) |
