All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/20] perf: Finish sampling commands when events are closed
@ 2014-08-11  8:49 Jiri Olsa
  2014-08-11  8:49 ` [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task Jiri Olsa
                   ` (20 more replies)
  0 siblings, 21 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Adrian Hunter, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra, Jiri Olsa

hi,
adding support to quit sampling commands:
  record,top,trace,kvm stat live

when all the monitored events are closed, like following perf
command will now exit when monitored process (pid 1234) exits:

  $ perf record -p 1234

I added independent poller object to handle basic polling
tasks. I had to factor some parts, so sending this as RFC,
because I'm pretty sure I broke something else ;-)

The patch#1 is kernel change, which is needed for the
patchset to work properly. The current behavior stays
without this kernel change.

The code is based on latest Arnaldo's perf/core and
following kernel change:
  http://marc.info/?l=linux-kernel&m=140715910417130&w=2

The patchset is also reachable in here:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/core_poll

thanks for comments,
jirka


Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
Jiri Olsa (20):
      perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
      perf tools: Add poller object to handle polling globaly
      perf tests: Add poller object test
      perf tools: Add support to traverse xyarrays
      perf tools: Introduce perf_evsel__fd function
      perf tools: Add evlist/evsel poller object support
      perf record: Add support to see event's ERR and HUP poll errors
      perf tools: Add set_term_quiet_input helper function
      perf tui browser: Add interface to terminate browser from uotside
      perf top: Add support to see event's ERR and HUP poll errors
      perf top: Join the display thread on exit
      perf top: Use set_term_quiet_input for terminal input
      perf top: Setup signals for terminal output
      perf top: Use poller object for display thread stdin
      perf kvm: Fix stdin handling for 'kvm stat live' command
      perf kvm: Add support to see event's ERR and HUP poll errors
      perf trace: Add support to see event's ERR and HUP poll errors
      perf python: Use poller object for polling
      perf tests: Use poller object for polling
      perf tools: Remove pollfd stuff out of evlist object

 include/linux/perf_event.h                |   1 +
 kernel/events/core.c                      |  12 ++++-
 tools/perf/Makefile.perf                  |   4 ++
 tools/perf/builtin-kvm.c                  | 123 +++++++++++++++++++++++------------------------
 tools/perf/builtin-record.c               |  29 ++++++++++-
 tools/perf/builtin-report.c               |   3 +-
 tools/perf/builtin-top.c                  | 104 ++++++++++++++++++++++++++--------------
 tools/perf/builtin-trace.c                |  25 +++++++++-
 tools/perf/tests/builtin-test.c           |   8 ++++
 tools/perf/tests/open-syscall-tp-fields.c |   9 +++-
 tools/perf/tests/perf-record.c            |   4 --
 tools/perf/tests/poller.c                 | 126 ++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/task-exit.c              |   9 +++-
 tools/perf/tests/tests.h                  |   2 +
 tools/perf/tests/xyarray.c                |  33 +++++++++++++
 tools/perf/ui/browser.c                   |   4 +-
 tools/perf/ui/browser.h                   |   8 +++-
 tools/perf/ui/browsers/annotate.c         |   2 +-
 tools/perf/ui/browsers/header.c           |   2 +-
 tools/perf/ui/browsers/hists.c            |  39 ++++++++-------
 tools/perf/ui/browsers/map.c              |   2 +-
 tools/perf/ui/browsers/scripts.c          |   2 +-
 tools/perf/ui/keysyms.h                   |   1 +
 tools/perf/ui/tui/util.c                  |   2 +-
 tools/perf/util/evlist.c                  |  38 ++++++---------
 tools/perf/util/evlist.h                  |   7 ++-
 tools/perf/util/evsel.c                   |  21 +++++++-
 tools/perf/util/evsel.h                   |  10 ++++
 tools/perf/util/hist.h                    |   6 ++-
 tools/perf/util/kvm-stat.h                |   1 -
 tools/perf/util/poller.c                  | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/poller.h                  |  88 ++++++++++++++++++++++++++++++++++
 tools/perf/util/python-ext-sources        |   2 +
 tools/perf/util/python.c                  |  19 ++++++--
 tools/perf/util/util.c                    |  13 +++++
 tools/perf/util/util.h                    |   2 +
 tools/perf/util/xyarray.c                 |   4 +-
 tools/perf/util/xyarray.h                 |   6 +++
 38 files changed, 832 insertions(+), 172 deletions(-)
 create mode 100644 tools/perf/tests/poller.c
 create mode 100644 tools/perf/tests/xyarray.c
 create mode 100644 tools/perf/util/poller.c
 create mode 100644 tools/perf/util/poller.h

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
@ 2014-08-11  8:49 ` Jiri Olsa
  2014-08-11 12:01   ` Peter Zijlstra
  2014-08-11  8:49 ` [PATCH 02/20] perf tools: Add poller object to handle polling globaly Jiri Olsa
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding new perf event state to indicate that the monitored
task has exited.  In this case the event stays alive until
the owner task exits or close the event fd while providing
the last data through the read syscall and ring buffer.

Instead it needs to propagate the error info (monitored task
has died)  via poll and read  syscalls by  returning POLLHUP
and 0 respectively.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 include/linux/perf_event.h |  1 +
 kernel/events/core.c       | 12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 707617a8c0f6..54f3a6241386 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -268,6 +268,7 @@ struct pmu {
  * enum perf_event_active_state - the states of a event
  */
 enum perf_event_active_state {
+	PERF_EVENT_STATE_EXIT		= -3,
 	PERF_EVENT_STATE_ERROR		= -2,
 	PERF_EVENT_STATE_OFF		= -1,
 	PERF_EVENT_STATE_INACTIVE	=  0,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 14086e45c5c4..dde0eefa410a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3499,7 +3499,8 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
 	 * error state (i.e. because it was pinned but it couldn't be
 	 * scheduled on to the CPU at some point).
 	 */
-	if (event->state == PERF_EVENT_STATE_ERROR)
+	if ((event->state == PERF_EVENT_STATE_ERROR) ||
+	    (event->state == PERF_EVENT_STATE_EXIT))
 		return 0;
 
 	if (count < event->read_size)
@@ -3526,9 +3527,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
 {
 	struct perf_event *event = file->private_data;
 	struct ring_buffer *rb;
-	unsigned int events = POLL_HUP;
+	unsigned int events = POLLHUP;
 
 	poll_wait(file, &event->waitq, wait);
+
+	if (event->state == PERF_EVENT_STATE_EXIT)
+		return POLLHUP;
+
 	/*
 	 * Pin the event->rb by taking event->mmap_mutex; otherwise
 	 * perf_event_set_output() can swizzle our rb and make us miss wakeups.
@@ -7484,6 +7489,9 @@ __perf_event_exit_task(struct perf_event *child_event,
 	if (child_event->parent) {
 		sync_child_event(child_event, child);
 		free_event(child_event);
+	} else {
+		child_event->state = PERF_EVENT_STATE_EXIT;
+		perf_event_wakeup(child_event);
 	}
 }
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 02/20] perf tools: Add poller object to handle polling globaly
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
  2014-08-11  8:49 ` [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task Jiri Olsa
@ 2014-08-11  8:49 ` Jiri Olsa
  2014-08-11  8:49 ` [PATCH 03/20] perf tests: Add poller object test Jiri Olsa
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding poller object to centralize polling processing and
to have independent polling object, that could gather and
process multiple file descriptors from different sources.
(like perf events, timers or standard input..)

The interface functions are documented in the poller.c and
usage is explained in the poller.h.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Makefile.perf |   2 +
 tools/perf/util/poller.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/poller.h |  88 ++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 tools/perf/util/poller.c
 create mode 100644 tools/perf/util/poller.h

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 1ea31e275b4d..3ef50d35f8bf 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -303,6 +303,7 @@ LIB_H += ui/util.h
 LIB_H += ui/ui.h
 LIB_H += util/data.h
 LIB_H += util/kvm-stat.h
+LIB_H += util/poller.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -379,6 +380,7 @@ LIB_OBJS += $(OUTPUT)util/srcline.o
 LIB_OBJS += $(OUTPUT)util/data.o
 LIB_OBJS += $(OUTPUT)util/tsc.o
 LIB_OBJS += $(OUTPUT)util/cloexec.o
+LIB_OBJS += $(OUTPUT)util/poller.o
 
 LIB_OBJS += $(OUTPUT)ui/setup.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
diff --git a/tools/perf/util/poller.c b/tools/perf/util/poller.c
new file mode 100644
index 000000000000..d6db392633d2
--- /dev/null
+++ b/tools/perf/util/poller.c
@@ -0,0 +1,233 @@
+#include <linux/bitops.h>
+#include <linux/hash.h>
+#include <linux/string.h>
+#include <asm/bug.h>
+#include <string.h>
+#include <errno.h>
+#include "perf.h"
+#include "poller.h"
+
+/**
+ * poller__init - Initialize poller object
+ * @p: poller object pointer
+ */
+void poller__init(struct poller *p)
+{
+	int i;
+
+	memset(p, 0, sizeof(*p));
+	for (i = 0; i < POLLER__HLIST_SIZE ; ++i)
+		INIT_HLIST_HEAD(&p->items[i]);
+}
+
+/**
+ * poller__cleanup - Cleanup poller object
+ * @p: poller object pointer
+ */
+void poller__cleanup(struct poller *p)
+{
+	free(p->ptr);
+}
+
+static struct poller_item *item_find(struct poller *p, int fd)
+{
+	struct hlist_head *head;
+	struct poller_item *item;
+	int hash;
+
+	hash = hash_64(fd, POLLER__HLIST_BITS);
+	head = &p->items[hash];
+
+	hlist_for_each_entry(item, head, node) {
+		if (item->fd == fd)
+			return item;
+	}
+
+	return NULL;
+}
+
+static int process_item(struct poller *p, struct poller_item *item,
+			short revents)
+{
+	poller_cb cb = NULL;
+
+#define OP(__name) ({item->ops.__name ?: p->ops.__name; })
+	if (revents & POLLIN)
+		cb = OP(data);
+	if (revents & POLLERR)
+		cb = OP(error);
+	if (revents & POLLHUP)
+		cb = OP(hup);
+#undef OP
+	return cb ? cb(p, item) : 0;
+}
+
+static int process(struct poller *p, int nret)
+{
+	struct pollfd *pfd, *pfd_base;
+	int n = p->n;
+	int i, ret = 0;
+
+	/*
+	 * We allow to call poller__del from poll callbacks,
+	 * we we need to duplicate pollfd table to be sure
+	 * it's still there.
+	 */
+	pfd = pfd_base = memdup(p->ptr, p->n * sizeof(struct pollfd));
+	if (!pfd)
+		return -ENOMEM;
+
+	for (i = 0; (i < n) && nret; pfd++, i++) {
+		struct poller_item *item;
+
+		if (!pfd->revents)
+			continue;
+
+		ret = -EINVAL;
+
+		item = item_find(p, pfd->fd);
+		if (WARN(!item, "poller: unknown fd found"))
+			goto err;
+
+		ret = process_item(p, item, pfd->revents);
+		if (ret)
+			goto err;
+
+		nret--;
+	}
+
+err:
+	free(pfd_base);
+	return ret;
+}
+
+/**
+ * poller__poll - poll installed descriptors
+ * @p:       poller object pointer
+ * @timeout: poll timeout (same as for poll syscall)
+ *
+ * This will poll  on installed  descriptors  and  run installed
+ * callbacks in case there's an activity. If there's no activity
+ * it will sleep for @timeout milliseconds.
+ *
+ * On success returns number of descriptors processed.
+ * On error returns poll(3) error or failed callback
+ * error.
+ *
+ * Note first failed callback will stop processing
+ */
+int poller__poll(struct poller *p, int timeout)
+{
+	int ret, err;
+
+	ret = poll(p->ptr, p->n, timeout);
+	if (ret < 0 || !ret)
+		return ret;
+
+	err = process(p, ret);
+	return err ?: ret;
+}
+
+static struct pollfd *get_pfd(struct poller *p)
+{
+	struct pollfd *ptr = p->ptr;
+
+	if (p->n + 1 < p->n_alloc)
+		goto out;
+
+	ptr = realloc(ptr, (p->n + 1) * sizeof(*ptr));
+	if (!ptr)
+		return NULL;
+
+	p->n_alloc++;
+	p->ptr = ptr;
+out:
+	return ptr + p->n++;
+}
+
+static void put_pfd(struct poller *p, int fd)
+{
+	struct pollfd *pfd = p->ptr;
+	int i;
+
+	for (i = 0; i < p->n; pfd++, i++) {
+		if (pfd->fd == fd)
+			break;
+	}
+
+	if (WARN(i == p->n, "poller: fd not found"))
+		return;
+
+	p->n--;
+	*pfd = *(p->ptr + p->n);
+}
+
+/**
+ * poller__add - add file descriptor to poller object
+ * @p:    poller object pointer
+ * @item: file descriptor poller-item object pointer
+ *
+ * This will install file descriptor poller-item object
+ * pointer into  poller object. It will be processed in
+ * the poller__poll call.
+ *
+ * On success returns 0.
+ * On error returns value <0 indicating the error.
+ */
+int poller__add(struct poller *p, struct poller_item *item)
+{
+	struct pollfd *pfd;
+	int hash;
+
+	if (item_find(p, item->fd))
+		return -EINVAL;
+
+	pfd = get_pfd(p);
+	if (!pfd)
+		return -ENOMEM;
+
+	pfd->fd     = item->fd;
+	pfd->events = POLLIN|POLLERR|POLLHUP;
+
+	hash = hash_64(item->fd, POLLER__HLIST_BITS);
+	hlist_add_head(&item->node, &p->items[hash]);
+	return 0;
+}
+
+/**
+ * poller__del - remove file descriptor from poller object
+ * @p:    poller object pointer
+ * @item: file descriptor poller-item object pointer
+ *
+ * This will remove file descriptor poller-item object
+ * pointer from poller object.
+ */
+void poller__del(struct poller *p, struct poller_item *item)
+{
+	put_pfd(p, item->fd);
+	hlist_del_init(&item->node);
+}
+
+/**
+ * poller__set_ops - set poller object operations
+ * @p:   poller object pointer
+ * @ops: new operations
+ *
+ * This will remove file descriptor poller-item object
+ * pointer from poller object.
+ */
+void poller__set_ops(struct poller *p, struct poller_ops *ops)
+{
+	p->ops = *ops;
+}
+
+/**
+ * poller__empty - Check poller object emptiness
+ * @p:    poller object pointer
+ *
+ * Returns true if poller object is empty, false otherwise.
+ */
+bool poller__empty(struct poller *p)
+{
+	return p->n == 0;
+}
diff --git a/tools/perf/util/poller.h b/tools/perf/util/poller.h
new file mode 100644
index 000000000000..36b6f15d7538
--- /dev/null
+++ b/tools/perf/util/poller.h
@@ -0,0 +1,88 @@
+#ifndef __PERF_POLLER
+#define __PERF_POLLER
+
+/*
+ * The interface functions are documented in the poller.c.
+ *
+ * Basically user has 'struct poller poller' object and
+ * initialize it by calling:
+ *
+ *   poller__init(&poller);
+ *
+ * For each file descriptor define 'struct poller_item'
+ * object like:
+ *
+ *   struct poller_item p = {
+ *     .fd   = fd,              -> monitored fd
+ *     .data = ...              -> user data
+ *     .ops  = {                -> callbacks (optional)
+ *       data   = data_cb,      -> data  callback called for POLLIN event
+ *       error  = error_cb,     -> error callback called for POLLERR event
+ *       hup    = hup_cb,       -> hup   callback called for POLLHUP event
+ *     },
+ *   }
+ *
+ *  Any defined 'struct poller_item' object could be then added
+ *  (or removed) into poller object by:
+ *
+ *    poller__add(&poller, &p);
+ *    poller__del(&poller, &p);
+ *
+ *  Each added object gets processed by poller__poll:
+ *
+ *    poller__poll(&poller, -1);
+ *
+ *  which calls poll(3) on installed (added) descriptors
+ *  and calls callbacks for specific descriptors.
+ *
+ *  Note it's possible to call poller__add/del within
+ *  the callback function.
+ *
+ *  If 'struct poller_item::ops' stays undefined, the
+ *  'struct poller:ops' is checked and used instead.
+ *
+ *  To cleanup poller's object at the end call:
+ *
+ *     poller__cleanup(struct poller *p);
+ */
+
+#include <poll.h>
+#include <linux/list.h>
+
+#define POLLER__HLIST_BITS 8
+#define POLLER__HLIST_SIZE (1 << POLLER__HLIST_BITS)
+
+struct poller_item;
+struct poller;
+
+typedef int (*poller_cb)(struct poller *p, struct poller_item *item);
+
+struct poller_ops {
+	poller_cb data;
+	poller_cb error;
+	poller_cb hup;
+};
+
+struct poller_item {
+	int			 fd;
+	struct hlist_node	 node;
+	struct poller_ops	 ops;
+	void			 *data;
+};
+
+struct poller {
+	int			 n;
+	int			 n_alloc;
+	struct pollfd		*ptr;
+	struct poller_ops	 ops;
+	struct hlist_head	 items[POLLER__HLIST_SIZE];
+};
+
+void poller__init(struct poller *p);
+void poller__cleanup(struct poller *p);
+int poller__poll(struct poller *p, int timeout);
+int poller__add(struct poller *p, struct poller_item *item);
+void poller__del(struct poller *p, struct poller_item *item);
+void poller__set_ops(struct poller *p, struct poller_ops *ops);
+bool poller__empty(struct poller *p);
+#endif /* __PERF_POLLER */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 03/20] perf tests: Add poller object test
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
  2014-08-11  8:49 ` [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task Jiri Olsa
  2014-08-11  8:49 ` [PATCH 02/20] perf tools: Add poller object to handle polling globaly Jiri Olsa
@ 2014-08-11  8:49 ` Jiri Olsa
  2014-08-11  8:49 ` [PATCH 04/20] perf tools: Add support to traverse xyarrays Jiri Olsa
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding some basic automated tests for poller object.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Makefile.perf        |   1 +
 tools/perf/tests/builtin-test.c |   4 ++
 tools/perf/tests/poller.c       | 126 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |   1 +
 4 files changed, 132 insertions(+)
 create mode 100644 tools/perf/tests/poller.c

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 3ef50d35f8bf..69d90285a994 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -427,6 +427,7 @@ endif
 endif
 LIB_OBJS += $(OUTPUT)tests/mmap-thread-lookup.o
 LIB_OBJS += $(OUTPUT)tests/thread-mg-share.o
+LIB_OBJS += $(OUTPUT)tests/poller.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 6f8b01bc6033..e2e3827ebd17 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -154,6 +154,10 @@ static struct test {
 		.func = test__hists_cumulate,
 	},
 	{
+		.desc = "Test poller",
+		.func = test__poller,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/poller.c b/tools/perf/tests/poller.c
new file mode 100644
index 000000000000..11a7f1310172
--- /dev/null
+++ b/tools/perf/tests/poller.c
@@ -0,0 +1,126 @@
+#include <linux/compiler.h>
+#include <unistd.h>
+#include "tests.h"
+#include "poller.h"
+#include "debug.h"
+
+static int reader_hup_cnt;
+static int reader_data_cnt;
+static int writer_error_cnt;
+static int wrong_cnt;
+
+static int reader_hup_cb(struct poller *p __maybe_unused,
+			 struct poller_item *item __maybe_unused)
+{
+	pr_debug("got reader_hup_cb\n");
+	reader_hup_cnt++;
+	return 0;
+}
+
+static int reader_data_cb(struct poller *p __maybe_unused,
+			  struct poller_item *item __maybe_unused)
+{
+	pr_debug("got reader_data_cb\n");
+	reader_data_cnt++;
+	return 0;
+}
+
+static int writer_error_cb(struct poller *p __maybe_unused,
+			   struct poller_item *item __maybe_unused)
+{
+	pr_debug("got writer_error_cb\n");
+	writer_error_cnt++;
+	return 0;
+}
+
+static int wrong_cb(struct poller *p __maybe_unused,
+		    struct poller_item *item __maybe_unused)
+{
+	pr_debug("got wrong_cb\n");
+	wrong_cnt++;
+	return 0;
+}
+
+typedef int (*pipe_test_cb)(struct poller *p, int *pipefd);
+
+static int test_hup(struct poller *poller, int *pipefd)
+{
+	/* We close the writer, we should get HUP on reader. */
+	close(pipefd[1]);
+	poller__poll(poller, -1);
+
+	TEST_ASSERT_VAL("failed to get read hup", reader_hup_cnt == 1);
+	TEST_ASSERT_VAL("failed, got wrong cnt", !wrong_cnt);
+	return 0;
+}
+
+static int test_error(struct poller *poller, int *pipefd)
+{
+	/* We close the reader, we should get ERROR on writer. */
+	close(pipefd[0]);
+	poller__poll(poller, -1);
+
+	TEST_ASSERT_VAL("failed to get write error", writer_error_cnt == 1);
+	TEST_ASSERT_VAL("failed, got wrong cnt", !wrong_cnt);
+	return 0;
+}
+
+static int test_data(struct poller *poller, int *pipefd)
+{
+	int data = 1;
+
+	/* Writing data into writer, we should get data IN on reader. */
+	TEST_ASSERT_VAL("failed to write data",
+		write(pipefd[1], &data, sizeof(data)) == sizeof(data));
+
+	poller__poll(poller, -1);
+
+	TEST_ASSERT_VAL("failed to get reader data", reader_data_cnt == 1);
+	TEST_ASSERT_VAL("failed, got wrong cnt", !wrong_cnt);
+	return 0;
+}
+
+static int test_pipe(pipe_test_cb test)
+{
+	struct poller poller;
+	struct poller_item reader = {
+		.ops = {
+			.data  = reader_data_cb,
+			.error = wrong_cb,
+			.hup   = reader_hup_cb,
+		},
+	};
+	struct poller_item writer = {
+		.ops = {
+			.data  = wrong_cb,
+			.error = writer_error_cb,
+			.hup   = wrong_cb,
+		},
+	};
+	int pipefd[2], err;
+
+	TEST_ASSERT_VAL("failed to create pipe", !pipe(pipefd));
+
+	poller__init(&poller);
+
+	reader.fd = pipefd[0];
+	TEST_ASSERT_VAL("failed to add reader", !poller__add(&poller, &reader));
+
+	writer.fd = pipefd[1];
+	TEST_ASSERT_VAL("failed to add writer", !poller__add(&poller, &writer));
+
+	err = test(&poller, pipefd);
+
+	poller__cleanup(&poller);
+	close(pipefd[0]);
+	close(pipefd[1]);
+	return err;
+}
+
+int test__poller(void)
+{
+	TEST_ASSERT_VAL("failed to test HUP  ", !test_pipe(test_hup));
+	TEST_ASSERT_VAL("failed to test ERROR", !test_pipe(test_error));
+	TEST_ASSERT_VAL("failed to test DATA ", !test_pipe(test_data));
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index ed64790a395f..e2a76d509644 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -48,6 +48,7 @@ int test__mmap_thread_lookup(void);
 int test__thread_mg_share(void);
 int test__hists_output(void);
 int test__hists_cumulate(void);
+int test__poller(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 04/20] perf tools: Add support to traverse xyarrays
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (2 preceding siblings ...)
  2014-08-11  8:49 ` [PATCH 03/20] perf tests: Add poller object test Jiri Olsa
@ 2014-08-11  8:49 ` Jiri Olsa
  2014-08-11  8:49 ` [PATCH 05/20] perf tools: Introduce perf_evsel__fd function Jiri Olsa
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding xyarray__for_each define to allow sequentially
traverse xyarrays. It will be handy in following patch.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Makefile.perf        |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/tests/xyarray.c      | 33 +++++++++++++++++++++++++++++++++
 tools/perf/util/xyarray.c       |  4 +++-
 tools/perf/util/xyarray.h       |  6 ++++++
 6 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/tests/xyarray.c

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 69d90285a994..0b478a372494 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -428,6 +428,7 @@ endif
 LIB_OBJS += $(OUTPUT)tests/mmap-thread-lookup.o
 LIB_OBJS += $(OUTPUT)tests/thread-mg-share.o
 LIB_OBJS += $(OUTPUT)tests/poller.o
+LIB_OBJS += $(OUTPUT)tests/xyarray.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index e2e3827ebd17..2da8c86599cd 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -158,6 +158,10 @@ static struct test {
 		.func = test__poller,
 	},
 	{
+		.desc = "Test xyarray",
+		.func = test__xyarray,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index e2a76d509644..7b726578ff0d 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -49,6 +49,7 @@ int test__thread_mg_share(void);
 int test__hists_output(void);
 int test__hists_cumulate(void);
 int test__poller(void);
+int test__xyarray(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/tests/xyarray.c b/tools/perf/tests/xyarray.c
new file mode 100644
index 000000000000..e1a1d6a45106
--- /dev/null
+++ b/tools/perf/tests/xyarray.c
@@ -0,0 +1,33 @@
+#include "tests.h"
+#include "xyarray.h"
+#include "debug.h"
+
+struct krava {
+	int a;
+};
+
+#define X 100
+#define Y 100
+
+int test__xyarray(void)
+{
+	struct xyarray *a;
+	struct krava *k;
+	int x, y;
+
+	a = xyarray__new(X, Y, sizeof(struct krava));
+	TEST_ASSERT_VAL("failed to allocate xyarray", a);
+
+	for (x = 0; x < X; x++) {
+		for (y = 0; y < Y; y++) {
+			k = xyarray__entry(a, x, y);
+			k->a = x * X + y;
+		}
+	}
+
+	y = 0;
+	xyarray__for_each(a, k)
+		TEST_ASSERT_VAL("wrong array value", k->a == y++);
+
+	return 0;
+}
diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
index 22afbf6c536a..077e8240fe98 100644
--- a/tools/perf/util/xyarray.c
+++ b/tools/perf/util/xyarray.c
@@ -4,11 +4,13 @@
 struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
 {
 	size_t row_size = ylen * entry_size;
-	struct xyarray *xy = zalloc(sizeof(*xy) + xlen * row_size);
+	size_t size = xlen * row_size;
+	struct xyarray *xy = zalloc(sizeof(*xy) + size);
 
 	if (xy != NULL) {
 		xy->entry_size = entry_size;
 		xy->row_size   = row_size;
+		xy->size       = size;
 	}
 
 	return xy;
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
index c488a07275dd..e4efa075fd76 100644
--- a/tools/perf/util/xyarray.h
+++ b/tools/perf/util/xyarray.h
@@ -6,6 +6,7 @@
 struct xyarray {
 	size_t row_size;
 	size_t entry_size;
+	size_t size;
 	char contents[];
 };
 
@@ -17,4 +18,9 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
 	return &xy->contents[x * xy->row_size + y * xy->entry_size];
 }
 
+#define xyarray__for_each(array, entry)					\
+	for (entry = (void *) &array->contents[0];			\
+	     (void *) entry < ((void *) array->contents + array->size);	\
+	     entry++)
+
 #endif /* _PERF_XYARRAY_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 05/20] perf tools: Introduce perf_evsel__fd function
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (3 preceding siblings ...)
  2014-08-11  8:49 ` [PATCH 04/20] perf tools: Add support to traverse xyarrays Jiri Olsa
@ 2014-08-11  8:49 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 06/20] perf tools: Add evlist/evsel poller object support Jiri Olsa
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

I'm about to make the fd entry more complex, so adding
perf_evsel__fd helper to keep the FD macro sane.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c | 2 +-
 tools/perf/util/evsel.c  | 2 +-
 tools/perf/util/evsel.h  | 5 +++++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3b366c085021..4e0f0670b655 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -25,7 +25,7 @@
 #include <linux/bitops.h>
 #include <linux/hash.h>
 
-#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
+#define FD(e, x, y) (*perf_evsel__fd(e, x, y))
 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
 
 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0c8919decac8..1ec1a7ec1cfb 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -32,7 +32,7 @@ static struct {
 	bool cloexec;
 } perf_missing_features;
 
-#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
+#define FD(e, x, y) (*perf_evsel__fd(e, x, y))
 
 int __perf_evsel__sample_size(u64 sample_type)
 {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d7f93ce0ebc1..fe8794fa73ed 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -364,4 +364,9 @@ for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); 	\
      (_evsel) && (_evsel)->leader == (_leader);					\
      (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node))
 
+static inline int *perf_evsel__fd(struct perf_evsel *evsel, int cpu, int thread)
+{
+	return (int *) xyarray__entry(evsel->fd, cpu, thread);
+}
+
 #endif /* __PERF_EVSEL_H */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 06/20] perf tools: Add evlist/evsel poller object support
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (4 preceding siblings ...)
  2014-08-11  8:49 ` [PATCH 05/20] perf tools: Introduce perf_evsel__fd function Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 07/20] perf record: Add support to see event's ERR and HUP poll errors Jiri Olsa
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Changing perf_evsel fd (xyarray) entry to carry poller_item
object. The reason for this is to source polling data with
file descriptor, because we need them both.

Adding following helper functions to go through the event's
descriptors and initialize poller object:

  perf_evlist__set_poller
  perf_evsel__set_poller

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c | 14 ++++++++++++++
 tools/perf/util/evlist.h |  3 +++
 tools/perf/util/evsel.c  | 19 ++++++++++++++++++-
 tools/perf/util/evsel.h  |  7 ++++++-
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4e0f0670b655..a4c381c10c72 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1266,3 +1266,17 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 
 	list_splice(&move, &evlist->entries);
 }
+
+int perf_evlist__set_poller(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+	int err = -1;
+
+	evlist__for_each(evlist, evsel) {
+		err = perf_evsel__set_poller(evsel, &evlist->poller);
+		if (err)
+			break;
+	}
+
+	return err;
+}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index f5173cd63693..7d03af1ce4f7 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -45,6 +45,7 @@ struct perf_evlist {
 	struct thread_map *threads;
 	struct cpu_map	  *cpus;
 	struct perf_evsel *selected;
+	struct poller	 poller;
 };
 
 struct perf_evsel_str_handler {
@@ -196,6 +197,8 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
 void perf_evlist__to_front(struct perf_evlist *evlist,
 			   struct perf_evsel *move_evsel);
 
+int perf_evlist__set_poller(struct perf_evlist *evlist);
+
 /**
  * __evlist__for_each - iterate thru all the evsels
  * @list: list_head instance to iterate
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1ec1a7ec1cfb..580061d16e4a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -695,7 +695,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
 	int cpu, thread;
-	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
+	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(struct poller_item));
 
 	if (evsel->fd) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
@@ -2055,3 +2055,20 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 	"No CONFIG_PERF_EVENTS=y kernel support configured?\n",
 			 err, strerror(err), perf_evsel__name(evsel));
 }
+
+int perf_evsel__set_poller(struct perf_evsel *evsel, struct poller *poller)
+{
+	struct poller_item *p;
+	int err = -1;
+
+	xyarray__for_each(evsel->fd, p) {
+		if (p->fd == -1)
+			continue;
+
+		err = poller__add(poller, p);
+		if (err)
+			break;
+	}
+
+	return err;
+}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index fe8794fa73ed..4c6cd9185710 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -10,6 +10,7 @@
 #include "cgroup.h"
 #include "hist.h"
 #include "symbol.h"
+#include "poller.h"
 
 struct perf_counts_values {
 	union {
@@ -366,7 +367,11 @@ for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); 	\
 
 static inline int *perf_evsel__fd(struct perf_evsel *evsel, int cpu, int thread)
 {
-	return (int *) xyarray__entry(evsel->fd, cpu, thread);
+	struct poller_item *p;
+
+	p = xyarray__entry(evsel->fd, cpu, thread);
+	return &p->fd;
 }
 
+int perf_evsel__set_poller(struct perf_evsel *evsel, struct poller *poller);
 #endif /* __PERF_EVSEL_H */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 07/20] perf record: Add support to see event's ERR and HUP poll errors
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (5 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 06/20] perf tools: Add evlist/evsel poller object support Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 08/20] perf tools: Add set_term_quiet_input helper function Jiri Olsa
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding record command support to see when all events
are down and forcing it to stop in that case.

Like following record session will stop if the
monitored pid (1234) exits:

  $ perf record -p 1234

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-record.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ca0251e8470d..dfcc470a9b4a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -25,6 +25,7 @@
 #include "util/cpumap.h"
 #include "util/thread_map.h"
 #include "util/data.h"
+#include "util/poller.h"
 
 #include <unistd.h>
 #include <sched.h>
@@ -157,6 +158,13 @@ try_again:
 			ui__error("%s\n", msg);
 			goto out;
 		}
+
+		if (perf_evsel__set_poller(pos, &evlist->poller)) {
+			error("failed to set poller with %d (%s)\n", errno,
+				strerror(errno));
+			rc = -1;
+			goto out;
+		}
 	}
 
 	if (perf_evlist__apply_filters(evlist)) {
@@ -296,6 +304,18 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
 	child_finished = 1;
 }
 
+static int data_error(struct poller *p, struct poller_item *item)
+{
+	pr_debug("got HUP/ERROR on fd %d\n", item->fd);
+
+	poller__del(p, item);
+	if (poller__empty(p)) {
+		pr_debug("All events closed, shutting down.\n");
+		done = 1;
+	}
+	return 0;
+}
+
 static int __cmd_record(struct record *rec, int argc, const char **argv)
 {
 	int err;
@@ -308,6 +328,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	struct perf_data_file *file = &rec->file;
 	struct perf_session *session;
 	bool disabled = false;
+	struct poller *poller = &rec->evlist->poller;
+	struct poller_ops poller_ops = {
+		.error	= data_error,
+		.hup	= data_error,
+	};
 
 	rec->progname = argv[0];
 
@@ -447,6 +472,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 		perf_evlist__enable(rec->evlist);
 	}
 
+	poller__set_ops(poller, &poller_ops);
+
 	for (;;) {
 		int hits = rec->samples;
 
@@ -458,7 +485,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 		if (hits == rec->samples) {
 			if (done)
 				break;
-			err = poll(rec->evlist->pollfd, rec->evlist->nr_fds, -1);
+			err = poller__poll(poller, -1);
 			/*
 			 * Propagate error, only if there's any. Ignore positive
 			 * number of returned events and interrupt error.
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 08/20] perf tools: Add set_term_quiet_input helper function
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (6 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 07/20] perf record: Add support to see event's ERR and HUP poll errors Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-14  8:43   ` [tip:perf/core] perf tools: Introduce " tip-bot for Jiri Olsa
  2014-08-11  8:50 ` [PATCH 09/20] perf tui browser: Add interface to terminate browser from uotside Jiri Olsa
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding set_term_quiet_input helper to set the terminal
quiet. It will be used in following patches.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/util.c | 13 +++++++++++++
 tools/perf/util/util.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index b82a93cb1694..25822bdf7bbf 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -13,6 +13,7 @@
 #include <limits.h>
 #include <byteswap.h>
 #include <linux/kernel.h>
+#include <unistd.h>
 
 /*
  * XXX We need to find a better place for these things...
@@ -282,6 +283,18 @@ void get_term_dimensions(struct winsize *ws)
 	ws->ws_col = 80;
 }
 
+void set_term_quiet_input(struct termios *old)
+{
+	struct termios tc;
+
+	tcgetattr(0, old);
+	tc = *old;
+	tc.c_lflag &= ~(ICANON | ECHO);
+	tc.c_cc[VMIN] = 0;
+	tc.c_cc[VTIME] = 0;
+	tcsetattr(0, TCSANOW, &tc);
+}
+
 static void set_tracing_events_path(const char *mountpoint)
 {
 	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 03a1ea2266b8..d6a79b1fb28c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -75,6 +75,7 @@
 #include <api/fs/debugfs.h>
 #include <termios.h>
 #include <linux/bitops.h>
+#include <termios.h>
 
 extern const char *graph_line;
 extern const char *graph_dotted_line;
@@ -308,6 +309,7 @@ extern unsigned int page_size;
 extern int cacheline_size;
 
 void get_term_dimensions(struct winsize *ws);
+void set_term_quiet_input(struct termios *old);
 
 struct parse_tag {
 	char tag;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 09/20] perf tui browser: Add interface to terminate browser from uotside
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (7 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 08/20] perf tools: Add set_term_quiet_input helper function Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 10/20] perf top: Add support to see event's ERR and HUP poll errors Jiri Olsa
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Currently the TUI browser could be terminated only via keypress
'q' and interrupt. But there's another situation possible where
we want to terminate the browser from outside like when all
monitored events are closed.

Adding 'done' pointer parameter to TUI browser functions to
allow a browser loops break when '*done != 0'.

Changing top TUI browser to use top's 'done' in here.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-report.c       |  3 ++-
 tools/perf/builtin-top.c          |  3 ++-
 tools/perf/ui/browser.c           |  4 ++--
 tools/perf/ui/browser.h           |  8 +++++++-
 tools/perf/ui/browsers/annotate.c |  2 +-
 tools/perf/ui/browsers/header.c   |  2 +-
 tools/perf/ui/browsers/hists.c    | 39 ++++++++++++++++++++++-----------------
 tools/perf/ui/browsers/map.c      |  2 +-
 tools/perf/ui/browsers/scripts.c  |  2 +-
 tools/perf/ui/keysyms.h           |  1 +
 tools/perf/ui/tui/util.c          |  2 +-
 tools/perf/util/hist.h            |  6 ++++--
 12 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 041e93da13e4..a5d8c9140eba 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -400,7 +400,8 @@ static int report__browse_hists(struct report *rep)
 	case 1:
 		ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
 						    rep->min_percent,
-						    &session->header.env);
+						    &session->header.env,
+						    NULL);
 		/*
 		 * Usually "ret" is the last pressed key, and we only
 		 * care if the key notifies us to switch data file.
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4fb6f726271c..4cd56c9ddedc 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -571,7 +571,8 @@ static void *display_thread_tui(void *arg)
 		pos->hists.uid_filter_str = top->record_opts.target.uid_str;
 
 	perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
-				      &top->session->header.env);
+				      &top->session->header.env,
+				      (int *) &done);
 
 	done = 1;
 	return NULL;
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 6680fa5cb9dd..82d70c71f522 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -352,11 +352,11 @@ void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
 	browser->seek(browser, browser->top_idx, SEEK_SET);
 }
 
-int ui_browser__run(struct ui_browser *browser, int delay_secs)
+int ui_browser__run(struct ui_browser *browser, int delay_secs, int *done)
 {
 	int err, key;
 
-	while (1) {
+	while (!browser_is_done(done)) {
 		off_t offset;
 
 		pthread_mutex_lock(&ui__lock);
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 92ae72113965..9e9a4bf12f2a 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -46,7 +46,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
 		     const char *helpline, ...);
 void ui_browser__hide(struct ui_browser *browser);
 int ui_browser__refresh(struct ui_browser *browser);
-int ui_browser__run(struct ui_browser *browser, int delay_secs);
+int ui_browser__run(struct ui_browser *browser, int delay_secs, int *done);
 void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
 void ui_browser__handle_resize(struct ui_browser *browser);
 void __ui_browser__vline(struct ui_browser *browser, unsigned int column,
@@ -72,4 +72,10 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser);
 
 void ui_browser__init(void);
 void annotate_browser__init(void);
+
+static inline bool browser_is_done(int *done)
+{
+	return done ? *done != 0 : 0;
+}
+
 #endif /* _PERF_UI_BROWSER_H_ */
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index f0697a3aede0..e3271d76480d 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -681,7 +681,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
 	nd = browser->curr_hot;
 
 	while (1) {
-		key = ui_browser__run(&browser->b, delay_secs);
+		key = ui_browser__run(&browser->b, delay_secs, NULL);
 
 		if (delay_secs != 0) {
 			annotate_browser__calc_percent(browser, evsel);
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
index 89c16b988618..931be7c5e91b 100644
--- a/tools/perf/ui/browsers/header.c
+++ b/tools/perf/ui/browsers/header.c
@@ -42,7 +42,7 @@ static int list_menu__run(struct ui_browser *menu)
 		return -1;
 
 	while (1) {
-		key = ui_browser__run(menu, 0);
+		key = ui_browser__run(menu, 0, NULL);
 
 		switch (key) {
 		case K_RIGHT:
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 045c1e16ac59..bb8beb8c3ad8 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -378,9 +378,10 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
 }
 
 static int hist_browser__run(struct hist_browser *browser,
-			     struct hist_browser_timer *hbt)
+			     struct hist_browser_timer *hbt,
+			     int *done)
 {
-	int key;
+	int key = K_INIT;
 	char title[160];
 	int delay_secs = hbt ? hbt->refresh : 0;
 
@@ -393,8 +394,8 @@ static int hist_browser__run(struct hist_browser *browser,
 			     "Press '?' for help on key bindings") < 0)
 		return -1;
 
-	while (1) {
-		key = ui_browser__run(&browser->b, delay_secs);
+	while (!browser_is_done(done)) {
+		key = ui_browser__run(&browser->b, delay_secs, done);
 
 		switch (key) {
 		case K_TIMER: {
@@ -1486,7 +1487,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 				    bool left_exits,
 				    struct hist_browser_timer *hbt,
 				    float min_pcnt,
-				    struct perf_session_env *env)
+				    struct perf_session_env *env,
+				    int *done)
 {
 	struct hists *hists = &evsel->hists;
 	struct hist_browser *browser = hist_browser__new(hists);
@@ -1554,7 +1556,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 	if (symbol_conf.col_width_list_str)
 		perf_hpp__set_user_width(symbol_conf.col_width_list_str);
 
-	while (1) {
+	while (!browser_is_done(done)) {
 		const struct thread *thread = NULL;
 		const struct dso *dso = NULL;
 		int choice = 0,
@@ -1565,7 +1567,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 
 		nr_options = 0;
 
-		key = hist_browser__run(browser, hbt);
+		key = hist_browser__run(browser, hbt, done);
 
 		if (browser->he_selection != NULL) {
 			thread = hist_browser__selected_thread(browser);
@@ -1939,20 +1941,21 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
 
 static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
 				int nr_events, const char *help,
-				struct hist_browser_timer *hbt)
+				struct hist_browser_timer *hbt,
+				int *done)
 {
 	struct perf_evlist *evlist = menu->b.priv;
 	struct perf_evsel *pos;
 	const char *title = "Available samples";
 	int delay_secs = hbt ? hbt->refresh : 0;
-	int key;
+	int key = K_INIT;
 
 	if (ui_browser__show(&menu->b, title,
 			     "ESC: exit, ENTER|->: Browse histograms") < 0)
 		return -1;
 
-	while (1) {
-		key = ui_browser__run(&menu->b, delay_secs);
+	while (!browser_is_done(done)) {
+		key = ui_browser__run(&menu->b, delay_secs, done);
 
 		switch (key) {
 		case K_TIMER:
@@ -1979,7 +1982,7 @@ browse_hists:
 			key = perf_evsel__hists_browse(pos, nr_events, help,
 						       true, hbt,
 						       menu->min_pcnt,
-						       menu->env);
+						       menu->env, done);
 			ui_browser__show_title(&menu->b, title);
 			switch (key) {
 			case K_TAB:
@@ -2041,7 +2044,8 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
 					   int nr_entries, const char *help,
 					   struct hist_browser_timer *hbt,
 					   float min_pcnt,
-					   struct perf_session_env *env)
+					   struct perf_session_env *env,
+					   int *done)
 {
 	struct perf_evsel *pos;
 	struct perf_evsel_menu menu = {
@@ -2068,13 +2072,14 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
 			menu.b.width = line_len;
 	}
 
-	return perf_evsel_menu__run(&menu, nr_entries, help, hbt);
+	return perf_evsel_menu__run(&menu, nr_entries, help, hbt, done);
 }
 
 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
 				  struct hist_browser_timer *hbt,
 				  float min_pcnt,
-				  struct perf_session_env *env)
+				  struct perf_session_env *env,
+				  int *done)
 {
 	int nr_entries = evlist->nr_entries;
 
@@ -2084,7 +2089,7 @@ single_entry:
 
 		return perf_evsel__hists_browse(first, nr_entries, help,
 						false, hbt, min_pcnt,
-						env);
+						env, done);
 	}
 
 	if (symbol_conf.event_group) {
@@ -2101,5 +2106,5 @@ single_entry:
 	}
 
 	return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
-					       hbt, min_pcnt, env);
+					       hbt, min_pcnt, env, done);
 }
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index b11639f33682..f87fa61c5e91 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -78,7 +78,7 @@ static int map_browser__run(struct map_browser *browser)
 		return -1;
 
 	while (1) {
-		key = ui_browser__run(&browser->b, 0);
+		key = ui_browser__run(&browser->b, 0, NULL);
 
 		switch (key) {
 		case '/':
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 402d2bd30b09..6c23b197d6fb 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -93,7 +93,7 @@ static int script_browser__run(struct perf_script_browser *browser)
 		return -1;
 
 	while (1) {
-		key = ui_browser__run(&browser->b, 0);
+		key = ui_browser__run(&browser->b, 0, NULL);
 
 		/* We can add some special key handling here if needed */
 		break;
diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h
index 65092d576b4e..63a0c1b56761 100644
--- a/tools/perf/ui/keysyms.h
+++ b/tools/perf/ui/keysyms.h
@@ -24,5 +24,6 @@
 #define K_ERROR	 -2
 #define K_RESIZE -3
 #define K_SWITCH_INPUT_DATA -4
+#define K_INIT	 -5
 
 #endif /* _PERF_KEYSYMS_H_ */
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index bf890f72fe80..a97fd4c43079 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -32,7 +32,7 @@ static int popup_menu__run(struct ui_browser *menu)
 		return -1;
 
 	while (1) {
-		key = ui_browser__run(menu, 0);
+		key = ui_browser__run(menu, 0, NULL);
 
 		switch (key) {
 		case K_RIGHT:
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 95405a8fbd95..c452af22ea89 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -312,7 +312,8 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
 				  struct hist_browser_timer *hbt,
 				  float min_pcnt,
-				  struct perf_session_env *env);
+				  struct perf_session_env *env,
+				  int *done);
 int script_browse(const char *script_opt);
 #else
 static inline
@@ -320,7 +321,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
 				  const char *help __maybe_unused,
 				  struct hist_browser_timer *hbt __maybe_unused,
 				  float min_pcnt __maybe_unused,
-				  struct perf_session_env *env __maybe_unused)
+				  struct perf_session_env *env __maybe_unused,
+				  int *done __maybe_unused)
 {
 	return 0;
 }
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 10/20] perf top: Add support to see event's ERR and HUP poll errors
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (8 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 09/20] perf tui browser: Add interface to terminate browser from uotside Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 11/20] perf top: Join the display thread on exit Jiri Olsa
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding top command support to see when all events
are down and forcing it to stop in that case.

Like following top session will stop if the
monitored pid (1234) exits:

  $ perf top -p 1234

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-top.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4cd56c9ddedc..d0eeeb7ca5ff 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -40,6 +40,7 @@
 #include "util/xyarray.h"
 #include "util/sort.h"
 #include "util/intlist.h"
+#include "util/poller.h"
 #include "arch/common.h"
 
 #include "util/debug.h"
@@ -875,6 +876,12 @@ try_again:
 			ui__error("%s\n", msg);
 			goto out_err;
 		}
+
+		if (perf_evsel__set_poller(counter, &evlist->poller)) {
+			error("failed to set poller with %d (%s)\n", errno,
+			      strerror(errno));
+			goto out_err;
+		}
 	}
 
 	if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
@@ -906,11 +913,28 @@ static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
 	return 0;
 }
 
+static int data_error(struct poller *p, struct poller_item *item)
+{
+	pr_debug("got HUP/ERROR on fd %d\n", item->fd);
+
+	poller__del(p, item);
+	if (poller__empty(p)) {
+		pr_debug("All events closed shutting down.\n");
+		done = 1;
+	}
+	return 0;
+}
+
 static int __cmd_top(struct perf_top *top)
 {
 	struct record_opts *opts = &top->record_opts;
 	pthread_t thread;
 	int ret;
+	struct poller *poller = &top->evlist->poller;
+	struct poller_ops poller_ops = {
+		.error  = data_error,
+		.hup    = data_error,
+	};
 
 	top->session = perf_session__new(NULL, false, NULL);
 	if (top->session == NULL)
@@ -948,8 +972,10 @@ static int __cmd_top(struct perf_top *top)
         if (!target__none(&opts->target))
                 perf_evlist__enable(top->evlist);
 
+	poller__set_ops(poller, &poller_ops);
+
 	/* Wait for a minimal set of events before starting the snapshot */
-	poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
+	poller__poll(poller, 100);
 
 	perf_top__mmap_read(top);
 
@@ -976,7 +1002,7 @@ static int __cmd_top(struct perf_top *top)
 		perf_top__mmap_read(top);
 
 		if (hits == top->samples)
-			ret = poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
+			ret = poller__poll(poller, 100);
 	}
 
 	ret = 0;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 11/20] perf top: Join the display thread on exit
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (9 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 10/20] perf top: Add support to see event's ERR and HUP poll errors Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2014-08-11  8:50 ` [PATCH 12/20] perf top: Use set_term_quiet_input for terminal input Jiri Olsa
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

We create the display thread, but never join it. It gives
the display thread a chance to quit and cleanup properly.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-top.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index d0eeeb7ca5ff..eca2318b68a3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -992,7 +992,7 @@ static int __cmd_top(struct perf_top *top)
 		param.sched_priority = top->realtime_prio;
 		if (sched_setscheduler(0, SCHED_FIFO, &param)) {
 			ui__error("Could not set realtime priority.\n");
-			goto out_delete;
+			goto out_join;
 		}
 	}
 
@@ -1006,6 +1006,8 @@ static int __cmd_top(struct perf_top *top)
 	}
 
 	ret = 0;
+out_join:
+	pthread_join(thread, NULL);
 out_delete:
 	perf_session__delete(top->session);
 	top->session = NULL;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 12/20] perf top: Use set_term_quiet_input for terminal input
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (10 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 11/20] perf top: Join the display thread on exit Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 13/20] perf top: Setup signals for terminal output Jiri Olsa
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Using helper function instead of repeating the code.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-top.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index eca2318b68a3..f19321282436 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -582,20 +582,14 @@ static void *display_thread_tui(void *arg)
 static void *display_thread(void *arg)
 {
 	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
-	struct termios tc, save;
+	struct termios save;
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
-	tcgetattr(0, &save);
-	tc = save;
-	tc.c_lflag &= ~(ICANON | ECHO);
-	tc.c_cc[VMIN] = 0;
-	tc.c_cc[VTIME] = 0;
-
 	pthread__unblock_sigwinch();
 repeat:
 	delay_msecs = top->delay_secs * 1000;
-	tcsetattr(0, TCSANOW, &tc);
+	set_term_quiet_input(&save);
 	/* trash return*/
 	getc(stdin);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 13/20] perf top: Setup signals for terminal output
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (11 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 12/20] perf top: Use set_term_quiet_input for terminal input Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2014-08-11  8:50 ` [PATCH 14/20] perf top: Use poller object for display thread stdin Jiri Olsa
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

The TUI code setup standard signals handling, while the stdio
display code does not. This leads to premature termination of
display thread when signal is received and leaving terminal in
wrong state.

Also adding terminal cleanup at the end of display thread,
to ensure we get the old terminal state in case of signal
interruption.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-top.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f19321282436..9b4edf0bd49f 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -579,6 +579,20 @@ static void *display_thread_tui(void *arg)
 	return NULL;
 }
 
+static void display_sig(int sig __maybe_unused)
+{
+	done = 1;
+}
+
+static void display_setup_sig(void)
+{
+	signal(SIGSEGV, display_sig);
+	signal(SIGFPE,  display_sig);
+	signal(SIGINT,  display_sig);
+	signal(SIGQUIT, display_sig);
+	signal(SIGTERM, display_sig);
+}
+
 static void *display_thread(void *arg)
 {
 	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -586,6 +600,7 @@ static void *display_thread(void *arg)
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
+	display_setup_sig();
 	pthread__unblock_sigwinch();
 repeat:
 	delay_msecs = top->delay_secs * 1000;
@@ -616,6 +631,7 @@ repeat:
 		}
 	}
 
+	tcsetattr(0, TCSAFLUSH, &save);
 	return NULL;
 }
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 14/20] perf top: Use poller object for display thread stdin
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (12 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 13/20] perf top: Setup signals for terminal output Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 15/20] perf kvm: Fix stdin handling for 'kvm stat live' command Jiri Olsa
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Using poller object to handle user input for stdio top.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-top.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 9b4edf0bd49f..8d0ed211fd7b 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -422,26 +422,22 @@ static int perf_top__key_mapped(struct perf_top *top, int c)
 	return 0;
 }
 
-static bool perf_top__handle_keypress(struct perf_top *top, int c)
+static bool perf_top__handle_keypress(struct perf_top *top, int c,
+				      struct poller *poller)
 {
 	bool ret = true;
 
 	if (!perf_top__key_mapped(top, c)) {
-		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
-		struct termios tc, save;
+		struct termios save;
 
 		perf_top__print_mapped_keys(top);
 		fprintf(stdout, "\nEnter selection, or unmapped key to continue: ");
 		fflush(stdout);
 
-		tcgetattr(0, &save);
-		tc = save;
-		tc.c_lflag &= ~(ICANON | ECHO);
-		tc.c_cc[VMIN] = 0;
-		tc.c_cc[VTIME] = 0;
-		tcsetattr(0, TCSANOW, &tc);
+		set_term_quiet_input(&save);
+		if (poller__poll(poller, -1) < 0)
+			return 0;
 
-		poll(&stdin_poll, 1, -1);
 		c = getc(stdin);
 
 		tcsetattr(0, TCSAFLUSH, &save);
@@ -595,11 +591,19 @@ static void display_setup_sig(void)
 
 static void *display_thread(void *arg)
 {
-	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
+	struct poller poller;
+	struct poller_item in = {
+		.fd = fileno(stdin),
+	};
 	struct termios save;
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
+	if (poller__add(&poller, &in)) {
+		done = 1;
+		return NULL;
+	}
+
 	display_setup_sig();
 	pthread__unblock_sigwinch();
 repeat:
@@ -610,23 +614,14 @@ repeat:
 
 	while (!done) {
 		perf_top__print_sym_table(top);
-		/*
-		 * Either timeout expired or we got an EINTR due to SIGWINCH,
-		 * refresh screen in both cases.
-		 */
-		switch (poll(&stdin_poll, 1, delay_msecs)) {
-		case 0:
-			continue;
-		case -1:
-			if (errno == EINTR)
-				continue;
-			/* Fall trhu */
-		default:
+
+		if (poller__poll(&poller, delay_msecs) > 0) {
 			c = getc(stdin);
 			tcsetattr(0, TCSAFLUSH, &save);
 
-			if (perf_top__handle_keypress(top, c))
+			if (perf_top__handle_keypress(top, c, &poller))
 				goto repeat;
+
 			done = 1;
 		}
 	}
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 15/20] perf kvm: Fix stdin handling for 'kvm stat live' command
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (13 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 14/20] perf top: Use poller object for display thread stdin Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2014-08-11  8:50 ` [PATCH 16/20] perf kvm: Add support to see event's ERR and HUP poll errors Jiri Olsa
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Currently the initial ~(ICANON | ECHO) terminal mode is
not set, so we dont get stdin data until we press ENTER.

Fixing this by early setting of the ~(ICANON | ECHO) mode
and leaving this mode for whole life of the command, because
canonical mode is not needed.

This fix is preparation for the poller object installation
into 'kvm stat live' command.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-kvm.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 7ccceadcd9f8..ff404750d744 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -885,15 +885,11 @@ static int fd_set_nonblock(int fd)
 	return 0;
 }
 
-static
-int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
+static int perf_kvm__handle_stdin(void)
 {
 	int c;
 
-	tcsetattr(0, TCSANOW, tc_now);
 	c = getc(stdin);
-	tcsetattr(0, TCSAFLUSH, tc_save);
-
 	if (c == 'q')
 		return 1;
 
@@ -904,7 +900,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 {
 	struct pollfd *pollfds = NULL;
 	int nr_fds, nr_stdin, ret, err = -EINVAL;
-	struct termios tc, save;
+	struct termios save;
 
 	/* live flag must be set first */
 	kvm->live = true;
@@ -919,14 +915,9 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 		goto out;
 	}
 
+	set_term_quiet_input(&save);
 	init_kvm_event_record(kvm);
 
-	tcgetattr(0, &save);
-	tc = save;
-	tc.c_lflag &= ~(ICANON | ECHO);
-	tc.c_cc[VMIN] = 0;
-	tc.c_cc[VTIME] = 0;
-
 	signal(SIGINT, sig_handler);
 	signal(SIGTERM, sig_handler);
 
@@ -972,7 +963,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 			goto out;
 
 		if (pollfds[nr_stdin].revents & POLLIN)
-			done = perf_kvm__handle_stdin(&tc, &save);
+			done = perf_kvm__handle_stdin();
 
 		if (!rc && !done)
 			err = poll(pollfds, nr_fds, 100);
@@ -989,6 +980,7 @@ out:
 	if (kvm->timerfd >= 0)
 		close(kvm->timerfd);
 
+	tcsetattr(0, TCSAFLUSH, &save);
 	free(pollfds);
 	return err;
 }
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 16/20] perf kvm: Add support to see event's ERR and HUP poll errors
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (14 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 15/20] perf kvm: Fix stdin handling for 'kvm stat live' command Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 17/20] perf trace: " Jiri Olsa
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding kvm command support to see when all events
are down and forcing it to stop in that case.

Like following kvm stat live session will stop if the
monitored pid (1234) exits:

      $ sudo perf kvm stat live -p 1234

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-kvm.c   | 111 +++++++++++++++++++++++----------------------
 tools/perf/util/kvm-stat.h |   1 -
 2 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index ff404750d744..30057b6fb44b 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -808,10 +808,10 @@ static void sig_handler(int sig __maybe_unused)
 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
 {
 	struct itimerspec new_value;
-	int rc = -1;
+	int fd;
 
-	kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
-	if (kvm->timerfd < 0) {
+	fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+	if (fd < 0) {
 		pr_err("timerfd_create failed\n");
 		goto out;
 	}
@@ -821,23 +821,24 @@ static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
 	new_value.it_interval.tv_sec = kvm->display_time;
 	new_value.it_interval.tv_nsec = 0;
 
-	if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
+	if (timerfd_settime(fd, 0, &new_value, NULL) != 0) {
 		pr_err("timerfd_settime failed: %d\n", errno);
-		close(kvm->timerfd);
-		goto out;
+		close(fd);
+		return -1;
 	}
 
-	rc = 0;
 out:
-	return rc;
+	return fd;
 }
 
-static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
+static int perf_kvm__handle_timerfd(struct poller *p __maybe_unused,
+				    struct poller_item *item)
 {
+	struct perf_kvm_stat *kvm = item->data;
 	uint64_t c;
 	int rc;
 
-	rc = read(kvm->timerfd, &c, sizeof(uint64_t));
+	rc = read(item->fd, &c, sizeof(uint64_t));
 	if (rc < 0) {
 		if (errno == EAGAIN)
 			return 0;
@@ -867,40 +868,59 @@ static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
 	return 0;
 }
 
-static int fd_set_nonblock(int fd)
+static int data_error(struct poller *p, struct poller_item *item)
 {
-	long arg = 0;
+	pr_debug("got HUP/ERROR on fd %d\n", item->fd);
 
-	arg = fcntl(fd, F_GETFL);
-	if (arg < 0) {
-		pr_err("Failed to get current flags for fd %d\n", fd);
-		return -1;
-	}
+	poller__del(p, item);
 
-	if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) {
-		pr_err("Failed to set non-block option on fd %d\n", fd);
-		return -1;
+	/*
+	 * Only 2 remains (stdin and timerfd), that mean we are
+	 * out of events, time to leave.
+	 */
+	if (p->n == 2) {
+		pr_debug("All events closed, shutting down.\n");
+		done = 1;
 	}
-
 	return 0;
 }
 
-static int perf_kvm__handle_stdin(void)
+static
+int perf_kvm__handle_stdin(struct poller *p __maybe_unused,
+			   struct poller_item *item __maybe_unused)
 {
 	int c;
 
 	c = getc(stdin);
 	if (c == 'q')
-		return 1;
+		done = 1;
 
 	return 0;
 }
 
 static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 {
-	struct pollfd *pollfds = NULL;
-	int nr_fds, nr_stdin, ret, err = -EINVAL;
+	int ret, err = -EINVAL;
 	struct termios save;
+	struct poller *poller = &kvm->evlist->poller;
+	struct poller_item input = {
+		.fd  = fileno(stdin),
+		.ops = {
+			.data = perf_kvm__handle_stdin,
+		}
+	};
+	struct poller_item timer = {
+		.data = kvm,
+		.ops  = {
+			.data = perf_kvm__handle_timerfd,
+		},
+	};
+	struct poller_ops poller_ops = {
+		.error  = data_error,
+		.hup    = data_error,
+	};
+
+	poller__set_ops(poller, &poller_ops);
 
 	/* live flag must be set first */
 	kvm->live = true;
@@ -921,31 +941,22 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 	signal(SIGINT, sig_handler);
 	signal(SIGTERM, sig_handler);
 
-	/* copy pollfds -- need to add timerfd and stdin */
-	nr_fds = kvm->evlist->nr_fds;
-	pollfds = zalloc(sizeof(struct pollfd) * (nr_fds + 2));
-	if (!pollfds) {
-		err = -ENOMEM;
+	err = perf_evlist__set_poller(kvm->evlist);
+	if (err < 0)
 		goto out;
-	}
-	memcpy(pollfds, kvm->evlist->pollfd,
-		sizeof(struct pollfd) * kvm->evlist->nr_fds);
 
-	/* add timer fd */
-	if (perf_kvm__timerfd_create(kvm) < 0) {
+	/* create timer fd */
+	timer.fd = perf_kvm__timerfd_create(kvm);
+	if (timer.fd < 0) {
 		err = -1;
 		goto out;
 	}
 
-	pollfds[nr_fds].fd = kvm->timerfd;
-	pollfds[nr_fds].events = POLLIN;
-	nr_fds++;
+	err = -1;
 
-	pollfds[nr_fds].fd = fileno(stdin);
-	pollfds[nr_fds].events = POLLIN;
-	nr_stdin = nr_fds;
-	nr_fds++;
-	if (fd_set_nonblock(fileno(stdin)) != 0)
+	/* add stdin and timer into poller */
+	if (poller__add(poller, &timer) ||
+	    poller__add(poller, &input))
 		goto out;
 
 	/* everything is good - enable the events and process */
@@ -958,15 +969,8 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 		if (rc < 0)
 			break;
 
-		err = perf_kvm__handle_timerfd(kvm);
-		if (err)
-			goto out;
-
-		if (pollfds[nr_stdin].revents & POLLIN)
-			done = perf_kvm__handle_stdin();
-
 		if (!rc && !done)
-			err = poll(pollfds, nr_fds, 100);
+			err = poller__poll(poller, 100);
 	}
 
 	perf_evlist__disable(kvm->evlist);
@@ -977,11 +981,10 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 	}
 
 out:
-	if (kvm->timerfd >= 0)
-		close(kvm->timerfd);
+	if (timer.fd >= 0)
+		close(timer.fd);
 
 	tcsetattr(0, TCSAFLUSH, &save);
-	free(pollfds);
 	return err;
 }
 
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index 0b5a8cd2ee79..eb34bee83615 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -97,7 +97,6 @@ struct perf_kvm_stat {
 
 	struct rb_root result;
 
-	int timerfd;
 	unsigned int display_time;
 	bool live;
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 17/20] perf trace: Add support to see event's ERR and HUP poll errors
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (15 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 16/20] perf kvm: Add support to see event's ERR and HUP poll errors Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 18/20] perf python: Use poller object for polling Jiri Olsa
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Adding trace command support to see when all events
are down and forcing it to stop in that case.

Like following trace session will stop if the
monitored pid (1234) exits:

  $ perf trace -p 1234

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-trace.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 36ae51d61be2..d465f4519a66 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2011,6 +2011,18 @@ static int perf_evlist__add_pgfault(struct perf_evlist *evlist,
 	return 0;
 }
 
+static int data_error(struct poller *p, struct poller_item *item)
+{
+	pr_debug("got HUP/ERROR on fd %d\n", item->fd);
+
+	poller__del(p, item);
+	if (poller__empty(p)) {
+		pr_debug("All events closed, shutting down.\n");
+		done = true;
+	}
+	return 0;
+}
+
 static int trace__run(struct trace *trace, int argc, const char **argv)
 {
 	struct perf_evlist *evlist = perf_evlist__new();
@@ -2018,6 +2030,11 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	int err = -1, i;
 	unsigned long before;
 	const bool forks = argc > 0;
+	struct poller *poller = &evlist->poller;
+	struct poller_ops poller_ops = {
+		.error  = data_error,
+		.hup    = data_error,
+	};
 
 	trace->live = true;
 
@@ -2077,6 +2094,10 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	if (err < 0)
 		goto out_error_open;
 
+	err = perf_evlist__set_poller(evlist);
+	if (err < 0)
+		goto out_delete_evlist;
+
 	err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
 	if (err < 0) {
 		fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno));
@@ -2088,6 +2109,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	if (forks)
 		perf_evlist__start_workload(evlist);
 
+	poller__set_ops(poller, &poller_ops);
+
 	trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1;
 again:
 	before = trace->nr_events;
@@ -2143,7 +2166,7 @@ next_event:
 	if (trace->nr_events == before) {
 		int timeout = done ? 100 : -1;
 
-		if (poll(evlist->pollfd, evlist->nr_fds, timeout) > 0)
+		if (poller__poll(poller, timeout) > 0)
 			goto again;
 	} else {
 		goto again;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 18/20] perf python: Use poller object for polling
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (16 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 17/20] perf trace: " Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 19/20] perf tests: " Jiri Olsa
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Change python polling guts using evlist->pollfd for
poller object.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/python-ext-sources |  2 ++
 tools/perf/util/python.c           | 19 +++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 16a475a7d492..a2d584126eb1 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -20,3 +20,5 @@ util/strlist.c
 ../lib/api/fs/fs.c
 util/trace-event.c
 ../../lib/rbtree.c
+util/poller.c
+util/string.c
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 12aa9b0d0ba1..5903b6c30c16 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -7,6 +7,7 @@
 #include "event.h"
 #include "cpumap.h"
 #include "thread_map.h"
+#include "poller.h"
 
 /*
  * Support debug printing even though util/debug.c is not linked.  That means
@@ -730,13 +731,22 @@ static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
 				   PyObject *args, PyObject *kwargs)
 {
 	struct perf_evlist *evlist = &pevlist->evlist;
+	struct poller *poller = &evlist->poller;
 	static char *kwlist[] = { "timeout", NULL };
-	int timeout = -1, n;
+	int timeout = -1, n, err;
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
 		return NULL;
 
-	n = poll(evlist->pollfd, evlist->nr_fds, timeout);
+	if (poller__empty(poller)) {
+		err = perf_evlist__set_poller(evlist);
+		if (err) {
+			PyErr_SetFromErrno(PyExc_OSError);
+			return NULL;
+		}
+	}
+
+	n = poller__poll(poller, timeout);
 	if (n < 0) {
 		PyErr_SetFromErrno(PyExc_OSError);
 		return NULL;
@@ -750,12 +760,13 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
 					 PyObject *kwargs __maybe_unused)
 {
 	struct perf_evlist *evlist = &pevlist->evlist;
+	struct poller *poller = &evlist->poller;
         PyObject *list = PyList_New(0);
 	int i;
 
-	for (i = 0; i < evlist->nr_fds; ++i) {
+	for (i = 0; i < poller->n; ++i) {
 		PyObject *file;
-		FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
+		FILE *fp = fdopen(poller->ptr[i].fd, "r");
 
 		if (fp == NULL)
 			goto free_list;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 19/20] perf tests: Use poller object for polling
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (17 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 18/20] perf python: Use poller object for polling Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11  8:50 ` [PATCH 20/20] perf tools: Remove pollfd stuff out of evlist object Jiri Olsa
  2014-08-11 20:12 ` [RFC 00/20] perf: Finish sampling commands when events are closed Arnaldo Carvalho de Melo
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

Several tests are using evlist->pollfd means for
polling events. Changing them to use poller object.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/open-syscall-tp-fields.c | 9 ++++++++-
 tools/perf/tests/perf-record.c            | 4 ----
 tools/perf/tests/task-exit.c              | 9 ++++++++-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 0785b64ffd6c..b0fc35d23244 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -4,6 +4,7 @@
 #include "thread_map.h"
 #include "tests.h"
 #include "debug.h"
+#include "poller.h"
 
 int test__syscall_open_tp_fields(void)
 {
@@ -58,6 +59,12 @@ int test__syscall_open_tp_fields(void)
 		goto out_delete_evlist;
 	}
 
+	err = perf_evlist__set_poller(evlist);
+	if (err < 0) {
+		pr_debug("perf_evlist__set_poller: %s\n", strerror(errno));
+		goto out_delete_evlist;
+	};
+
 	perf_evlist__enable(evlist);
 
 	/*
@@ -102,7 +109,7 @@ int test__syscall_open_tp_fields(void)
 		}
 
 		if (nr_events == before)
-			poll(evlist->pollfd, evlist->nr_fds, 10);
+			poller__poll(&evlist->poller, 10);
 
 		if (++nr_polls > 5) {
 			pr_debug("%s: no events!\n", __func__);
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index aca1a83dd13a..ee5d2881e3fe 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -147,8 +147,6 @@ int test__PERF_RECORD(void)
 	perf_evlist__start_workload(evlist);
 
 	while (1) {
-		int before = total_events;
-
 		for (i = 0; i < evlist->nr_mmaps; i++) {
 			union perf_event *event;
 
@@ -262,8 +260,6 @@ int test__PERF_RECORD(void)
 		 * PERF_RECORD_{!SAMPLE} events don't honour
 		 * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does.
 		 */
-		if (total_events == before && false)
-			poll(evlist->pollfd, evlist->nr_fds, -1);
 
 		sleep(1);
 		if (++wakeups > 5) {
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 5ff3db318f12..bc858c799ff2 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -3,6 +3,7 @@
 #include "thread_map.h"
 #include "cpumap.h"
 #include "tests.h"
+#include "poller.h"
 
 #include <signal.h>
 
@@ -92,6 +93,12 @@ int test__task_exit(void)
 		goto out_delete_evlist;
 	}
 
+	if (perf_evlist__set_poller(evlist)) {
+		pr_debug("failed to set poller: %d (%s)\n", errno,
+			 strerror(errno));
+		goto out_delete_evlist;
+	}
+
 	perf_evlist__start_workload(evlist);
 
 retry:
@@ -103,7 +110,7 @@ retry:
 	}
 
 	if (!exited || !nr_exit) {
-		poll(evlist->pollfd, evlist->nr_fds, -1);
+		poller__poll(&evlist->poller, -1);
 		goto retry;
 	}
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 20/20] perf tools: Remove pollfd stuff out of evlist object
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (18 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 19/20] perf tests: " Jiri Olsa
@ 2014-08-11  8:50 ` Jiri Olsa
  2014-08-11 20:12 ` [RFC 00/20] perf: Finish sampling commands when events are closed Arnaldo Carvalho de Melo
  20 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11  8:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras, Peter Zijlstra

There's no need for evlist->pollfd data anymore.
All the perf events polling job is now done poller
object.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c | 22 ----------------------
 tools/perf/util/evlist.h |  4 ----
 2 files changed, 26 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a4c381c10c72..3cd5b711b762 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -102,7 +102,6 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
 void perf_evlist__exit(struct perf_evlist *evlist)
 {
 	zfree(&evlist->mmap);
-	zfree(&evlist->pollfd);
 }
 
 void perf_evlist__delete(struct perf_evlist *evlist)
@@ -339,23 +338,6 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
 	return 0;
 }
 
-static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
-{
-	int nr_cpus = cpu_map__nr(evlist->cpus);
-	int nr_threads = thread_map__nr(evlist->threads);
-	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
-	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
-	return evlist->pollfd != NULL ? 0 : -ENOMEM;
-}
-
-void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
-{
-	fcntl(fd, F_SETFL, O_NONBLOCK);
-	evlist->pollfd[evlist->nr_fds].fd = fd;
-	evlist->pollfd[evlist->nr_fds].events = POLLIN;
-	evlist->nr_fds++;
-}
-
 static void perf_evlist__id_hash(struct perf_evlist *evlist,
 				 struct perf_evsel *evsel,
 				 int cpu, int thread, u64 id)
@@ -625,7 +607,6 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
 		return -1;
 	}
 
-	perf_evlist__add_pollfd(evlist, fd);
 	return 0;
 }
 
@@ -804,9 +785,6 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
 		return -ENOMEM;
 
-	if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
-		return -ENOMEM;
-
 	evlist->overwrite = overwrite;
 	evlist->mmap_len = perf_evlist__mmap_size(pages);
 	pr_debug("mmap size %zuB\n", evlist->mmap_len);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 7d03af1ce4f7..d9a55e79f8bb 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -9,7 +9,6 @@
 #include "util.h"
 #include <unistd.h>
 
-struct pollfd;
 struct thread_map;
 struct cpu_map;
 struct record_opts;
@@ -41,7 +40,6 @@ struct perf_evlist {
 	} workload;
 	bool		 overwrite;
 	struct perf_mmap *mmap;
-	struct pollfd	 *pollfd;
 	struct thread_map *threads;
 	struct cpu_map	  *cpus;
 	struct perf_evsel *selected;
@@ -83,8 +81,6 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
 			 int cpu, int thread, u64 id);
 
-void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
-
 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
 
 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
  2014-08-11  8:49 ` [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task Jiri Olsa
@ 2014-08-11 12:01   ` Peter Zijlstra
  2014-08-11 12:22     ` Jiri Olsa
                       ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Peter Zijlstra @ 2014-08-11 12:01 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras

[-- Attachment #1: Type: text/plain, Size: 2402 bytes --]

On Mon, Aug 11, 2014 at 10:49:55AM +0200, Jiri Olsa wrote:
> ---
>  include/linux/perf_event.h |  1 +
>  kernel/events/core.c       | 12 ++++++++++--
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 707617a8c0f6..54f3a6241386 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -268,6 +268,7 @@ struct pmu {
>   * enum perf_event_active_state - the states of a event
>   */
>  enum perf_event_active_state {
> +	PERF_EVENT_STATE_EXIT		= -3,
>  	PERF_EVENT_STATE_ERROR		= -2,
>  	PERF_EVENT_STATE_OFF		= -1,
>  	PERF_EVENT_STATE_INACTIVE	=  0,
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 14086e45c5c4..dde0eefa410a 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -3499,7 +3499,8 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
>  	 * error state (i.e. because it was pinned but it couldn't be
>  	 * scheduled on to the CPU at some point).
>  	 */
> -	if (event->state == PERF_EVENT_STATE_ERROR)
> +	if ((event->state == PERF_EVENT_STATE_ERROR) ||
> +	    (event->state == PERF_EVENT_STATE_EXIT))
>  		return 0;
>  
>  	if (count < event->read_size)
> @@ -3526,9 +3527,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
>  {
>  	struct perf_event *event = file->private_data;
>  	struct ring_buffer *rb;
> -	unsigned int events = POLL_HUP;
> +	unsigned int events = POLLHUP;

Should not that be an independent bugfix? It is a silly little thing
indeed, but it does change behaviour.

>  	poll_wait(file, &event->waitq, wait);
> +
> +	if (event->state == PERF_EVENT_STATE_EXIT)
> +		return POLLHUP;
> +

So, seeing how events is already POLLHUP here, why not return that?

>  	/*
>  	 * Pin the event->rb by taking event->mmap_mutex; otherwise
>  	 * perf_event_set_output() can swizzle our rb and make us miss wakeups.
> @@ -7484,6 +7489,9 @@ __perf_event_exit_task(struct perf_event *child_event,
>  	if (child_event->parent) {
>  		sync_child_event(child_event, child);
>  		free_event(child_event);
> +	} else {
> +		child_event->state = PERF_EVENT_STATE_EXIT;
> +		perf_event_wakeup(child_event);
>  	}
>  }

In any case, ACK on this patch, I'll assume you want to take the lot
through acme seeing how its mostly tools bits.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
  2014-08-11 12:01   ` Peter Zijlstra
@ 2014-08-11 12:22     ` Jiri Olsa
  2014-08-24 14:59     ` [tip:perf/core] perf: Fix perf_poll to return proper POLLHUP value tip-bot for Jiri Olsa
  2014-08-24 14:59     ` [tip:perf/core] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task tip-bot for Jiri Olsa
  2 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-11 12:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Jiri Olsa, linux-kernel, Adrian Hunter, Arnaldo Carvalho de Melo,
	Corey Ashford, David Ahern, Frederic Weisbecker, Ingo Molnar,
	Jean Pihet, Namhyung Kim, Paul Mackerras

On Mon, Aug 11, 2014 at 02:01:02PM +0200, Peter Zijlstra wrote:

SNIP

> >  	struct perf_event *event = file->private_data;
> >  	struct ring_buffer *rb;
> > -	unsigned int events = POLL_HUP;
> > +	unsigned int events = POLLHUP;
> 
> Should not that be an independent bugfix? It is a silly little thing
> indeed, but it does change behaviour.

ok, I'll send it in a separate patch plus your suggestion
below in v2

> 
> >  	poll_wait(file, &event->waitq, wait);
> > +
> > +	if (event->state == PERF_EVENT_STATE_EXIT)
> > +		return POLLHUP;
> > +
> 
> So, seeing how events is already POLLHUP here, why not return that?
> 
> >  	/*
> >  	 * Pin the event->rb by taking event->mmap_mutex; otherwise
> >  	 * perf_event_set_output() can swizzle our rb and make us miss wakeups.
> > @@ -7484,6 +7489,9 @@ __perf_event_exit_task(struct perf_event *child_event,
> >  	if (child_event->parent) {
> >  		sync_child_event(child_event, child);
> >  		free_event(child_event);
> > +	} else {
> > +		child_event->state = PERF_EVENT_STATE_EXIT;
> > +		perf_event_wakeup(child_event);
> >  	}
> >  }
> 
> In any case, ACK on this patch, I'll assume you want to take the lot
> through acme seeing how its mostly tools bits.

yep

thanks,
jirka

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC 00/20] perf: Finish sampling commands when events are closed
  2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
                   ` (19 preceding siblings ...)
  2014-08-11  8:50 ` [PATCH 20/20] perf tools: Remove pollfd stuff out of evlist object Jiri Olsa
@ 2014-08-11 20:12 ` Arnaldo Carvalho de Melo
  2014-08-11 20:28   ` Arnaldo Carvalho de Melo
  2014-08-12  7:29   ` Jiri Olsa
  20 siblings, 2 replies; 33+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-08-11 20:12 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Adrian Hunter, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Em Mon, Aug 11, 2014 at 10:49:54AM +0200, Jiri Olsa escreveu:
> hi,
> adding support to quit sampling commands:
>   record,top,trace,kvm stat live
> 
> when all the monitored events are closed, like following perf
> command will now exit when monitored process (pid 1234) exits:
> 
>   $ perf record -p 1234
> 
> I added independent poller object to handle basic polling
> tasks. I had to factor some parts, so sending this as RFC,

Why? I'm trying to figure out why this poller class is needed, just from
reading the changelog entries, no luck so far.

> because I'm pretty sure I broke something else ;-)
> 
> The patch#1 is kernel change, which is needed for the
> patchset to work properly. The current behavior stays
> without this kernel change.
> 
> The code is based on latest Arnaldo's perf/core and
> following kernel change:
>   http://marc.info/?l=linux-kernel&m=140715910417130&w=2
> 
> The patchset is also reachable in here:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
>   perf/core_poll
> 
> thanks for comments,
> jirka
> 
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Jean Pihet <jean.pihet@linaro.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> Jiri Olsa (20):
>       perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
>       perf tools: Add poller object to handle polling globaly
>       perf tests: Add poller object test
>       perf tools: Add support to traverse xyarrays
>       perf tools: Introduce perf_evsel__fd function
>       perf tools: Add evlist/evsel poller object support
>       perf record: Add support to see event's ERR and HUP poll errors
>       perf tools: Add set_term_quiet_input helper function
>       perf tui browser: Add interface to terminate browser from uotside
>       perf top: Add support to see event's ERR and HUP poll errors
>       perf top: Join the display thread on exit
>       perf top: Use set_term_quiet_input for terminal input
>       perf top: Setup signals for terminal output
>       perf top: Use poller object for display thread stdin
>       perf kvm: Fix stdin handling for 'kvm stat live' command
>       perf kvm: Add support to see event's ERR and HUP poll errors
>       perf trace: Add support to see event's ERR and HUP poll errors
>       perf python: Use poller object for polling
>       perf tests: Use poller object for polling
>       perf tools: Remove pollfd stuff out of evlist object
> 
>  include/linux/perf_event.h                |   1 +
>  kernel/events/core.c                      |  12 ++++-
>  tools/perf/Makefile.perf                  |   4 ++
>  tools/perf/builtin-kvm.c                  | 123 +++++++++++++++++++++++------------------------
>  tools/perf/builtin-record.c               |  29 ++++++++++-
>  tools/perf/builtin-report.c               |   3 +-
>  tools/perf/builtin-top.c                  | 104 ++++++++++++++++++++++++++--------------
>  tools/perf/builtin-trace.c                |  25 +++++++++-
>  tools/perf/tests/builtin-test.c           |   8 ++++
>  tools/perf/tests/open-syscall-tp-fields.c |   9 +++-
>  tools/perf/tests/perf-record.c            |   4 --
>  tools/perf/tests/poller.c                 | 126 ++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/tests/task-exit.c              |   9 +++-
>  tools/perf/tests/tests.h                  |   2 +
>  tools/perf/tests/xyarray.c                |  33 +++++++++++++
>  tools/perf/ui/browser.c                   |   4 +-
>  tools/perf/ui/browser.h                   |   8 +++-
>  tools/perf/ui/browsers/annotate.c         |   2 +-
>  tools/perf/ui/browsers/header.c           |   2 +-
>  tools/perf/ui/browsers/hists.c            |  39 ++++++++-------
>  tools/perf/ui/browsers/map.c              |   2 +-
>  tools/perf/ui/browsers/scripts.c          |   2 +-
>  tools/perf/ui/keysyms.h                   |   1 +
>  tools/perf/ui/tui/util.c                  |   2 +-
>  tools/perf/util/evlist.c                  |  38 ++++++---------
>  tools/perf/util/evlist.h                  |   7 ++-
>  tools/perf/util/evsel.c                   |  21 +++++++-
>  tools/perf/util/evsel.h                   |  10 ++++
>  tools/perf/util/hist.h                    |   6 ++-
>  tools/perf/util/kvm-stat.h                |   1 -
>  tools/perf/util/poller.c                  | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/poller.h                  |  88 ++++++++++++++++++++++++++++++++++
>  tools/perf/util/python-ext-sources        |   2 +
>  tools/perf/util/python.c                  |  19 ++++++--
>  tools/perf/util/util.c                    |  13 +++++
>  tools/perf/util/util.h                    |   2 +
>  tools/perf/util/xyarray.c                 |   4 +-
>  tools/perf/util/xyarray.h                 |   6 +++
>  38 files changed, 832 insertions(+), 172 deletions(-)
>  create mode 100644 tools/perf/tests/poller.c
>  create mode 100644 tools/perf/tests/xyarray.c
>  create mode 100644 tools/perf/util/poller.c
>  create mode 100644 tools/perf/util/poller.h

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC 00/20] perf: Finish sampling commands when events are closed
  2014-08-11 20:12 ` [RFC 00/20] perf: Finish sampling commands when events are closed Arnaldo Carvalho de Melo
@ 2014-08-11 20:28   ` Arnaldo Carvalho de Melo
  2014-08-12  7:33     ` Jiri Olsa
  2014-08-12  7:29   ` Jiri Olsa
  1 sibling, 1 reply; 33+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-08-11 20:28 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Adrian Hunter, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Em Mon, Aug 11, 2014 at 05:12:49PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Aug 11, 2014 at 10:49:54AM +0200, Jiri Olsa escreveu:
> > hi,
> > adding support to quit sampling commands:
> >   record,top,trace,kvm stat live
> > 
> > when all the monitored events are closed, like following perf
> > command will now exit when monitored process (pid 1234) exits:
> > 
> >   $ perf record -p 1234
> > 
> > I added independent poller object to handle basic polling
> > tasks. I had to factor some parts, so sending this as RFC,
> 
> Why? I'm trying to figure out why this poller class is needed, just from
> reading the changelog entries, no luck so far.

So this is all about accounting for when all events are closed? I.e. as
we receive the ERR and HUP we go on closing the entries in the pollfd?
Then, when none are closed, then we exit, is that the case?

Why not just mark them -1 and decrement evlist->nr_open_fds (new field)?

struct pollfds {
	struct pollfd *pollfds;
	int    nr_fds;
	int    nr_open_fds;
};

Don't use callbacks and then that poller_item doesn't need to exist :-\

I'll try to cook a patch with those ideas later today, if for anything,
to validate your patches :-)

- Arnaldo
 
> > because I'm pretty sure I broke something else ;-)
> > 
> > The patch#1 is kernel change, which is needed for the
> > patchset to work properly. The current behavior stays
> > without this kernel change.
> > 
> > The code is based on latest Arnaldo's perf/core and
> > following kernel change:
> >   http://marc.info/?l=linux-kernel&m=140715910417130&w=2
> > 
> > The patchset is also reachable in here:
> >   git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
> >   perf/core_poll
> > 
> > thanks for comments,
> > jirka
> > 
> > 
> > Cc: Adrian Hunter <adrian.hunter@intel.com>
> > Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> > Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Ingo Molnar <mingo@kernel.org>
> > Cc: Jean Pihet <jean.pihet@linaro.org>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > Jiri Olsa (20):
> >       perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
> >       perf tools: Add poller object to handle polling globaly
> >       perf tests: Add poller object test
> >       perf tools: Add support to traverse xyarrays
> >       perf tools: Introduce perf_evsel__fd function
> >       perf tools: Add evlist/evsel poller object support
> >       perf record: Add support to see event's ERR and HUP poll errors
> >       perf tools: Add set_term_quiet_input helper function
> >       perf tui browser: Add interface to terminate browser from uotside
> >       perf top: Add support to see event's ERR and HUP poll errors
> >       perf top: Join the display thread on exit
> >       perf top: Use set_term_quiet_input for terminal input
> >       perf top: Setup signals for terminal output
> >       perf top: Use poller object for display thread stdin
> >       perf kvm: Fix stdin handling for 'kvm stat live' command
> >       perf kvm: Add support to see event's ERR and HUP poll errors
> >       perf trace: Add support to see event's ERR and HUP poll errors
> >       perf python: Use poller object for polling
> >       perf tests: Use poller object for polling
> >       perf tools: Remove pollfd stuff out of evlist object
> > 
> >  include/linux/perf_event.h                |   1 +
> >  kernel/events/core.c                      |  12 ++++-
> >  tools/perf/Makefile.perf                  |   4 ++
> >  tools/perf/builtin-kvm.c                  | 123 +++++++++++++++++++++++------------------------
> >  tools/perf/builtin-record.c               |  29 ++++++++++-
> >  tools/perf/builtin-report.c               |   3 +-
> >  tools/perf/builtin-top.c                  | 104 ++++++++++++++++++++++++++--------------
> >  tools/perf/builtin-trace.c                |  25 +++++++++-
> >  tools/perf/tests/builtin-test.c           |   8 ++++
> >  tools/perf/tests/open-syscall-tp-fields.c |   9 +++-
> >  tools/perf/tests/perf-record.c            |   4 --
> >  tools/perf/tests/poller.c                 | 126 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/tests/task-exit.c              |   9 +++-
> >  tools/perf/tests/tests.h                  |   2 +
> >  tools/perf/tests/xyarray.c                |  33 +++++++++++++
> >  tools/perf/ui/browser.c                   |   4 +-
> >  tools/perf/ui/browser.h                   |   8 +++-
> >  tools/perf/ui/browsers/annotate.c         |   2 +-
> >  tools/perf/ui/browsers/header.c           |   2 +-
> >  tools/perf/ui/browsers/hists.c            |  39 ++++++++-------
> >  tools/perf/ui/browsers/map.c              |   2 +-
> >  tools/perf/ui/browsers/scripts.c          |   2 +-
> >  tools/perf/ui/keysyms.h                   |   1 +
> >  tools/perf/ui/tui/util.c                  |   2 +-
> >  tools/perf/util/evlist.c                  |  38 ++++++---------
> >  tools/perf/util/evlist.h                  |   7 ++-
> >  tools/perf/util/evsel.c                   |  21 +++++++-
> >  tools/perf/util/evsel.h                   |  10 ++++
> >  tools/perf/util/hist.h                    |   6 ++-
> >  tools/perf/util/kvm-stat.h                |   1 -
> >  tools/perf/util/poller.c                  | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/poller.h                  |  88 ++++++++++++++++++++++++++++++++++
> >  tools/perf/util/python-ext-sources        |   2 +
> >  tools/perf/util/python.c                  |  19 ++++++--
> >  tools/perf/util/util.c                    |  13 +++++
> >  tools/perf/util/util.h                    |   2 +
> >  tools/perf/util/xyarray.c                 |   4 +-
> >  tools/perf/util/xyarray.h                 |   6 +++
> >  38 files changed, 832 insertions(+), 172 deletions(-)
> >  create mode 100644 tools/perf/tests/poller.c
> >  create mode 100644 tools/perf/tests/xyarray.c
> >  create mode 100644 tools/perf/util/poller.c
> >  create mode 100644 tools/perf/util/poller.h

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC 00/20] perf: Finish sampling commands when events are closed
  2014-08-11 20:12 ` [RFC 00/20] perf: Finish sampling commands when events are closed Arnaldo Carvalho de Melo
  2014-08-11 20:28   ` Arnaldo Carvalho de Melo
@ 2014-08-12  7:29   ` Jiri Olsa
  1 sibling, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-12  7:29 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, linux-kernel, Adrian Hunter, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra

On Mon, Aug 11, 2014 at 05:12:49PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Aug 11, 2014 at 10:49:54AM +0200, Jiri Olsa escreveu:
> > hi,
> > adding support to quit sampling commands:
> >   record,top,trace,kvm stat live
> > 
> > when all the monitored events are closed, like following perf
> > command will now exit when monitored process (pid 1234) exits:
> > 
> >   $ perf record -p 1234
> > 
> > I added independent poller object to handle basic polling
> > tasks. I had to factor some parts, so sending this as RFC,
> 
> Why? I'm trying to figure out why this poller class is needed, just from
> reading the changelog entries, no luck so far.

multiple reasons.. at the moment:
  - have a way to get FD state notification -> callback triggers for FD
    and we can figure when we are out of monitored events or notify there
    was error/hup on event

  - to be able to gather/register more kinds of FDs under one
    poll instance, so we could poll together on standard input
    or other kind of notify event with perf events within a
    single poll call

for future:
  - there's another feature for record to watch hotplug CPUs
    and open/close perf event for it when CPU is added/removed
    we need to watch/poll inotify events for that

  - when having multiple threads for record command we'll need to split
    evlist events into more polling instances, so each thread could
    poll independently

also I think the poller class just encapsulates the polling
processing and reduces the evlist complexity

jirka

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC 00/20] perf: Finish sampling commands when events are closed
  2014-08-11 20:28   ` Arnaldo Carvalho de Melo
@ 2014-08-12  7:33     ` Jiri Olsa
  0 siblings, 0 replies; 33+ messages in thread
From: Jiri Olsa @ 2014-08-12  7:33 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, linux-kernel, Adrian Hunter, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra

On Mon, Aug 11, 2014 at 05:28:12PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Aug 11, 2014 at 05:12:49PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Aug 11, 2014 at 10:49:54AM +0200, Jiri Olsa escreveu:
> > > hi,
> > > adding support to quit sampling commands:
> > >   record,top,trace,kvm stat live
> > > 
> > > when all the monitored events are closed, like following perf
> > > command will now exit when monitored process (pid 1234) exits:
> > > 
> > >   $ perf record -p 1234
> > > 
> > > I added independent poller object to handle basic polling
> > > tasks. I had to factor some parts, so sending this as RFC,
> > 
> > Why? I'm trying to figure out why this poller class is needed, just from
> > reading the changelog entries, no luck so far.
> 
> So this is all about accounting for when all events are closed? I.e. as
> we receive the ERR and HUP we go on closing the entries in the pollfd?
> Then, when none are closed, then we exit, is that the case?
> 
> Why not just mark them -1 and decrement evlist->nr_open_fds (new field)?
> 
> struct pollfds {
> 	struct pollfd *pollfds;
> 	int    nr_fds;
> 	int    nr_open_fds;
> };
> 
> Don't use callbacks and then that poller_item doesn't need to exist :-\

I think callbacks are convenient when having different kind
of events combined in polling, as described in my reply to
your first email

> 
> I'll try to cook a patch with those ideas later today, if for anything,
> to validate your patches :-)

ok ;-) thanks

jirka

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf top: Join the display thread on exit
  2014-08-11  8:50 ` [PATCH 11/20] perf top: Join the display thread on exit Jiri Olsa
@ 2014-08-14  8:43   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-14  8:43 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, jolsa, a.p.zijlstra,
	jean.pihet, namhyung, fweisbec, adrian.hunter, dsahern, tglx,
	cjashfor

Commit-ID:  ae256fa27118e54b0f093f0cfe2ada28f1704ef3
Gitweb:     http://git.kernel.org/tip/ae256fa27118e54b0f093f0cfe2ada28f1704ef3
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Mon, 11 Aug 2014 10:50:05 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Aug 2014 11:14:21 -0300

perf top: Join the display thread on exit

We create the display thread, but never join it. It gives
the display thread a chance to quit and cleanup properly.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1407747014-18394-12-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-top.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4fb6f72..10fc7e8 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -965,7 +965,7 @@ static int __cmd_top(struct perf_top *top)
 		param.sched_priority = top->realtime_prio;
 		if (sched_setscheduler(0, SCHED_FIFO, &param)) {
 			ui__error("Could not set realtime priority.\n");
-			goto out_delete;
+			goto out_join;
 		}
 	}
 
@@ -979,6 +979,8 @@ static int __cmd_top(struct perf_top *top)
 	}
 
 	ret = 0;
+out_join:
+	pthread_join(thread, NULL);
 out_delete:
 	perf_session__delete(top->session);
 	top->session = NULL;

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf tools: Introduce set_term_quiet_input helper function
  2014-08-11  8:50 ` [PATCH 08/20] perf tools: Add set_term_quiet_input helper function Jiri Olsa
@ 2014-08-14  8:43   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-14  8:43 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, jolsa, a.p.zijlstra,
	jean.pihet, namhyung, fweisbec, adrian.hunter, dsahern, tglx,
	cjashfor

Commit-ID:  9398c484f8abc8d287cb90f5a33dd43ac26f24ef
Gitweb:     http://git.kernel.org/tip/9398c484f8abc8d287cb90f5a33dd43ac26f24ef
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Mon, 11 Aug 2014 10:50:02 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Aug 2014 11:14:22 -0300

perf tools: Introduce set_term_quiet_input helper function

Adding set_term_quiet_input helper to set the terminal quiet, out from
'perf top', used in following patches in 'perf kvm'.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1407747014-18394-9-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-top.c | 10 ++--------
 tools/perf/util/util.c   | 13 +++++++++++++
 tools/perf/util/util.h   |  2 ++
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 10fc7e8..e8459e2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -580,20 +580,14 @@ static void *display_thread_tui(void *arg)
 static void *display_thread(void *arg)
 {
 	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
-	struct termios tc, save;
+	struct termios save;
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
-	tcgetattr(0, &save);
-	tc = save;
-	tc.c_lflag &= ~(ICANON | ECHO);
-	tc.c_cc[VMIN] = 0;
-	tc.c_cc[VTIME] = 0;
-
 	pthread__unblock_sigwinch();
 repeat:
 	delay_msecs = top->delay_secs * 1000;
-	tcsetattr(0, TCSANOW, &tc);
+	set_term_quiet_input(&save);
 	/* trash return*/
 	getc(stdin);
 
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index b82a93c..25822bd 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -13,6 +13,7 @@
 #include <limits.h>
 #include <byteswap.h>
 #include <linux/kernel.h>
+#include <unistd.h>
 
 /*
  * XXX We need to find a better place for these things...
@@ -282,6 +283,18 @@ void get_term_dimensions(struct winsize *ws)
 	ws->ws_col = 80;
 }
 
+void set_term_quiet_input(struct termios *old)
+{
+	struct termios tc;
+
+	tcgetattr(0, old);
+	tc = *old;
+	tc.c_lflag &= ~(ICANON | ECHO);
+	tc.c_cc[VMIN] = 0;
+	tc.c_cc[VTIME] = 0;
+	tcsetattr(0, TCSANOW, &tc);
+}
+
 static void set_tracing_events_path(const char *mountpoint)
 {
 	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 03a1ea2..d6a79b1 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -75,6 +75,7 @@
 #include <api/fs/debugfs.h>
 #include <termios.h>
 #include <linux/bitops.h>
+#include <termios.h>
 
 extern const char *graph_line;
 extern const char *graph_dotted_line;
@@ -308,6 +309,7 @@ extern unsigned int page_size;
 extern int cacheline_size;
 
 void get_term_dimensions(struct winsize *ws);
+void set_term_quiet_input(struct termios *old);
 
 struct parse_tag {
 	char tag;

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf top: Setup signals for terminal output
  2014-08-11  8:50 ` [PATCH 13/20] perf top: Setup signals for terminal output Jiri Olsa
@ 2014-08-14  8:43   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-14  8:43 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, jolsa, a.p.zijlstra,
	jean.pihet, namhyung, fweisbec, adrian.hunter, dsahern, tglx,
	cjashfor

Commit-ID:  4a1a99712a8a13d97e9de818869bf1b88583d6bc
Gitweb:     http://git.kernel.org/tip/4a1a99712a8a13d97e9de818869bf1b88583d6bc
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Mon, 11 Aug 2014 10:50:07 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Aug 2014 12:42:24 -0300

perf top: Setup signals for terminal output

The TUI code setup standard signals handling, while the stdio display
code does not. This leads to premature termination of display thread
when signal is received and leaving terminal in wrong state.

Also adding terminal cleanup at the end of display thread, to ensure we
get the old terminal state in case of signal interruption.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1407747014-18394-14-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-top.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e8459e2..0ab3ea7 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -577,6 +577,20 @@ static void *display_thread_tui(void *arg)
 	return NULL;
 }
 
+static void display_sig(int sig __maybe_unused)
+{
+	done = 1;
+}
+
+static void display_setup_sig(void)
+{
+	signal(SIGSEGV, display_sig);
+	signal(SIGFPE,  display_sig);
+	signal(SIGINT,  display_sig);
+	signal(SIGQUIT, display_sig);
+	signal(SIGTERM, display_sig);
+}
+
 static void *display_thread(void *arg)
 {
 	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -584,6 +598,7 @@ static void *display_thread(void *arg)
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
+	display_setup_sig();
 	pthread__unblock_sigwinch();
 repeat:
 	delay_msecs = top->delay_secs * 1000;
@@ -614,6 +629,7 @@ repeat:
 		}
 	}
 
+	tcsetattr(0, TCSAFLUSH, &save);
 	return NULL;
 }
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf kvm: Fix stdin handling for 'kvm stat live' command
  2014-08-11  8:50 ` [PATCH 15/20] perf kvm: Fix stdin handling for 'kvm stat live' command Jiri Olsa
@ 2014-08-14  8:43   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-14  8:43 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, jolsa, a.p.zijlstra,
	jean.pihet, namhyung, fweisbec, adrian.hunter, dsahern, tglx,
	cjashfor

Commit-ID:  d5b4130ae636e1fd0eaaea7152170198c34fbf62
Gitweb:     http://git.kernel.org/tip/d5b4130ae636e1fd0eaaea7152170198c34fbf62
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Mon, 11 Aug 2014 10:50:09 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Aug 2014 12:42:24 -0300

perf kvm: Fix stdin handling for 'kvm stat live' command

Currently the initial ~(ICANON | ECHO) terminal mode is not set, so we
dont get stdin data until we press ENTER.

Fixing this by early setting of the ~(ICANON | ECHO) mode and leaving
this mode for whole life of the command, because canonical mode is not
needed.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1407747014-18394-16-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-kvm.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 7cccead..ff40475 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -885,15 +885,11 @@ static int fd_set_nonblock(int fd)
 	return 0;
 }
 
-static
-int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
+static int perf_kvm__handle_stdin(void)
 {
 	int c;
 
-	tcsetattr(0, TCSANOW, tc_now);
 	c = getc(stdin);
-	tcsetattr(0, TCSAFLUSH, tc_save);
-
 	if (c == 'q')
 		return 1;
 
@@ -904,7 +900,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 {
 	struct pollfd *pollfds = NULL;
 	int nr_fds, nr_stdin, ret, err = -EINVAL;
-	struct termios tc, save;
+	struct termios save;
 
 	/* live flag must be set first */
 	kvm->live = true;
@@ -919,14 +915,9 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 		goto out;
 	}
 
+	set_term_quiet_input(&save);
 	init_kvm_event_record(kvm);
 
-	tcgetattr(0, &save);
-	tc = save;
-	tc.c_lflag &= ~(ICANON | ECHO);
-	tc.c_cc[VMIN] = 0;
-	tc.c_cc[VTIME] = 0;
-
 	signal(SIGINT, sig_handler);
 	signal(SIGTERM, sig_handler);
 
@@ -972,7 +963,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 			goto out;
 
 		if (pollfds[nr_stdin].revents & POLLIN)
-			done = perf_kvm__handle_stdin(&tc, &save);
+			done = perf_kvm__handle_stdin();
 
 		if (!rc && !done)
 			err = poll(pollfds, nr_fds, 100);
@@ -989,6 +980,7 @@ out:
 	if (kvm->timerfd >= 0)
 		close(kvm->timerfd);
 
+	tcsetattr(0, TCSAFLUSH, &save);
 	free(pollfds);
 	return err;
 }

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf: Fix perf_poll to return proper POLLHUP value
  2014-08-11 12:01   ` Peter Zijlstra
  2014-08-11 12:22     ` Jiri Olsa
@ 2014-08-24 14:59     ` tip-bot for Jiri Olsa
  2014-08-24 14:59     ` [tip:perf/core] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task tip-bot for Jiri Olsa
  2 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-24 14:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, mingo, jolsa, a.p.zijlstra, peterz, jean.pihet, acme,
	fweisbec, dsahern, tglx, cjashfor, hpa, linux-kernel, paulus,
	namhyung, adrian.hunter

Commit-ID:  61b67684c4a4d04b30d9ed67aa2eadfa0089c590
Gitweb:     http://git.kernel.org/tip/61b67684c4a4d04b30d9ed67aa2eadfa0089c590
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 13 Aug 2014 19:39:56 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Sun, 24 Aug 2014 08:10:55 -0300

perf: Fix perf_poll to return proper POLLHUP value

Currently perf_poll returns POLL_HUP in case of error, which is wrong,
because poll syscall expects POLLHUP.  The POLL_HUP is meant to be used
for SIGIO state.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20140811120102.GY9918@twins.programming.kicks-ass.net
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-0ywfthh4lh65swe15f6w2x2q@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2d7363a..4575dd6 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3627,7 +3627,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
 {
 	struct perf_event *event = file->private_data;
 	struct ring_buffer *rb;
-	unsigned int events = POLL_HUP;
+	unsigned int events = POLLHUP;
 
 	poll_wait(file, &event->waitq, wait);
 	/*

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [tip:perf/core] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
  2014-08-11 12:01   ` Peter Zijlstra
  2014-08-11 12:22     ` Jiri Olsa
  2014-08-24 14:59     ` [tip:perf/core] perf: Fix perf_poll to return proper POLLHUP value tip-bot for Jiri Olsa
@ 2014-08-24 14:59     ` tip-bot for Jiri Olsa
  2 siblings, 0 replies; 33+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-08-24 14:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, mingo, jolsa, a.p.zijlstra, peterz, jean.pihet, acme,
	fweisbec, dsahern, tglx, cjashfor, hpa, linux-kernel, paulus,
	namhyung, adrian.hunter

Commit-ID:  179033b3e064d2cd3f5f9945e76b0a0f0fbf4883
Gitweb:     http://git.kernel.org/tip/179033b3e064d2cd3f5f9945e76b0a0f0fbf4883
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Thu, 7 Aug 2014 11:48:26 -0400
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Sun, 24 Aug 2014 08:11:09 -0300

perf: Add PERF_EVENT_STATE_EXIT state for events with exited task

Adding new perf event state to indicate that the monitored task has
exited.  In this case the event stays alive until the owner task exits
or close the event fd while providing the last data through the read
syscall and ring buffer.

Instead it needs to propagate the error info (monitored task has died)
via poll and read  syscalls by  returning POLLHUP and 0 respectively.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20140811120102.GY9918@twins.programming.kicks-ass.net
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-t5y3w8jjx6tfo5w8y6oajsjq@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 include/linux/perf_event.h |  1 +
 kernel/events/core.c       | 10 +++++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f0a1036..893a0d0 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -269,6 +269,7 @@ struct pmu {
  * enum perf_event_active_state - the states of a event
  */
 enum perf_event_active_state {
+	PERF_EVENT_STATE_EXIT		= -3,
 	PERF_EVENT_STATE_ERROR		= -2,
 	PERF_EVENT_STATE_OFF		= -1,
 	PERF_EVENT_STATE_INACTIVE	=  0,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 4575dd6..d8cb4d2 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3600,7 +3600,8 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
 	 * error state (i.e. because it was pinned but it couldn't be
 	 * scheduled on to the CPU at some point).
 	 */
-	if (event->state == PERF_EVENT_STATE_ERROR)
+	if ((event->state == PERF_EVENT_STATE_ERROR) ||
+	    (event->state == PERF_EVENT_STATE_EXIT))
 		return 0;
 
 	if (count < event->read_size)
@@ -3630,6 +3631,10 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
 	unsigned int events = POLLHUP;
 
 	poll_wait(file, &event->waitq, wait);
+
+	if (event->state == PERF_EVENT_STATE_EXIT)
+		return events;
+
 	/*
 	 * Pin the event->rb by taking event->mmap_mutex; otherwise
 	 * perf_event_set_output() can swizzle our rb and make us miss wakeups.
@@ -7588,6 +7593,9 @@ __perf_event_exit_task(struct perf_event *child_event,
 	if (child_event->parent) {
 		sync_child_event(child_event, child);
 		free_event(child_event);
+	} else {
+		child_event->state = PERF_EVENT_STATE_EXIT;
+		perf_event_wakeup(child_event);
 	}
 }
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2014-08-24 15:02 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-11  8:49 [RFC 00/20] perf: Finish sampling commands when events are closed Jiri Olsa
2014-08-11  8:49 ` [PATCH 01/20] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task Jiri Olsa
2014-08-11 12:01   ` Peter Zijlstra
2014-08-11 12:22     ` Jiri Olsa
2014-08-24 14:59     ` [tip:perf/core] perf: Fix perf_poll to return proper POLLHUP value tip-bot for Jiri Olsa
2014-08-24 14:59     ` [tip:perf/core] perf: Add PERF_EVENT_STATE_EXIT state for events with exited task tip-bot for Jiri Olsa
2014-08-11  8:49 ` [PATCH 02/20] perf tools: Add poller object to handle polling globaly Jiri Olsa
2014-08-11  8:49 ` [PATCH 03/20] perf tests: Add poller object test Jiri Olsa
2014-08-11  8:49 ` [PATCH 04/20] perf tools: Add support to traverse xyarrays Jiri Olsa
2014-08-11  8:49 ` [PATCH 05/20] perf tools: Introduce perf_evsel__fd function Jiri Olsa
2014-08-11  8:50 ` [PATCH 06/20] perf tools: Add evlist/evsel poller object support Jiri Olsa
2014-08-11  8:50 ` [PATCH 07/20] perf record: Add support to see event's ERR and HUP poll errors Jiri Olsa
2014-08-11  8:50 ` [PATCH 08/20] perf tools: Add set_term_quiet_input helper function Jiri Olsa
2014-08-14  8:43   ` [tip:perf/core] perf tools: Introduce " tip-bot for Jiri Olsa
2014-08-11  8:50 ` [PATCH 09/20] perf tui browser: Add interface to terminate browser from uotside Jiri Olsa
2014-08-11  8:50 ` [PATCH 10/20] perf top: Add support to see event's ERR and HUP poll errors Jiri Olsa
2014-08-11  8:50 ` [PATCH 11/20] perf top: Join the display thread on exit Jiri Olsa
2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
2014-08-11  8:50 ` [PATCH 12/20] perf top: Use set_term_quiet_input for terminal input Jiri Olsa
2014-08-11  8:50 ` [PATCH 13/20] perf top: Setup signals for terminal output Jiri Olsa
2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
2014-08-11  8:50 ` [PATCH 14/20] perf top: Use poller object for display thread stdin Jiri Olsa
2014-08-11  8:50 ` [PATCH 15/20] perf kvm: Fix stdin handling for 'kvm stat live' command Jiri Olsa
2014-08-14  8:43   ` [tip:perf/core] " tip-bot for Jiri Olsa
2014-08-11  8:50 ` [PATCH 16/20] perf kvm: Add support to see event's ERR and HUP poll errors Jiri Olsa
2014-08-11  8:50 ` [PATCH 17/20] perf trace: " Jiri Olsa
2014-08-11  8:50 ` [PATCH 18/20] perf python: Use poller object for polling Jiri Olsa
2014-08-11  8:50 ` [PATCH 19/20] perf tests: " Jiri Olsa
2014-08-11  8:50 ` [PATCH 20/20] perf tools: Remove pollfd stuff out of evlist object Jiri Olsa
2014-08-11 20:12 ` [RFC 00/20] perf: Finish sampling commands when events are closed Arnaldo Carvalho de Melo
2014-08-11 20:28   ` Arnaldo Carvalho de Melo
2014-08-12  7:33     ` Jiri Olsa
2014-08-12  7:29   ` Jiri Olsa

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.