summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2008-05-12 21:20:58 +0200
committerThomas Gleixner <tglx@linutronix.de>2008-05-24 11:25:16 +0200
commit138295373ccf7625fcb0218dfea114837983bc39 (patch)
tree3d4afbb0d976fa41435fd5806ff0338aa1f15567 /kernel
parentbd8ac686c73c7e925fcfe0b02dc4e7b947127864 (diff)
ftrace: mmiotrace update, #2
another weekend, another patch. This should apply on top of my previous patch from March 23rd. Summary of changes: - Print PCI device list in output header - work around recursive probe hits on SMP - refactor dis/arm_kmmio_fault_page() and add check for page levels - remove un/reference_kmmio(), the die notifier hook is registered permanently into the list - explicitly check for single stepping in die notifier callback I have tested this version on my UP Athlon64 desktop with Nouveau, and SMP Core 2 Duo laptop with the proprietary nvidia driver. Both systems are 64-bit. One previously unknown bug crept into daylight: the ftrace framework's output routines print the first entry last after buffer has wrapped around. The most important regressions compared to non-ftrace mmiotrace at this time are: - failure of trace_pipe file - illegal lines in output file - unaware of losing data due to buffer full Personally I'd like to see these three solved before submitting to mainline. Other issues may come up once we know when we lose events. Signed-off-by: Pekka Paalanen <pq@iki.fi> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_mmiotrace.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 3a12b1ad0c6..361472b5788 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/mmiotrace.h>
+#include <linux/pci.h>
#include "trace.h"
@@ -53,12 +54,52 @@ static void mmio_trace_ctrl_update(struct trace_array *tr)
}
}
+static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
+{
+ int ret = 0;
+ int i;
+ resource_size_t start, end;
+ const struct pci_driver *drv = pci_dev_driver(dev);
+
+ /* XXX: incomplete checks for trace_seq_printf() return value */
+ ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
+ dev->bus->number, dev->devfn,
+ dev->vendor, dev->device, dev->irq);
+ /*
+ * XXX: is pci_resource_to_user() appropriate, since we are
+ * supposed to interpret the __ioremap() phys_addr argument based on
+ * these printed values?
+ */
+ for (i = 0; i < 7; i++) {
+ pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
+ ret += trace_seq_printf(s, " %llx",
+ (unsigned long long)(start |
+ (dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
+ }
+ for (i = 0; i < 7; i++) {
+ pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
+ ret += trace_seq_printf(s, " %llx",
+ dev->resource[i].start < dev->resource[i].end ?
+ (unsigned long long)(end - start) + 1 : 0);
+ }
+ if (drv)
+ ret += trace_seq_printf(s, " %s\n", drv->name);
+ else
+ ret += trace_seq_printf(s, " \n");
+ return ret;
+}
+
/* XXX: This is not called for trace_pipe file! */
-void mmio_print_header(struct trace_iterator *iter)
+static void mmio_print_header(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
- trace_seq_printf(s, "VERSION broken 20070824\n");
- /* TODO: print /proc/bus/pci/devices contents as PCIDEV lines */
+ struct pci_dev *dev = NULL;
+
+ trace_seq_printf(s, "VERSION 20070824\n");
+
+ for_each_pci_dev(dev)
+ mmio_print_pcidev(s, dev);
+ /* XXX: return value? What if header is very long? */
}
static int mmio_print_rw(struct trace_iterator *iter)