Release 4.15 kernel/trace/trace_mmiotrace.c
// SPDX-License-Identifier: GPL-2.0
/*
* Memory mapped I/O tracing
*
* Copyright (C) 2008 Pekka Paalanen <pq@iki.fi>
*/
#define DEBUG 1
#include <linux/kernel.h>
#include <linux/mmiotrace.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/atomic.h>
#include "trace.h"
#include "trace_output.h"
struct header_iter {
struct pci_dev *dev;
};
static struct trace_array *mmio_trace_array;
static bool overrun_detected;
static unsigned long prev_overruns;
static atomic_t dropped_count;
static void mmio_reset_data(struct trace_array *tr)
{
overrun_detected = false;
prev_overruns = 0;
tracing_reset_online_cpus(&tr->trace_buffer);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 23 | 85.19% | 3 | 60.00% |
Steven Rostedt | 3 | 11.11% | 1 | 20.00% |
Pekka J Enberg | 1 | 3.70% | 1 | 20.00% |
Total | 27 | 100.00% | 5 | 100.00% |
static int mmio_trace_init(struct trace_array *tr)
{
pr_debug("in %s\n", __func__);
mmio_trace_array = tr;
mmio_reset_data(tr);
enable_mmiotrace();
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 29 | 87.88% | 2 | 66.67% |
Frédéric Weisbecker | 4 | 12.12% | 1 | 33.33% |
Total | 33 | 100.00% | 3 | 100.00% |
static void mmio_trace_reset(struct trace_array *tr)
{
pr_debug("in %s\n", __func__);
disable_mmiotrace();
mmio_reset_data(tr);
mmio_trace_array = NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 30 | 100.00% | 2 | 100.00% |
Total | 30 | 100.00% | 2 | 100.00% |
static void mmio_trace_start(struct trace_array *tr)
{
pr_debug("in %s\n", __func__);
mmio_reset_data(tr);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 22 | 95.65% | 2 | 66.67% |
Steven Rostedt | 1 | 4.35% | 1 | 33.33% |
Total | 23 | 100.00% | 3 | 100.00% |
static void mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
{
int i;
resource_size_t start, end;
const struct pci_driver *drv = pci_dev_driver(dev);
trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
dev->bus->number, dev->devfn,
dev->vendor, dev->device, dev->irq);
for (i = 0; i < 7; i++) {
start = dev->resource[i].start;
trace_seq_printf(s, " %llx",
(unsigned long long)(start |
(dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
}
for (i = 0; i < 7; i++) {
start = dev->resource[i].start;
end = dev->resource[i].end;
trace_seq_printf(s, " %llx",
dev->resource[i].start < dev->resource[i].end ?
(unsigned long long)(end - start) + 1 : 0);
}
if (drv)
trace_seq_printf(s, " %s\n", drv->name);
else
trace_seq_puts(s, " \n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 203 | 92.27% | 1 | 25.00% |
Björn Helgaas | 15 | 6.82% | 1 | 25.00% |
Steven Rostedt | 1 | 0.45% | 1 | 25.00% |
Jovi Zhangwei | 1 | 0.45% | 1 | 25.00% |
Total | 220 | 100.00% | 4 | 100.00% |
static void destroy_header_iter(struct header_iter *hiter)
{
if (!hiter)
return;
pci_dev_put(hiter->dev);
kfree(hiter);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 29 | 100.00% | 1 | 100.00% |
Total | 29 | 100.00% | 1 | 100.00% |
static void mmio_pipe_open(struct trace_iterator *iter)
{
struct header_iter *hiter;
struct trace_seq *s = &iter->seq;
trace_seq_puts(s, "VERSION 20070824\n");
hiter = kzalloc(sizeof(*hiter), GFP_KERNEL);
if (!hiter)
return;
hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
iter->private = hiter;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 70 | 98.59% | 3 | 75.00% |
Jovi Zhangwei | 1 | 1.41% | 1 | 25.00% |
Total | 71 | 100.00% | 4 | 100.00% |
/* XXX: This is not called when the pipe is closed! */
static void mmio_close(struct trace_iterator *iter)
{
struct header_iter *hiter = iter->private;
destroy_header_iter(hiter);
iter->private = NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 31 | 100.00% | 2 | 100.00% |
Total | 31 | 100.00% | 2 | 100.00% |
static unsigned long count_overruns(struct trace_iterator *iter)
{
unsigned long cnt = atomic_xchg(&dropped_count, 0);
unsigned long over = ring_buffer_overruns(iter->trace_buffer->buffer);
if (over > prev_overruns)
cnt += over - prev_overruns;
prev_overruns = over;
return cnt;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 55 | 98.21% | 3 | 75.00% |
Steven Rostedt | 1 | 1.79% | 1 | 25.00% |
Total | 56 | 100.00% | 4 | 100.00% |
static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
char __user *ubuf, size_t cnt, loff_t *ppos)
{
ssize_t ret;
struct header_iter *hiter = iter->private;
struct trace_seq *s = &iter->seq;
unsigned long n;
n = count_overruns(iter);
if (n) {
/* XXX: This is later than where events were lost. */
trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n);
if (!overrun_detected)
pr_warn("mmiotrace has lost events\n");
overrun_detected = true;
goto print_out;
}
if (!hiter)
return 0;
mmio_print_pcidev(s, hiter->dev);
hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev);
if (!hiter->dev) {
destroy_header_iter(hiter);
iter->private = NULL;
}
print_out:
ret = trace_seq_to_user(s, ubuf, cnt);
return (ret == -EBUSY) ? 0 : ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 169 | 98.83% | 4 | 80.00% |
Joe Perches | 2 | 1.17% | 1 | 20.00% |
Total | 171 | 100.00% | 5 | 100.00% |
static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
{
struct trace_entry *entry = iter->ent;
struct trace_mmiotrace_rw *field;
struct mmiotrace_rw *rw;
struct trace_seq *s = &iter->seq;
unsigned long long t = ns2usecs(iter->ts);
unsigned long usec_rem = do_div(t, USEC_PER_SEC);
unsigned secs = (unsigned long)t;
trace_assign_type(field, entry);
rw = &field->rw;
switch (rw->opcode) {
case MMIO_READ:
trace_seq_printf(s,
"R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
rw->width, secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
rw->value, rw->pc, 0);
break;
case MMIO_WRITE:
trace_seq_printf(s,
"W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
rw->width, secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
rw->value, rw->pc, 0);
break;
case MMIO_UNKNOWN_OP:
trace_seq_printf(s,
"UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx,"
"%02lx 0x%lx %d\n",
secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
(rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff,
(rw->value >> 0) & 0xff, rw->pc, 0);
break;
default:
trace_seq_puts(s, "rw what?\n");
break;
}
return trace_handle_return(s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 225 | 86.87% | 3 | 27.27% |
Steven Rostedt | 30 | 11.58% | 5 | 45.45% |
Frédéric Weisbecker | 2 | 0.77% | 1 | 9.09% |
Jovi Zhangwei | 1 | 0.39% | 1 | 9.09% |
Li Zefan | 1 | 0.39% | 1 | 9.09% |
Total | 259 | 100.00% | 11 | 100.00% |
static enum print_line_t mmio_print_map(struct trace_iterator *iter)
{
struct trace_entry *entry = iter->ent;
struct trace_mmiotrace_map *field;
struct mmiotrace_map *m;
struct trace_seq *s = &iter->seq;
unsigned long long t = ns2usecs(iter->ts);
unsigned long usec_rem = do_div(t, USEC_PER_SEC);
unsigned secs = (unsigned long)t;
trace_assign_type(field, entry);
m = &field->map;
switch (m->opcode) {
case MMIO_PROBE:
trace_seq_printf(s,
"MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
secs, usec_rem, m->map_id,
(unsigned long long)m->phys, m->virt, m->len,
0UL, 0);
break;
case MMIO_UNPROBE:
trace_seq_printf(s,
"UNMAP %u.%06lu %d 0x%lx %d\n",
secs, usec_rem, m->map_id, 0UL, 0);
break;
default:
trace_seq_puts(s, "map what?\n");
break;
}
return trace_handle_return(s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 141 | 81.50% | 3 | 27.27% |
Steven Rostedt | 28 | 16.18% | 5 | 45.45% |
Frédéric Weisbecker | 2 | 1.16% | 1 | 9.09% |
Li Zefan | 1 | 0.58% | 1 | 9.09% |
Jovi Zhangwei | 1 | 0.58% | 1 | 9.09% |
Total | 173 | 100.00% | 11 | 100.00% |
static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
{
struct trace_entry *entry = iter->ent;
struct print_entry *print = (struct print_entry *)entry;
const char *msg = print->buf;
struct trace_seq *s = &iter->seq;
unsigned long long t = ns2usecs(iter->ts);
unsigned long usec_rem = do_div(t, USEC_PER_SEC);
unsigned secs = (unsigned long)t;
/* The trailing newline must be in the message. */
trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg);
return trace_handle_return(s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 72 | 69.23% | 1 | 14.29% |
Steven Rostedt | 18 | 17.31% | 3 | 42.86% |
Frédéric Weisbecker | 14 | 13.46% | 3 | 42.86% |
Total | 104 | 100.00% | 7 | 100.00% |
static enum print_line_t mmio_print_line(struct trace_iterator *iter)
{
switch (iter->ent->type) {
case TRACE_MMIO_RW:
return mmio_print_rw(iter);
case TRACE_MMIO_MAP:
return mmio_print_map(iter);
case TRACE_PRINT:
return mmio_print_mark(iter);
default:
return TRACE_TYPE_HANDLED; /* ignore unknown entries */
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 51 | 94.44% | 2 | 66.67% |
Frédéric Weisbecker | 3 | 5.56% | 1 | 33.33% |
Total | 54 | 100.00% | 3 | 100.00% |
static struct tracer mmio_tracer __read_mostly =
{
.name = "mmiotrace",
.init = mmio_trace_init,
.reset = mmio_trace_reset,
.start = mmio_trace_start,
.pipe_open = mmio_pipe_open,
.close = mmio_close,
.read = mmio_read,
.print_line = mmio_print_line,
.noboot = true,
};
__init static int init_mmio_trace(void)
{
return register_tracer(&mmio_tracer);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 16 | 100.00% | 1 | 100.00% |
Total | 16 | 100.00% | 1 | 100.00% |
device_initcall(init_mmio_trace);
static void __trace_mmiotrace_rw(struct trace_array *tr,
struct trace_array_cpu *data,
struct mmiotrace_rw *rw)
{
struct trace_event_call *call = &event_mmiotrace_rw;
struct ring_buffer *buffer = tr->trace_buffer.buffer;
struct ring_buffer_event *event;
struct trace_mmiotrace_rw *entry;
int pc = preempt_count();
event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW,
sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
return;
}
entry = ring_buffer_event_data(event);
entry->rw = *rw;
if (!call_filter_check_discard(call, entry, buffer, event))
trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 60 | 46.15% | 7 | 63.64% |
Pekka Paalanen | 51 | 39.23% | 2 | 18.18% |
Arnaldo Carvalho de Melo | 18 | 13.85% | 1 | 9.09% |
Tom Zanussi | 1 | 0.77% | 1 | 9.09% |
Total | 130 | 100.00% | 11 | 100.00% |
void mmio_trace_rw(struct mmiotrace_rw *rw)
{
struct trace_array *tr = mmio_trace_array;
struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
__trace_mmiotrace_rw(tr, data, rw);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 37 | 86.05% | 2 | 50.00% |
Steven Rostedt | 6 | 13.95% | 2 | 50.00% |
Total | 43 | 100.00% | 4 | 100.00% |
static void __trace_mmiotrace_map(struct trace_array *tr,
struct trace_array_cpu *data,
struct mmiotrace_map *map)
{
struct trace_event_call *call = &event_mmiotrace_map;
struct ring_buffer *buffer = tr->trace_buffer.buffer;
struct ring_buffer_event *event;
struct trace_mmiotrace_map *entry;
int pc = preempt_count();
event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP,
sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
return;
}
entry = ring_buffer_event_data(event);
entry->map = *map;
if (!call_filter_check_discard(call, entry, buffer, event))
trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 60 | 46.15% | 7 | 63.64% |
Pekka Paalanen | 51 | 39.23% | 2 | 18.18% |
Arnaldo Carvalho de Melo | 18 | 13.85% | 1 | 9.09% |
Tom Zanussi | 1 | 0.77% | 1 | 9.09% |
Total | 130 | 100.00% | 11 | 100.00% |
void mmio_trace_mapping(struct mmiotrace_map *map)
{
struct trace_array *tr = mmio_trace_array;
struct trace_array_cpu *data;
preempt_disable();
data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
__trace_mmiotrace_map(tr, data, map);
preempt_enable();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 45 | 88.24% | 2 | 50.00% |
Steven Rostedt | 6 | 11.76% | 2 | 50.00% |
Total | 51 | 100.00% | 4 | 100.00% |
int mmio_trace_printk(const char *fmt, va_list args)
{
return trace_vprintk(0, fmt, args);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 23 | 100.00% | 1 | 100.00% |
Total | 23 | 100.00% | 1 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pekka Paalanen | 1470 | 82.03% | 13 | 31.71% |
Steven Rostedt | 222 | 12.39% | 13 | 31.71% |
Arnaldo Carvalho de Melo | 36 | 2.01% | 1 | 2.44% |
Frédéric Weisbecker | 25 | 1.40% | 4 | 9.76% |
Björn Helgaas | 15 | 0.84% | 1 | 2.44% |
Ziqian SUN (Zamir) | 5 | 0.28% | 1 | 2.44% |
Li Zefan | 5 | 0.28% | 1 | 2.44% |
Jovi Zhangwei | 4 | 0.22% | 1 | 2.44% |
Tejun Heo | 3 | 0.17% | 1 | 2.44% |
Joe Perches | 2 | 0.11% | 1 | 2.44% |
Tom Zanussi | 2 | 0.11% | 1 | 2.44% |
Greg Kroah-Hartman | 1 | 0.06% | 1 | 2.44% |
Arun Sharma | 1 | 0.06% | 1 | 2.44% |
Pekka J Enberg | 1 | 0.06% | 1 | 2.44% |
Total | 1792 | 100.00% | 41 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.