1f984b51eSPekka Paalanen /* 2f984b51eSPekka Paalanen * Memory mapped I/O tracing 3f984b51eSPekka Paalanen * 4f984b51eSPekka Paalanen * Copyright (C) 2008 Pekka Paalanen <pq@iki.fi> 5f984b51eSPekka Paalanen */ 6f984b51eSPekka Paalanen 7f984b51eSPekka Paalanen #define DEBUG 1 8f984b51eSPekka Paalanen 9f984b51eSPekka Paalanen #include <linux/kernel.h> 10f984b51eSPekka Paalanen #include <linux/mmiotrace.h> 1113829537SPekka Paalanen #include <linux/pci.h> 125a0e3ad6STejun Heo #include <linux/slab.h> 13a5dec557SLi Zefan #include <linux/time.h> 14a5dec557SLi Zefan 1560063497SArun Sharma #include <linux/atomic.h> 16f984b51eSPekka Paalanen 17f984b51eSPekka Paalanen #include "trace.h" 18f0868d1eSSteven Rostedt #include "trace_output.h" 19f984b51eSPekka Paalanen 20d0a7e8caSPekka Paalanen struct header_iter { 21d0a7e8caSPekka Paalanen struct pci_dev *dev; 22d0a7e8caSPekka Paalanen }; 23d0a7e8caSPekka Paalanen 24f984b51eSPekka Paalanen static struct trace_array *mmio_trace_array; 252039238bSPekka Paalanen static bool overrun_detected; 267ee1768dSPekka Paalanen static unsigned long prev_overruns; 27173ed24eSPekka Paalanen static atomic_t dropped_count; 28f984b51eSPekka Paalanen 29bd8ac686SPekka Paalanen static void mmio_reset_data(struct trace_array *tr) 30bd8ac686SPekka Paalanen { 312039238bSPekka Paalanen overrun_detected = false; 327ee1768dSPekka Paalanen prev_overruns = 0; 33bd8ac686SPekka Paalanen 3412883efbSSteven Rostedt (Red Hat) tracing_reset_online_cpus(&tr->trace_buffer); 35bd8ac686SPekka Paalanen } 36f984b51eSPekka Paalanen 371c80025aSFrederic Weisbecker static int mmio_trace_init(struct trace_array *tr) 38f984b51eSPekka Paalanen { 39f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 40f984b51eSPekka Paalanen mmio_trace_array = tr; 41c76f0694SSteven Rostedt 42bd8ac686SPekka Paalanen mmio_reset_data(tr); 43f984b51eSPekka Paalanen enable_mmiotrace(); 441c80025aSFrederic Weisbecker return 0; 45f984b51eSPekka Paalanen } 46f984b51eSPekka Paalanen 47f984b51eSPekka Paalanen static void mmio_trace_reset(struct trace_array *tr) 48f984b51eSPekka Paalanen { 49f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 50c76f0694SSteven Rostedt 51f984b51eSPekka Paalanen disable_mmiotrace(); 52bd8ac686SPekka Paalanen mmio_reset_data(tr); 53bd8ac686SPekka Paalanen mmio_trace_array = NULL; 54f984b51eSPekka Paalanen } 55f984b51eSPekka Paalanen 56bbf5b1a0SSteven Rostedt static void mmio_trace_start(struct trace_array *tr) 57f984b51eSPekka Paalanen { 58f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 59bd8ac686SPekka Paalanen mmio_reset_data(tr); 60bd8ac686SPekka Paalanen } 61bd8ac686SPekka Paalanen 62a72e10afSSteven Rostedt (Red Hat) static void mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) 6313829537SPekka Paalanen { 6413829537SPekka Paalanen int i; 6513829537SPekka Paalanen resource_size_t start, end; 6613829537SPekka Paalanen const struct pci_driver *drv = pci_dev_driver(dev); 6713829537SPekka Paalanen 68a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", 6913829537SPekka Paalanen dev->bus->number, dev->devfn, 7013829537SPekka Paalanen dev->vendor, dev->device, dev->irq); 7113829537SPekka Paalanen for (i = 0; i < 7; i++) { 729a51933eSBjorn Helgaas start = dev->resource[i].start; 73a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, " %llx", 7413829537SPekka Paalanen (unsigned long long)(start | 7513829537SPekka Paalanen (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); 7613829537SPekka Paalanen } 7713829537SPekka Paalanen for (i = 0; i < 7; i++) { 789a51933eSBjorn Helgaas start = dev->resource[i].start; 799a51933eSBjorn Helgaas end = dev->resource[i].end; 80a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, " %llx", 8113829537SPekka Paalanen dev->resource[i].start < dev->resource[i].end ? 8213829537SPekka Paalanen (unsigned long long)(end - start) + 1 : 0); 8313829537SPekka Paalanen } 8413829537SPekka Paalanen if (drv) 85a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, " %s\n", drv->name); 8613829537SPekka Paalanen else 87a72e10afSSteven Rostedt (Red Hat) trace_seq_puts(s, " \n"); 8813829537SPekka Paalanen } 8913829537SPekka Paalanen 90d0a7e8caSPekka Paalanen static void destroy_header_iter(struct header_iter *hiter) 91bd8ac686SPekka Paalanen { 92d0a7e8caSPekka Paalanen if (!hiter) 93d0a7e8caSPekka Paalanen return; 94d0a7e8caSPekka Paalanen pci_dev_put(hiter->dev); 95d0a7e8caSPekka Paalanen kfree(hiter); 96d0a7e8caSPekka Paalanen } 97d0a7e8caSPekka Paalanen 98d0a7e8caSPekka Paalanen static void mmio_pipe_open(struct trace_iterator *iter) 99d0a7e8caSPekka Paalanen { 100d0a7e8caSPekka Paalanen struct header_iter *hiter; 101bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 10213829537SPekka Paalanen 103146c3442Szhangwei(Jovi) trace_seq_puts(s, "VERSION 20070824\n"); 10413829537SPekka Paalanen 105d0a7e8caSPekka Paalanen hiter = kzalloc(sizeof(*hiter), GFP_KERNEL); 106d0a7e8caSPekka Paalanen if (!hiter) 107d0a7e8caSPekka Paalanen return; 108d0a7e8caSPekka Paalanen 109d0a7e8caSPekka Paalanen hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 110d0a7e8caSPekka Paalanen iter->private = hiter; 111d0a7e8caSPekka Paalanen } 112d0a7e8caSPekka Paalanen 113d0a7e8caSPekka Paalanen /* XXX: This is not called when the pipe is closed! */ 114d0a7e8caSPekka Paalanen static void mmio_close(struct trace_iterator *iter) 115d0a7e8caSPekka Paalanen { 116d0a7e8caSPekka Paalanen struct header_iter *hiter = iter->private; 117d0a7e8caSPekka Paalanen destroy_header_iter(hiter); 118d0a7e8caSPekka Paalanen iter->private = NULL; 119d0a7e8caSPekka Paalanen } 120d0a7e8caSPekka Paalanen 1212039238bSPekka Paalanen static unsigned long count_overruns(struct trace_iterator *iter) 1222039238bSPekka Paalanen { 123173ed24eSPekka Paalanen unsigned long cnt = atomic_xchg(&dropped_count, 0); 12412883efbSSteven Rostedt (Red Hat) unsigned long over = ring_buffer_overruns(iter->trace_buffer->buffer); 1257ee1768dSPekka Paalanen 1267ee1768dSPekka Paalanen if (over > prev_overruns) 127173ed24eSPekka Paalanen cnt += over - prev_overruns; 1287ee1768dSPekka Paalanen prev_overruns = over; 1292039238bSPekka Paalanen return cnt; 1302039238bSPekka Paalanen } 1312039238bSPekka Paalanen 132d0a7e8caSPekka Paalanen static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp, 133d0a7e8caSPekka Paalanen char __user *ubuf, size_t cnt, loff_t *ppos) 134d0a7e8caSPekka Paalanen { 135d0a7e8caSPekka Paalanen ssize_t ret; 136d0a7e8caSPekka Paalanen struct header_iter *hiter = iter->private; 137d0a7e8caSPekka Paalanen struct trace_seq *s = &iter->seq; 1382039238bSPekka Paalanen unsigned long n; 1392039238bSPekka Paalanen 1402039238bSPekka Paalanen n = count_overruns(iter); 1412039238bSPekka Paalanen if (n) { 1422039238bSPekka Paalanen /* XXX: This is later than where events were lost. */ 1432039238bSPekka Paalanen trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n); 1442039238bSPekka Paalanen if (!overrun_detected) 145a395d6a7SJoe Perches pr_warn("mmiotrace has lost events\n"); 1462039238bSPekka Paalanen overrun_detected = true; 1472039238bSPekka Paalanen goto print_out; 1482039238bSPekka Paalanen } 149d0a7e8caSPekka Paalanen 150d0a7e8caSPekka Paalanen if (!hiter) 151d0a7e8caSPekka Paalanen return 0; 152d0a7e8caSPekka Paalanen 153d0a7e8caSPekka Paalanen mmio_print_pcidev(s, hiter->dev); 154d0a7e8caSPekka Paalanen hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev); 155d0a7e8caSPekka Paalanen 156d0a7e8caSPekka Paalanen if (!hiter->dev) { 157d0a7e8caSPekka Paalanen destroy_header_iter(hiter); 158d0a7e8caSPekka Paalanen iter->private = NULL; 159d0a7e8caSPekka Paalanen } 160d0a7e8caSPekka Paalanen 1612039238bSPekka Paalanen print_out: 162d0a7e8caSPekka Paalanen ret = trace_seq_to_user(s, ubuf, cnt); 163d0a7e8caSPekka Paalanen return (ret == -EBUSY) ? 0 : ret; 164bd8ac686SPekka Paalanen } 165bd8ac686SPekka Paalanen 16607f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_rw(struct trace_iterator *iter) 167bd8ac686SPekka Paalanen { 168bd8ac686SPekka Paalanen struct trace_entry *entry = iter->ent; 1697104f300SSteven Rostedt struct trace_mmiotrace_rw *field; 1707104f300SSteven Rostedt struct mmiotrace_rw *rw; 171bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 1723928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 173a5dec557SLi Zefan unsigned long usec_rem = do_div(t, USEC_PER_SEC); 174bd8ac686SPekka Paalanen unsigned secs = (unsigned long)t; 175bd8ac686SPekka Paalanen 1767104f300SSteven Rostedt trace_assign_type(field, entry); 1777104f300SSteven Rostedt rw = &field->rw; 1787104f300SSteven Rostedt 179777e208dSSteven Rostedt switch (rw->opcode) { 180bd8ac686SPekka Paalanen case MMIO_READ: 181a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, 1825e4abc98SSteven Rostedt "R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", 183dee310d0SPekka Paalanen rw->width, secs, usec_rem, rw->map_id, 184dee310d0SPekka Paalanen (unsigned long long)rw->phys, 185736ca61fSPekka Paalanen rw->value, rw->pc, 0); 186bd8ac686SPekka Paalanen break; 187bd8ac686SPekka Paalanen case MMIO_WRITE: 188a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, 1895e4abc98SSteven Rostedt "W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", 190dee310d0SPekka Paalanen rw->width, secs, usec_rem, rw->map_id, 191dee310d0SPekka Paalanen (unsigned long long)rw->phys, 192736ca61fSPekka Paalanen rw->value, rw->pc, 0); 193bd8ac686SPekka Paalanen break; 194bd8ac686SPekka Paalanen case MMIO_UNKNOWN_OP: 195a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, 1965e4abc98SSteven Rostedt "UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx," 1975e4abc98SSteven Rostedt "%02lx 0x%lx %d\n", 198dee310d0SPekka Paalanen secs, usec_rem, rw->map_id, 199dee310d0SPekka Paalanen (unsigned long long)rw->phys, 200bd8ac686SPekka Paalanen (rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff, 201736ca61fSPekka Paalanen (rw->value >> 0) & 0xff, rw->pc, 0); 202bd8ac686SPekka Paalanen break; 203bd8ac686SPekka Paalanen default: 204a72e10afSSteven Rostedt (Red Hat) trace_seq_puts(s, "rw what?\n"); 205bd8ac686SPekka Paalanen break; 206bd8ac686SPekka Paalanen } 207a72e10afSSteven Rostedt (Red Hat) 208a72e10afSSteven Rostedt (Red Hat) return trace_handle_return(s); 209bd8ac686SPekka Paalanen } 210bd8ac686SPekka Paalanen 21107f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_map(struct trace_iterator *iter) 212bd8ac686SPekka Paalanen { 213bd8ac686SPekka Paalanen struct trace_entry *entry = iter->ent; 2147104f300SSteven Rostedt struct trace_mmiotrace_map *field; 2157104f300SSteven Rostedt struct mmiotrace_map *m; 216bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 2173928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 218a5dec557SLi Zefan unsigned long usec_rem = do_div(t, USEC_PER_SEC); 219bd8ac686SPekka Paalanen unsigned secs = (unsigned long)t; 220bd8ac686SPekka Paalanen 2217104f300SSteven Rostedt trace_assign_type(field, entry); 2227104f300SSteven Rostedt m = &field->map; 2237104f300SSteven Rostedt 224777e208dSSteven Rostedt switch (m->opcode) { 225bd8ac686SPekka Paalanen case MMIO_PROBE: 226a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, 2275e4abc98SSteven Rostedt "MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", 228dee310d0SPekka Paalanen secs, usec_rem, m->map_id, 229dee310d0SPekka Paalanen (unsigned long long)m->phys, m->virt, m->len, 230e0fd5c2fSPekka Paalanen 0UL, 0); 231bd8ac686SPekka Paalanen break; 232bd8ac686SPekka Paalanen case MMIO_UNPROBE: 233a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, 2345e4abc98SSteven Rostedt "UNMAP %u.%06lu %d 0x%lx %d\n", 235e0fd5c2fSPekka Paalanen secs, usec_rem, m->map_id, 0UL, 0); 236bd8ac686SPekka Paalanen break; 237bd8ac686SPekka Paalanen default: 238a72e10afSSteven Rostedt (Red Hat) trace_seq_puts(s, "map what?\n"); 239bd8ac686SPekka Paalanen break; 240bd8ac686SPekka Paalanen } 241a72e10afSSteven Rostedt (Red Hat) 242a72e10afSSteven Rostedt (Red Hat) return trace_handle_return(s); 243bd8ac686SPekka Paalanen } 244bd8ac686SPekka Paalanen 24507f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_mark(struct trace_iterator *iter) 246fc5e27aeSPekka Paalanen { 247fc5e27aeSPekka Paalanen struct trace_entry *entry = iter->ent; 248777e208dSSteven Rostedt struct print_entry *print = (struct print_entry *)entry; 24948ead020SFrederic Weisbecker const char *msg = print->buf; 250fc5e27aeSPekka Paalanen struct trace_seq *s = &iter->seq; 2513928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 252769b0441SFrederic Weisbecker unsigned long usec_rem = do_div(t, USEC_PER_SEC); 253fc5e27aeSPekka Paalanen unsigned secs = (unsigned long)t; 254fc5e27aeSPekka Paalanen 255fc5e27aeSPekka Paalanen /* The trailing newline must be in the message. */ 256a72e10afSSteven Rostedt (Red Hat) trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); 257fc5e27aeSPekka Paalanen 258a72e10afSSteven Rostedt (Red Hat) return trace_handle_return(s); 259fc5e27aeSPekka Paalanen } 260fc5e27aeSPekka Paalanen 26107f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_line(struct trace_iterator *iter) 262bd8ac686SPekka Paalanen { 263bd8ac686SPekka Paalanen switch (iter->ent->type) { 264bd8ac686SPekka Paalanen case TRACE_MMIO_RW: 265bd8ac686SPekka Paalanen return mmio_print_rw(iter); 266bd8ac686SPekka Paalanen case TRACE_MMIO_MAP: 267bd8ac686SPekka Paalanen return mmio_print_map(iter); 268fc5e27aeSPekka Paalanen case TRACE_PRINT: 269fc5e27aeSPekka Paalanen return mmio_print_mark(iter); 270bd8ac686SPekka Paalanen default: 27107f4e4f7SFrederic Weisbecker return TRACE_TYPE_HANDLED; /* ignore unknown entries */ 272bd8ac686SPekka Paalanen } 273bd8ac686SPekka Paalanen } 274f984b51eSPekka Paalanen 275f984b51eSPekka Paalanen static struct tracer mmio_tracer __read_mostly = 276f984b51eSPekka Paalanen { 277f984b51eSPekka Paalanen .name = "mmiotrace", 278f984b51eSPekka Paalanen .init = mmio_trace_init, 279f984b51eSPekka Paalanen .reset = mmio_trace_reset, 280bbf5b1a0SSteven Rostedt .start = mmio_trace_start, 281d0a7e8caSPekka Paalanen .pipe_open = mmio_pipe_open, 282d0a7e8caSPekka Paalanen .close = mmio_close, 283d0a7e8caSPekka Paalanen .read = mmio_read, 284bd8ac686SPekka Paalanen .print_line = mmio_print_line, 285*c7b3ae0bSZiqian SUN (Zamir) .noboot = true, 286f984b51eSPekka Paalanen }; 287f984b51eSPekka Paalanen 288f984b51eSPekka Paalanen __init static int init_mmio_trace(void) 289f984b51eSPekka Paalanen { 290f984b51eSPekka Paalanen return register_tracer(&mmio_tracer); 291f984b51eSPekka Paalanen } 292f984b51eSPekka Paalanen device_initcall(init_mmio_trace); 293f984b51eSPekka Paalanen 29445dcd8b8SPekka Paalanen static void __trace_mmiotrace_rw(struct trace_array *tr, 29545dcd8b8SPekka Paalanen struct trace_array_cpu *data, 29645dcd8b8SPekka Paalanen struct mmiotrace_rw *rw) 29745dcd8b8SPekka Paalanen { 2982425bcb9SSteven Rostedt (Red Hat) struct trace_event_call *call = &event_mmiotrace_rw; 29912883efbSSteven Rostedt (Red Hat) struct ring_buffer *buffer = tr->trace_buffer.buffer; 3003928a8a2SSteven Rostedt struct ring_buffer_event *event; 301777e208dSSteven Rostedt struct trace_mmiotrace_rw *entry; 30251a763ddSArnaldo Carvalho de Melo int pc = preempt_count(); 30345dcd8b8SPekka Paalanen 304e77405adSSteven Rostedt event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW, 30551a763ddSArnaldo Carvalho de Melo sizeof(*entry), 0, pc); 306173ed24eSPekka Paalanen if (!event) { 307173ed24eSPekka Paalanen atomic_inc(&dropped_count); 3083928a8a2SSteven Rostedt return; 309173ed24eSPekka Paalanen } 3103928a8a2SSteven Rostedt entry = ring_buffer_event_data(event); 311777e208dSSteven Rostedt entry->rw = *rw; 31260ba7702SSteven Rostedt 313f306cc82STom Zanussi if (!call_filter_check_discard(call, entry, buffer, event)) 314b7f0c959SSteven Rostedt (Red Hat) trace_buffer_unlock_commit(tr, buffer, event, 0, pc); 31545dcd8b8SPekka Paalanen } 31645dcd8b8SPekka Paalanen 317bd8ac686SPekka Paalanen void mmio_trace_rw(struct mmiotrace_rw *rw) 318f984b51eSPekka Paalanen { 319f984b51eSPekka Paalanen struct trace_array *tr = mmio_trace_array; 32012883efbSSteven Rostedt (Red Hat) struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id()); 321bd8ac686SPekka Paalanen __trace_mmiotrace_rw(tr, data, rw); 322bd8ac686SPekka Paalanen } 323f984b51eSPekka Paalanen 32445dcd8b8SPekka Paalanen static void __trace_mmiotrace_map(struct trace_array *tr, 32545dcd8b8SPekka Paalanen struct trace_array_cpu *data, 32645dcd8b8SPekka Paalanen struct mmiotrace_map *map) 32745dcd8b8SPekka Paalanen { 3282425bcb9SSteven Rostedt (Red Hat) struct trace_event_call *call = &event_mmiotrace_map; 32912883efbSSteven Rostedt (Red Hat) struct ring_buffer *buffer = tr->trace_buffer.buffer; 3303928a8a2SSteven Rostedt struct ring_buffer_event *event; 331777e208dSSteven Rostedt struct trace_mmiotrace_map *entry; 33251a763ddSArnaldo Carvalho de Melo int pc = preempt_count(); 33345dcd8b8SPekka Paalanen 334e77405adSSteven Rostedt event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP, 33551a763ddSArnaldo Carvalho de Melo sizeof(*entry), 0, pc); 336173ed24eSPekka Paalanen if (!event) { 337173ed24eSPekka Paalanen atomic_inc(&dropped_count); 3383928a8a2SSteven Rostedt return; 339173ed24eSPekka Paalanen } 3403928a8a2SSteven Rostedt entry = ring_buffer_event_data(event); 341777e208dSSteven Rostedt entry->map = *map; 34260ba7702SSteven Rostedt 343f306cc82STom Zanussi if (!call_filter_check_discard(call, entry, buffer, event)) 344b7f0c959SSteven Rostedt (Red Hat) trace_buffer_unlock_commit(tr, buffer, event, 0, pc); 34545dcd8b8SPekka Paalanen } 34645dcd8b8SPekka Paalanen 347bd8ac686SPekka Paalanen void mmio_trace_mapping(struct mmiotrace_map *map) 348bd8ac686SPekka Paalanen { 349bd8ac686SPekka Paalanen struct trace_array *tr = mmio_trace_array; 350bd8ac686SPekka Paalanen struct trace_array_cpu *data; 351bd8ac686SPekka Paalanen 352bd8ac686SPekka Paalanen preempt_disable(); 35312883efbSSteven Rostedt (Red Hat) data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id()); 354bd8ac686SPekka Paalanen __trace_mmiotrace_map(tr, data, map); 355bd8ac686SPekka Paalanen preempt_enable(); 356f984b51eSPekka Paalanen } 3579e57fb35SPekka Paalanen 3589e57fb35SPekka Paalanen int mmio_trace_printk(const char *fmt, va_list args) 3599e57fb35SPekka Paalanen { 36040ce74f1SSteven Rostedt return trace_vprintk(0, fmt, args); 3619e57fb35SPekka Paalanen } 362