From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Ingo Molnar <mingo@elte.hu>, linux-kernel@vger.kernel.org
Cc: Paul Mackerras <paulus@samba.org>, Mike Galbraith <efault@gmx.de>,
Arjan van de Ven <arjan@infradead.org>,
Wu Fengguang <fengguang.wu@intel.com>,
Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 6/6] perf_counter: kerneltop: output event support
Date: Wed, 25 Mar 2009 12:30:27 +0100 [thread overview]
Message-ID: <20090325113317.192910290@chello.nl> (raw)
In-Reply-To: 20090325113021.781490788@chello.nl
[-- Attachment #1: kerneltop-mmap-packets.patch --]
[-- Type: text/plain, Size: 3733 bytes --]
Teach kerneltop about the new output ABI.
XXX: anybody fancy integrating the PID/TID data into the output?
Bump the mmap_data pages a little because we bloated the output and
have to be more careful about overruns with structured data.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
Documentation/perf_counter/kerneltop.c | 65 +++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 6 deletions(-)
Index: linux-2.6/Documentation/perf_counter/kerneltop.c
===================================================================
--- linux-2.6.orig/Documentation/perf_counter/kerneltop.c
+++ linux-2.6/Documentation/perf_counter/kerneltop.c
@@ -134,6 +134,11 @@
#endif
#define unlikely(x) __builtin_expect(!!(x), 0)
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; })
asmlinkage int sys_perf_counter_open(
struct perf_counter_hw_event *hw_event_uptr __user,
@@ -178,7 +183,7 @@ static int nr_cpus = 0;
static int nmi = 1;
static int group = 0;
static unsigned int page_size;
-static unsigned int mmap_pages = 4;
+static unsigned int mmap_pages = 16;
static char *vmlinux;
@@ -1147,28 +1152,75 @@ static void mmap_read(struct mmap_data *
unsigned int head = mmap_read_head(md);
unsigned int old = md->prev;
unsigned char *data = md->base + page_size;
+ int diff;
gettimeofday(&this_read, NULL);
- if (head - old > md->mask) {
+ /*
+ * If we're further behind than half the buffer, there's a chance
+ * the writer will bite our tail and screw up the events under us.
+ *
+ * If we somehow ended up ahead of the head, we got messed up.
+ *
+ * In either case, truncate and restart at head.
+ */
+ diff = head - old;
+ if (diff > md->mask / 2 || diff < 0) {
struct timeval iv;
unsigned long msecs;
timersub(&this_read, &last_read, &iv);
msecs = iv.tv_sec*1000 + iv.tv_usec/1000;
- fprintf(stderr, "WARNING: failed to keep up with mmap data. Last read %lu msecs ago.\n", msecs);
+ fprintf(stderr, "WARNING: failed to keep up with mmap data."
+ " Last read %lu msecs ago.\n", msecs);
+ /*
+ * head points to a known good entry, start there.
+ */
old = head;
}
last_read = this_read;
for (; old != head;) {
- __u64 *ptr = (__u64 *)&data[old & md->mask];
- old += sizeof(__u64);
+ struct event_struct {
+ struct perf_event_header header;
+ __u64 ip;
+ __u32 pid, tid;
+ } *event = (struct event_struct *)&data[old & md->mask];
+ struct event_struct event_copy;
+
+ unsigned int size = event->header.size;
- process_event(*ptr, md->counter);
+ /*
+ * Event straddles the mmap boundary -- header should always
+ * be inside due to u64 alignment of output.
+ */
+ if ((old & md->mask) + size != ((old + size) & md->mask)) {
+ unsigned int offset = old;
+ unsigned int len = sizeof(*event), cpy;
+ void *dst = &event_copy;
+
+ do {
+ cpy = min(md->mask + 1 - (offset & md->mask), len);
+ memcpy(dst, &data[offset & md->mask], cpy);
+ offset += cpy;
+ dst += cpy;
+ len -= cpy;
+ } while (len);
+
+ event = &event_copy;
+ }
+
+ old += size;
+
+ switch (event->header.type) {
+ case PERF_EVENT_IP:
+ case PERF_EVENT_IP | __PERF_EVENT_TID:
+ process_event(event->ip, md->counter);
+ break;
+ }
}
md->prev = old;
@@ -1214,6 +1266,7 @@ int main(int argc, char *argv[])
hw_event.irq_period = event_count[counter];
hw_event.record_type = PERF_RECORD_IRQ;
hw_event.nmi = nmi;
+ hw_event.include_tid = 1;
fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0);
if (fd[i][counter] < 0) {
--
next prev parent reply other threads:[~2009-03-25 11:39 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-25 11:30 [PATCH 0/6] perf_counter: new output ABI Peter Zijlstra
2009-03-25 11:30 ` [PATCH 1/6] perf_counter: more elaborate write API Peter Zijlstra
2009-03-25 12:06 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-25 11:30 ` [PATCH 2/6] perf_counter: output objects Peter Zijlstra
2009-03-25 12:06 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-25 11:30 ` [PATCH 3/6] perf_counter: sanity check on the output API Peter Zijlstra
2009-03-25 12:06 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-25 11:30 ` [PATCH 4/6] perf_counter: optionally provide the pid/tid of the sampled task Peter Zijlstra
2009-03-25 12:06 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-25 11:30 ` [PATCH 5/6] perf_counter: kerneltop: mmap_pages argument Peter Zijlstra
2009-03-25 12:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-25 12:18 ` [PATCH 5/6] " Ingo Molnar
2009-03-25 12:27 ` Peter Zijlstra
2009-03-25 12:35 ` Ingo Molnar
2009-03-25 12:41 ` Peter Zijlstra
2009-03-25 12:54 ` Ingo Molnar
2009-03-25 12:57 ` Peter Zijlstra
2009-03-25 14:52 ` Peter Zijlstra
2009-03-25 17:16 ` Ingo Molnar
2009-03-25 21:18 ` Peter Zijlstra
2009-03-26 2:22 ` Paul Mackerras
2009-03-25 11:30 ` Peter Zijlstra [this message]
2009-03-25 12:07 ` [tip:perfcounters/core] perf_counter: kerneltop: output event support Peter Zijlstra
2009-04-04 0:21 ` [PATCH 6/6] " Corey Ashford
2009-04-04 12:17 ` Peter Zijlstra
2009-04-04 18:10 ` Corey Ashford
2009-03-25 12:05 ` [PATCH 0/6] perf_counter: new output ABI Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090325113317.192910290@chello.nl \
--to=a.p.zijlstra@chello.nl \
--cc=arjan@infradead.org \
--cc=efault@gmx.de \
--cc=fengguang.wu@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.