cregit-Linux how code gets into the kernel

Release 4.15 kernel/trace/trace_mmiotrace.c

Directory: kernel/trace
// 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

PersonTokensPropCommitsCommitProp
Pekka Paalanen2385.19%360.00%
Steven Rostedt311.11%120.00%
Pekka J Enberg13.70%120.00%
Total27100.00%5100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen2987.88%266.67%
Frédéric Weisbecker412.12%133.33%
Total33100.00%3100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen30100.00%2100.00%
Total30100.00%2100.00%


static void mmio_trace_start(struct trace_array *tr) { pr_debug("in %s\n", __func__); mmio_reset_data(tr); }

Contributors

PersonTokensPropCommitsCommitProp
Pekka Paalanen2295.65%266.67%
Steven Rostedt14.35%133.33%
Total23100.00%3100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen20392.27%125.00%
Björn Helgaas156.82%125.00%
Steven Rostedt10.45%125.00%
Jovi Zhangwei10.45%125.00%
Total220100.00%4100.00%


static void destroy_header_iter(struct header_iter *hiter) { if (!hiter) return; pci_dev_put(hiter->dev); kfree(hiter); }

Contributors

PersonTokensPropCommitsCommitProp
Pekka Paalanen29100.00%1100.00%
Total29100.00%1100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen7098.59%375.00%
Jovi Zhangwei11.41%125.00%
Total71100.00%4100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen31100.00%2100.00%
Total31100.00%2100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen5598.21%375.00%
Steven Rostedt11.79%125.00%
Total56100.00%4100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen16998.83%480.00%
Joe Perches21.17%120.00%
Total171100.00%5100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen22586.87%327.27%
Steven Rostedt3011.58%545.45%
Frédéric Weisbecker20.77%19.09%
Jovi Zhangwei10.39%19.09%
Li Zefan10.39%19.09%
Total259100.00%11100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen14181.50%327.27%
Steven Rostedt2816.18%545.45%
Frédéric Weisbecker21.16%19.09%
Li Zefan10.58%19.09%
Jovi Zhangwei10.58%19.09%
Total173100.00%11100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen7269.23%114.29%
Steven Rostedt1817.31%342.86%
Frédéric Weisbecker1413.46%342.86%
Total104100.00%7100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen5194.44%266.67%
Frédéric Weisbecker35.56%133.33%
Total54100.00%3100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen16100.00%1100.00%
Total16100.00%1100.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

PersonTokensPropCommitsCommitProp
Steven Rostedt6046.15%763.64%
Pekka Paalanen5139.23%218.18%
Arnaldo Carvalho de Melo1813.85%19.09%
Tom Zanussi10.77%19.09%
Total130100.00%11100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen3786.05%250.00%
Steven Rostedt613.95%250.00%
Total43100.00%4100.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

PersonTokensPropCommitsCommitProp
Steven Rostedt6046.15%763.64%
Pekka Paalanen5139.23%218.18%
Arnaldo Carvalho de Melo1813.85%19.09%
Tom Zanussi10.77%19.09%
Total130100.00%11100.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

PersonTokensPropCommitsCommitProp
Pekka Paalanen4588.24%250.00%
Steven Rostedt611.76%250.00%
Total51100.00%4100.00%


int mmio_trace_printk(const char *fmt, va_list args) { return trace_vprintk(0, fmt, args); }

Contributors

PersonTokensPropCommitsCommitProp
Pekka Paalanen23100.00%1100.00%
Total23100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Pekka Paalanen147082.03%1331.71%
Steven Rostedt22212.39%1331.71%
Arnaldo Carvalho de Melo362.01%12.44%
Frédéric Weisbecker251.40%49.76%
Björn Helgaas150.84%12.44%
Ziqian SUN (Zamir)50.28%12.44%
Li Zefan50.28%12.44%
Jovi Zhangwei40.22%12.44%
Tejun Heo30.17%12.44%
Joe Perches20.11%12.44%
Tom Zanussi20.11%12.44%
Greg Kroah-Hartman10.06%12.44%
Arun Sharma10.06%12.44%
Pekka J Enberg10.06%12.44%
Total1792100.00%41100.00%
Directory: kernel/trace
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.