All of lore.kernel.org
 help / color / mirror / Atom feed
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;
 }
 
 /*

-- 


  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.