From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>,
Corey Ashford <cjashfor@linux.vnet.ibm.com>,
linux-kernel@vger.kernel.org,
Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 09/15] perf_counter: counter overflow limit
Date: Mon, 06 Apr 2009 11:45:07 +0200 [thread overview]
Message-ID: <20090406094518.083139737@chello.nl> (raw)
In-Reply-To: 20090406094458.977814421@chello.nl
[-- Attachment #1: perf_counter-event_limit.patch --]
[-- Type: text/plain, Size: 4124 bytes --]
Provide means to auto-disable the counter after 'n' overflow events.
Create the counter with hw_event.disabled = 1, and then issue an
ioctl(fd, PREF_COUNTER_IOC_REFRESH, n); to set the limit and enable
the counter.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/perf_counter.h | 12 +++++++---
kernel/perf_counter.c | 51 ++++++++++++++++++++++++++++++++++---------
2 files changed, 50 insertions(+), 13 deletions(-)
Index: linux-2.6/include/linux/perf_counter.h
===================================================================
--- linux-2.6.orig/include/linux/perf_counter.h
+++ linux-2.6/include/linux/perf_counter.h
@@ -155,8 +155,9 @@ struct perf_counter_hw_event {
/*
* Ioctls that can be done on a perf counter fd:
*/
-#define PERF_COUNTER_IOC_ENABLE _IO('$', 0)
-#define PERF_COUNTER_IOC_DISABLE _IO('$', 1)
+#define PERF_COUNTER_IOC_ENABLE _IO ('$', 0)
+#define PERF_COUNTER_IOC_DISABLE _IO ('$', 1)
+#define PERF_COUNTER_IOC_REFRESH _IOW('$', 2, u32)
/*
* Structure of the page that can be mapped via mmap
@@ -403,9 +404,14 @@ struct perf_counter {
/* poll related */
wait_queue_head_t waitq;
struct fasync_struct *fasync;
- /* optional: for NMIs */
+
+ /* delayed work for NMIs and such */
+ int pending_wakeup;
+ int pending_disable;
struct perf_pending_entry pending;
+ atomic_t event_limit;
+
void (*destroy)(struct perf_counter *);
struct rcu_head rcu_head;
#endif
Index: linux-2.6/kernel/perf_counter.c
===================================================================
--- linux-2.6.orig/kernel/perf_counter.c
+++ linux-2.6/kernel/perf_counter.c
@@ -744,6 +744,12 @@ static void perf_counter_enable(struct p
spin_unlock_irq(&ctx->lock);
}
+static void perf_counter_refresh(struct perf_counter *counter, int refresh)
+{
+ atomic_add(refresh, &counter->event_limit);
+ perf_counter_enable(counter);
+}
+
/*
* Enable a counter and all its children.
*/
@@ -1311,6 +1317,9 @@ static long perf_ioctl(struct file *file
case PERF_COUNTER_IOC_DISABLE:
perf_counter_disable_family(counter);
break;
+ case PERF_COUNTER_IOC_REFRESH:
+ perf_counter_refresh(counter, arg);
+ break;
default:
err = -ENOTTY;
}
@@ -1590,14 +1599,6 @@ void perf_counter_wakeup(struct perf_cou
kill_fasync(&counter->fasync, SIGIO, POLL_IN);
}
-static void perf_pending_wakeup(struct perf_pending_entry *entry)
-{
- struct perf_counter *counter = container_of(entry,
- struct perf_counter, pending);
-
- perf_counter_wakeup(counter);
-}
-
/*
* Pending wakeups
*
@@ -1607,6 +1608,22 @@ static void perf_pending_wakeup(struct p
* single linked list and use cmpxchg() to add entries lockless.
*/
+static void perf_pending_counter(struct perf_pending_entry *entry)
+{
+ struct perf_counter *counter = container_of(entry,
+ struct perf_counter, pending);
+
+ if (counter->pending_disable) {
+ counter->pending_disable = 0;
+ perf_counter_disable(counter);
+ }
+
+ if (counter->pending_wakeup) {
+ counter->pending_wakeup = 0;
+ perf_counter_wakeup(counter);
+ }
+}
+
#define PENDING_TAIL ((struct perf_pending_entry *)-1UL)
static DEFINE_PER_CPU(struct perf_pending_entry *, perf_pending_head) = {
@@ -1715,8 +1732,9 @@ struct perf_output_handle {
static inline void __perf_output_wakeup(struct perf_output_handle *handle)
{
if (handle->nmi) {
+ handle->counter->pending_wakeup = 1;
perf_pending_queue(&handle->counter->pending,
- perf_pending_wakeup);
+ perf_pending_counter);
} else
perf_counter_wakeup(handle->counter);
}
@@ -2063,8 +2081,21 @@ void perf_counter_munmap(unsigned long a
int perf_counter_overflow(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
{
+ int events = atomic_read(&counter->event_limit);
+ int ret = 0;
+
+ if (events && atomic_dec_and_test(&counter->event_limit)) {
+ ret = 1;
+ if (nmi) {
+ counter->pending_disable = 1;
+ perf_pending_queue(&counter->pending,
+ perf_pending_counter);
+ } else
+ perf_counter_disable(counter);
+ }
+
perf_counter_output(counter, nmi, regs);
- return 0;
+ return ret;
}
/*
--
next prev parent reply other threads:[~2009-04-06 9:49 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-06 9:44 [PATCH 00/15] various perf counter bits Peter Zijlstra
2009-04-06 9:44 ` [PATCH 01/15] perf_counter: update mmap() counter read, take 2 Peter Zijlstra
2009-04-07 9:06 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 02/15] perf_counter: add more context information Peter Zijlstra
2009-04-07 9:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 03/15] perf_counter: SIGIO support Peter Zijlstra
2009-04-07 9:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 04/15] perf_counter: generalize pending infrastructure Peter Zijlstra
2009-04-07 9:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 05/15] perf_counter: x86: self-IPI for pending work Peter Zijlstra
2009-04-07 9:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 06/15] perf_counter: theres more to overflow than writing events Peter Zijlstra
2009-04-07 9:07 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 07/15] perf_counter: fix the mlock accounting Peter Zijlstra
2009-04-07 9:08 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 08/15] perf_counter: PERF_RECORD_TIME Peter Zijlstra
2009-04-07 9:08 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` Peter Zijlstra [this message]
2009-04-07 9:08 ` [tip:perfcounters/core] perf_counter: counter overflow limit Peter Zijlstra
2009-04-06 9:45 ` [PATCH 10/15] perf_counter: comment the perf_event_type stuff Peter Zijlstra
2009-04-07 9:08 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 11/15] perf_counter: change event defenition Peter Zijlstra
2009-04-07 9:08 ` [tip:perfcounters/core] perf_counter: change event definition Peter Zijlstra
2009-04-06 9:45 ` [PATCH 12/15] perf_counter: rework context time Peter Zijlstra
2009-04-07 9:09 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 13/15] perf_counter: rework the task clock software counter Peter Zijlstra
2009-04-07 9:09 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-07 9:36 ` [tip:perfcounters/core] x86, perfcounters: add atomic64_xchg() Ingo Molnar
2009-04-07 11:19 ` Paul Mackerras
2009-04-07 13:28 ` Ingo Molnar
2009-04-07 10:06 ` Ingo Molnar
2009-04-06 9:45 ` [PATCH 14/15] perf_counter: remove rq->lock usage Peter Zijlstra
2009-04-07 9:09 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-06 9:45 ` [PATCH 15/15] perf_counter: minimize context time updates Peter Zijlstra
2009-04-07 9:09 ` [tip:perfcounters/core] " Peter Zijlstra
2009-04-07 9:21 ` [PATCH 00/15] various perf counter bits Ingo Molnar
2009-04-07 9:21 ` Ingo Molnar
2009-04-07 9:33 ` Ingo Molnar
2009-04-07 9:23 ` 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=20090406094518.083139737@chello.nl \
--to=a.p.zijlstra@chello.nl \
--cc=cjashfor@linux.vnet.ibm.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.