All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
@ 2017-02-20 13:33 Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 1/4] perf: Export AUX buffer helpers to modules Alexander Shishkin
                   ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 13:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, vince, eranian, Arnaldo Carvalho de Melo,
	Alexander Shishkin

Hi Peter,

With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
patchset does three things:
 * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
   in it (due to VMX root mode kicking in),
 * changes the AUX API slightly to allow for flags to be set at arbitrary
   points between perf_aux_output_begin() and perf_aux_output_end(),
 * restarts PT after VMXOFF.

I also stole Will's patch from another patchset that adds EXPORT_SYMBOL_GPL
to the AUX calls, which is not strictly relevant, but happens to touch the
same area and is long overdue. The AUX flags patch is also based on Will's
patch from that same context.

Alexander Shishkin (2):
  perf: Add a flag for partial AUX records
  perf/x86/intel/pt: Handle VMX better

Will Deacon (2):
  perf: Export AUX buffer helpers to modules
  perf: Keep AUX flags in the output handle

 arch/x86/events/intel/bts.c                      | 16 +++----
 arch/x86/events/intel/pt.c                       | 55 +++++++++++++-----------
 arch/x86/events/intel/pt.h                       |  1 -
 drivers/hwtracing/coresight/coresight-etb10.c    |  7 ++-
 drivers/hwtracing/coresight/coresight-etm-perf.c |  9 ++--
 drivers/hwtracing/coresight/coresight-priv.h     |  2 -
 drivers/hwtracing/coresight/coresight-tmc-etf.c  |  7 ++-
 include/linux/coresight.h                        |  2 +-
 include/linux/perf_event.h                       |  8 ++--
 include/uapi/linux/perf_event.h                  |  1 +
 kernel/events/ring_buffer.c                      | 38 +++++++++++-----
 11 files changed, 81 insertions(+), 65 deletions(-)

-- 
2.11.0

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

* [PATCH 1/4] perf: Export AUX buffer helpers to modules
  2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
@ 2017-02-20 13:33 ` Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 13:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, vince, eranian, Arnaldo Carvalho de Melo,
	Will Deacon, Peter Zijlstra, Alexander Shishkin

From: Will Deacon <will.deacon@arm.com>

Perf PMU drivers using AUX buffers cannot be built as modules unless
the AUX helpers are exported.

This patch exports perf_aux_output_{begin,end,skip} and perf_get_aux to
modules.

Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 kernel/events/ring_buffer.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 257fa460b8..6415807169 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -397,6 +397,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(perf_aux_output_begin);
 
 /*
  * Commit the data written by hardware into the ring buffer by adjusting
@@ -458,6 +459,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
 	rb_free_aux(rb);
 	ring_buffer_put(rb);
 }
+EXPORT_SYMBOL_GPL(perf_aux_output_end);
 
 /*
  * Skip over a given number of bytes in the AUX buffer, due to, for example,
@@ -486,6 +488,7 @@ int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(perf_aux_output_skip);
 
 void *perf_get_aux(struct perf_output_handle *handle)
 {
@@ -495,6 +498,7 @@ void *perf_get_aux(struct perf_output_handle *handle)
 
 	return handle->rb->aux_priv;
 }
+EXPORT_SYMBOL_GPL(perf_get_aux);
 
 #define PERF_AUX_GFP	(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY)
 
-- 
2.11.0

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

* [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 1/4] perf: Export AUX buffer helpers to modules Alexander Shishkin
@ 2017-02-20 13:33 ` Alexander Shishkin
  2017-02-20 17:01   ` kbuild test robot
                     ` (3 more replies)
  2017-02-20 13:33 ` [PATCH 3/4] perf: Add a flag for partial AUX records Alexander Shishkin
                   ` (2 subsequent siblings)
  4 siblings, 4 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 13:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, vince, eranian, Arnaldo Carvalho de Melo,
	Will Deacon, Mathieu Poirier, Alexander Shishkin

From: Will Deacon <will.deacon@arm.com>

In preparation for adding more flags to perf AUX records, introduce a
separate API for setting the flags for a session, rather than appending
more bool arguments to perf_aux_output_end. This allows to set each
flag at the time a corresponding condition is detected, instead of
tracking it in each driver's private state.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 arch/x86/events/intel/bts.c                      | 16 +++++------
 arch/x86/events/intel/pt.c                       | 17 ++++++------
 arch/x86/events/intel/pt.h                       |  1 -
 drivers/hwtracing/coresight/coresight-etb10.c    |  7 +++--
 drivers/hwtracing/coresight/coresight-etm-perf.c |  9 +++----
 drivers/hwtracing/coresight/coresight-priv.h     |  2 --
 drivers/hwtracing/coresight/coresight-tmc-etf.c  |  7 +++--
 include/linux/coresight.h                        |  2 +-
 include/linux/perf_event.h                       |  8 +++---
 kernel/events/ring_buffer.c                      | 34 ++++++++++++++++--------
 10 files changed, 55 insertions(+), 48 deletions(-)

diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
index 982c9e31da..8ae8c5ce3a 100644
--- a/arch/x86/events/intel/bts.c
+++ b/arch/x86/events/intel/bts.c
@@ -63,7 +63,6 @@ struct bts_buffer {
 	unsigned int	cur_buf;
 	bool		snapshot;
 	local_t		data_size;
-	local_t		lost;
 	local_t		head;
 	unsigned long	end;
 	void		**data_pages;
@@ -199,7 +198,8 @@ static void bts_update(struct bts_ctx *bts)
 			return;
 
 		if (ds->bts_index >= ds->bts_absolute_maximum)
-			local_inc(&buf->lost);
+			perf_aux_output_flag(&bts->handle,
+			                     PERF_AUX_FLAG_TRUNCATED);
 
 		/*
 		 * old and head are always in the same physical buffer, so we
@@ -276,7 +276,7 @@ static void bts_event_start(struct perf_event *event, int flags)
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(&bts->handle, 0, false);
+	perf_aux_output_end(&bts->handle, 0);
 
 fail_stop:
 	event->hw.state = PERF_HES_STOPPED;
@@ -319,9 +319,8 @@ static void bts_event_stop(struct perf_event *event, int flags)
 				bts->handle.head =
 					local_xchg(&buf->data_size,
 						   buf->nr_pages << PAGE_SHIFT);
-
-			perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-					    !!local_xchg(&buf->lost, 0));
+			perf_aux_output_end(&bts->handle,
+			                    local_xchg(&buf->data_size, 0));
 		}
 
 		cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
@@ -484,8 +483,7 @@ int intel_bts_interrupt(void)
 	if (old_head == local_read(&buf->head))
 		return handled;
 
-	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-			    !!local_xchg(&buf->lost, 0));
+	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0));
 
 	buf = perf_aux_output_begin(&bts->handle, event);
 	if (buf)
@@ -500,7 +498,7 @@ int intel_bts_interrupt(void)
 			 * cleared handle::event
 			 */
 			barrier();
-			perf_aux_output_end(&bts->handle, 0, false);
+			perf_aux_output_end(&bts->handle, 0);
 		}
 	}
 
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index d92a60ef08..a2d0050fde 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -823,7 +823,8 @@ static void pt_handle_status(struct pt *pt)
 		 */
 		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
 		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
-			local_inc(&buf->lost);
+			perf_aux_output_flag(&pt->handle,
+			                     PERF_AUX_FLAG_TRUNCATED);
 			advance++;
 		}
 	}
@@ -916,8 +917,10 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
 
 	/* can't stop in the middle of an output region */
 	if (buf->output_off + handle->size + 1 <
-	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
+	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		return -EINVAL;
+	}
 
 
 	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
@@ -1269,8 +1272,7 @@ void intel_pt_interrupt(void)
 
 	pt_update_head(pt);
 
-	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-			    local_xchg(&buf->lost, 0));
+	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
 
 	if (!event->hw.state) {
 		int ret;
@@ -1285,7 +1287,7 @@ void intel_pt_interrupt(void)
 		/* snapshot counters don't use PMI, so it's safe */
 		ret = pt_buffer_reset_markers(buf, &pt->handle);
 		if (ret) {
-			perf_aux_output_end(&pt->handle, 0, true);
+			perf_aux_output_end(&pt->handle, 0);
 			return;
 		}
 
@@ -1357,7 +1359,7 @@ static void pt_event_start(struct perf_event *event, int mode)
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(&pt->handle, 0, true);
+	perf_aux_output_end(&pt->handle, 0);
 fail_stop:
 	hwc->state = PERF_HES_STOPPED;
 }
@@ -1398,8 +1400,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
 			pt->handle.head =
 				local_xchg(&buf->data_size,
 					   buf->nr_pages << PAGE_SHIFT);
-		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-				    local_xchg(&buf->lost, 0));
+		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
 	}
 }
 
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index fa81f8d8ed..25fa9710f4 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -144,7 +144,6 @@ struct pt_buffer {
 	size_t			output_off;
 	unsigned long		nr_pages;
 	local_t			data_size;
-	local_t			lost;
 	local64_t		head;
 	bool			snapshot;
 	unsigned long		stop_pos, intr_pos;
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index d7325c6534..82c8ddcf09 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -321,7 +321,7 @@ static int etb_set_buffer(struct coresight_device *csdev,
 
 static unsigned long etb_reset_buffer(struct coresight_device *csdev,
 				      struct perf_output_handle *handle,
-				      void *sink_config, bool *lost)
+				      void *sink_config)
 {
 	unsigned long size = 0;
 	struct cs_buffers *buf = sink_config;
@@ -343,7 +343,6 @@ static unsigned long etb_reset_buffer(struct coresight_device *csdev,
 		 * resetting parameters here and squaring off with the ring
 		 * buffer API in the tracer PMU is fine.
 		 */
-		*lost = !!local_xchg(&buf->lost, 0);
 		size = local_xchg(&buf->data_size, 0);
 	}
 
@@ -385,7 +384,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 			(unsigned long)write_ptr);
 
 		write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1);
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	/*
@@ -396,7 +395,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 	 */
 	status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
 	if (status & ETB_STATUS_RAM_FULL) {
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		to_read = capacity;
 		read_ptr = write_ptr;
 	} else {
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 70eaa74dc2..47ea0eee67 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -301,7 +301,8 @@ static void etm_event_start(struct perf_event *event, int flags)
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(handle, 0, true);
+	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
+	perf_aux_output_end(handle, 0);
 fail:
 	event->hw.state = PERF_HES_STOPPED;
 	goto out;
@@ -309,7 +310,6 @@ static void etm_event_start(struct perf_event *event, int flags)
 
 static void etm_event_stop(struct perf_event *event, int mode)
 {
-	bool lost;
 	int cpu = smp_processor_id();
 	unsigned long size;
 	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
@@ -347,10 +347,9 @@ static void etm_event_stop(struct perf_event *event, int mode)
 			return;
 
 		size = sink_ops(sink)->reset_buffer(sink, handle,
-						    event_data->snk_config,
-						    &lost);
+						    event_data->snk_config);
 
-		perf_aux_output_end(handle, size, lost);
+		perf_aux_output_end(handle, size);
 	}
 
 	/* Disabling the path make its elements available to other sessions */
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index ef9d8e93e3..5f662d8205 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -76,7 +76,6 @@ enum cs_mode {
  * @nr_pages:	max number of pages granted to us
  * @offset:	offset within the current buffer
  * @data_size:	how much we collected in this run
- * @lost:	other than zero if we had a HW buffer wrap around
  * @snapshot:	is this run in snapshot mode
  * @data_pages:	a handle the ring buffer
  */
@@ -85,7 +84,6 @@ struct cs_buffers {
 	unsigned int		nr_pages;
 	unsigned long		offset;
 	local_t			data_size;
-	local_t			lost;
 	bool			snapshot;
 	void			**data_pages;
 };
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 1549436e24..aec61a6d5c 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -329,7 +329,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
 
 static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
 					  struct perf_output_handle *handle,
-					  void *sink_config, bool *lost)
+					  void *sink_config)
 {
 	long size = 0;
 	struct cs_buffers *buf = sink_config;
@@ -350,7 +350,6 @@ static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
 		 * resetting parameters here and squaring off with the ring
 		 * buffer API in the tracer PMU is fine.
 		 */
-		*lost = !!local_xchg(&buf->lost, 0);
 		size = local_xchg(&buf->data_size, 0);
 	}
 
@@ -389,7 +388,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
 	 */
 	status = readl_relaxed(drvdata->base + TMC_STS);
 	if (status & TMC_STS_FULL) {
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		to_read = drvdata->size;
 	} else {
 		to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size);
@@ -434,7 +433,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
 			read_ptr -= drvdata->size;
 		/* Tell the HW */
 		writel_relaxed(read_ptr, drvdata->base + TMC_RRP);
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	cur = buf->cur;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2a5982c37d..035c16c9a5 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -201,7 +201,7 @@ struct coresight_ops_sink {
 			  void *sink_config);
 	unsigned long (*reset_buffer)(struct coresight_device *csdev,
 				      struct perf_output_handle *handle,
-				      void *sink_config, bool *lost);
+				      void *sink_config);
 	void (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index a39564314e..cdbaa88dc8 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -812,6 +812,7 @@ struct perf_output_handle {
 	struct ring_buffer		*rb;
 	unsigned long			wakeup;
 	unsigned long			size;
+	u64				aux_flags;
 	union {
 		void			*addr;
 		unsigned long		head;
@@ -860,10 +861,11 @@ perf_cgroup_from_task(struct task_struct *task, struct perf_event_context *ctx)
 extern void *perf_aux_output_begin(struct perf_output_handle *handle,
 				   struct perf_event *event);
 extern void perf_aux_output_end(struct perf_output_handle *handle,
-				unsigned long size, bool truncated);
+				unsigned long size);
 extern int perf_aux_output_skip(struct perf_output_handle *handle,
 				unsigned long size);
 extern void *perf_get_aux(struct perf_output_handle *handle);
+extern void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags);
 
 extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
 extern void perf_pmu_unregister(struct pmu *pmu);
@@ -1278,8 +1280,8 @@ static inline void *
 perf_aux_output_begin(struct perf_output_handle *handle,
 		      struct perf_event *event)				{ return NULL; }
 static inline void
-perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
-		    bool truncated)					{ }
+perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
+									{ }
 static inline int
 perf_aux_output_skip(struct perf_output_handle *handle,
 		     unsigned long size)				{ return -EINVAL; }
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 6415807169..f3ebafe060 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -297,6 +297,19 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
 		rb->paused = 1;
 }
 
+void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags)
+{
+	/*
+	 * OVERWRITE is determined by perf_aux_output_end() and can't
+	 * be passed in directly.
+	 */
+	if (WARN_ON_ONCE(flags & PERF_AUX_FLAG_OVERWRITE))
+		return;
+
+	handle->aux_flags |= flags;
+}
+EXPORT_SYMBOL_GPL(perf_aux_output_flag);
+
 /*
  * This is called before hardware starts writing to the AUX area to
  * obtain an output handle and make sure there's room in the buffer.
@@ -360,6 +373,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
 	handle->event = event;
 	handle->head = aux_head;
 	handle->size = 0;
+	handle->aux_flags = 0;
 
 	/*
 	 * In overwrite mode, AUX data stores do not depend on aux_tail,
@@ -409,34 +423,32 @@ EXPORT_SYMBOL_GPL(perf_aux_output_begin);
  * of the AUX buffer management code is that after pmu::stop(), the AUX
  * transaction must be stopped and therefore drop the AUX reference count.
  */
-void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
-			 bool truncated)
+void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
 	struct ring_buffer *rb = handle->rb;
-	bool wakeup = truncated;
+	bool wakeup = !!handle->aux_flags;
 	unsigned long aux_head;
-	u64 flags = 0;
-
-	if (truncated)
-		flags |= PERF_AUX_FLAG_TRUNCATED;
 
 	/* in overwrite mode, driver provides aux_head via handle */
 	if (rb->aux_overwrite) {
-		flags |= PERF_AUX_FLAG_OVERWRITE;
+		handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE;
 
 		aux_head = handle->head;
 		local_set(&rb->aux_head, aux_head);
 	} else {
+		handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
+
 		aux_head = local_read(&rb->aux_head);
 		local_add(size, &rb->aux_head);
 	}
 
-	if (size || flags) {
+	if (size || handle->aux_flags) {
 		/*
 		 * Only send RECORD_AUX if we have something useful to communicate
 		 */
 
-		perf_event_aux_event(handle->event, aux_head, size, flags);
+		perf_event_aux_event(handle->event, aux_head, size,
+		                     handle->aux_flags);
 	}
 
 	aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
@@ -447,7 +459,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
 	}
 
 	if (wakeup) {
-		if (truncated)
+		if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)
 			handle->event->pending_disable = 1;
 		perf_output_wakeup(handle);
 	}
-- 
2.11.0

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

* [PATCH 3/4] perf: Add a flag for partial AUX records
  2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 1/4] perf: Export AUX buffer helpers to modules Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
@ 2017-02-20 13:33 ` Alexander Shishkin
  2017-03-16 11:23   ` [tip:perf/core] perf/core: " tip-bot for Alexander Shishkin
  2017-02-20 13:33 ` [PATCH 4/4] perf/x86/intel/pt: Handle VMX better Alexander Shishkin
  2017-02-20 15:18 ` [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
  4 siblings, 1 reply; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 13:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, vince, eranian, Arnaldo Carvalho de Melo,
	Alexander Shishkin, Arnaldo Carvalho de Melo, Mathieu Poirier

Intel PT driver needs to be able to communicate partial AUX transactions,
that is, transactions with gaps in data for reasons other than no room
left in the buffer (i.e. truncated transactions). Therefore, this condition
does not imply a wakeup for the consumer.

To this end, add a new "partial" AUX flag.

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 include/uapi/linux/perf_event.h | 1 +
 kernel/events/ring_buffer.c     | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index c66a485a24..8306415207 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -885,6 +885,7 @@ enum perf_callchain_context {
  */
 #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
 #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
+#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
 
 #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
 #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index f3ebafe060..cd5e902a27 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -425,8 +425,8 @@ EXPORT_SYMBOL_GPL(perf_aux_output_begin);
  */
 void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
+	bool wakeup = !!(handle->aux_flags & PERF_AUX_FLAG_TRUNCATED);
 	struct ring_buffer *rb = handle->rb;
-	bool wakeup = !!handle->aux_flags;
 	unsigned long aux_head;
 
 	/* in overwrite mode, driver provides aux_head via handle */
-- 
2.11.0

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

* [PATCH 4/4] perf/x86/intel/pt: Handle VMX better
  2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
                   ` (2 preceding siblings ...)
  2017-02-20 13:33 ` [PATCH 3/4] perf: Add a flag for partial AUX records Alexander Shishkin
@ 2017-02-20 13:33 ` Alexander Shishkin
  2017-03-16 11:24   ` [tip:perf/core] " tip-bot for Alexander Shishkin
  2017-02-20 15:18 ` [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
  4 siblings, 1 reply; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 13:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, vince, eranian, Arnaldo Carvalho de Melo,
	Alexander Shishkin, Arnaldo Carvalho de Melo

Since commit 1c5ac21a0e ("perf/x86/intel/pt: Don't die on VMXON") PT
events depend on re-scheduling to get enabled after a VMX session has
taken place. This is, in particular, a problem for CPU context events,
which don't normally get re-scheduled, unless there is a reason.

This patch changes the VMX handling so that PT event gets re-enabled
when VMX root mode exits.

Also, notify the user when there's a gap in PT data due to VMX root
mode by flagging AUX records as partial.

In combination with vmm_exclusive=0 parameter of the kvm_intel driver,
this will result in trace gaps only for the duration of the guest's
timeslices.

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 arch/x86/events/intel/pt.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index a2d0050fde..a0fd10f11f 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -468,6 +468,7 @@ static u64 pt_config_filters(struct perf_event *event)
 
 static void pt_config(struct perf_event *event)
 {
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	u64 reg;
 
 	if (!event->hw.itrace_started) {
@@ -499,11 +500,15 @@ static void pt_config(struct perf_event *event)
 	reg |= (event->attr.config & PT_CONFIG_MASK);
 
 	event->hw.config = reg;
-	wrmsrl(MSR_IA32_RTIT_CTL, reg);
+	if (READ_ONCE(pt->vmx_on))
+		perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
+	else
+		wrmsrl(MSR_IA32_RTIT_CTL, reg);
 }
 
 static void pt_config_stop(struct perf_event *event)
 {
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	u64 ctl = READ_ONCE(event->hw.config);
 
 	/* may be already stopped by a PMI */
@@ -511,7 +516,8 @@ static void pt_config_stop(struct perf_event *event)
 		return;
 
 	ctl &= ~RTIT_CTL_TRACEEN;
-	wrmsrl(MSR_IA32_RTIT_CTL, ctl);
+	if (!READ_ONCE(pt->vmx_on))
+		wrmsrl(MSR_IA32_RTIT_CTL, ctl);
 
 	WRITE_ONCE(event->hw.config, ctl);
 
@@ -1251,12 +1257,6 @@ void intel_pt_interrupt(void)
 	if (!READ_ONCE(pt->handle_nmi))
 		return;
 
-	/*
-	 * If VMX is on and PT does not support it, don't touch anything.
-	 */
-	if (READ_ONCE(pt->vmx_on))
-		return;
-
 	if (!event)
 		return;
 
@@ -1316,12 +1316,19 @@ void intel_pt_handle_vmx(int on)
 	local_irq_save(flags);
 	WRITE_ONCE(pt->vmx_on, on);
 
-	if (on) {
-		/* prevent pt_config_stop() from writing RTIT_CTL */
-		event = pt->handle.event;
-		if (event)
-			event->hw.config = 0;
-	}
+	/*
+	 * If an AUX transaction is in progress, it will contain
+	 * gap(s), so flag it PARTIAL to inform the user.
+	 */
+	event = pt->handle.event;
+	if (event)
+		perf_aux_output_flag(&pt->handle,
+		                     PERF_AUX_FLAG_PARTIAL);
+
+	/* Turn PTs back on */
+	if (!on && event)
+		wrmsrl(MSR_IA32_RTIT_CTL, event->hw.config);
+
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(intel_pt_handle_vmx);
@@ -1336,9 +1343,6 @@ static void pt_event_start(struct perf_event *event, int mode)
 	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	struct pt_buffer *buf;
 
-	if (READ_ONCE(pt->vmx_on))
-		return;
-
 	buf = perf_aux_output_begin(&pt->handle, event);
 	if (!buf)
 		goto fail_stop;
-- 
2.11.0

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

* Re: [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
  2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
                   ` (3 preceding siblings ...)
  2017-02-20 13:33 ` [PATCH 4/4] perf/x86/intel/pt: Handle VMX better Alexander Shishkin
@ 2017-02-20 15:18 ` Alexander Shishkin
  2017-02-20 15:39   ` Adrian Hunter
  4 siblings, 1 reply; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 15:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Adrian Hunter
  Cc: linux-kernel, vince, eranian, Peter Zijlstra, Ingo Molnar

Alexander Shishkin <alexander.shishkin@linux.intel.com> writes:

> With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
> patchset does three things:
>  * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
>    in it (due to VMX root mode kicking in),

Hi Arnaldo & Adrian,

In the above context, will something like this be fine?

Regards,
--
Alex

>From 5aba03e79c1119408b44435af8c4cee2480b0775 Mon Sep 17 00:00:00 2001
From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Date: Mon, 20 Feb 2017 17:08:53 +0200
Subject: [PATCH] perf tools: Handle partial AUX records and print a warning

This patch decodes the 'partial' flag in AUX records and prints
a warning to the user, so that they don't have to guess why their
PT traces contain gaps (or missing altogether):

> Warning:
> AUX data had gaps in it 6 times out of 8!
>
> Are you running a KVM guest in the background?

Currently this is the only reason for partial records.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 tools/include/uapi/linux/perf_event.h |  1 +
 tools/perf/util/event.c               |  5 +++--
 tools/perf/util/event.h               |  1 +
 tools/perf/util/session.c             | 17 ++++++++++++++---
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index c66a485a24..8306415207 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -885,6 +885,7 @@ enum perf_callchain_context {
  */
 #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
 #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
+#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
 
 #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
 #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 4ea7ce72ed..ba193cd019 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1153,11 +1153,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
 
 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
 {
-	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
+	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
 		       event->aux.aux_offset, event->aux.aux_size,
 		       event->aux.flags,
 		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
-		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
+		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
+		       event->aux.flags & PERF_AUX_FLAG_PARTIAL   ? "P" : "");
 }
 
 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index c735c53a26..d7e53fe176 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -269,6 +269,7 @@ struct events_stats {
 	u64 total_lost;
 	u64 total_lost_samples;
 	u64 total_aux_lost;
+	u64 total_aux_partial;
 	u64 total_invalid_chains;
 	u32 nr_events[PERF_RECORD_HEADER_MAX];
 	u32 nr_non_filtered_samples;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4cdbc8f5f1..abdb797fa4 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1258,9 +1258,12 @@ static int machines__deliver_event(struct machines *machines,
 	case PERF_RECORD_UNTHROTTLE:
 		return tool->unthrottle(tool, event, sample, machine);
 	case PERF_RECORD_AUX:
-		if (tool->aux == perf_event__process_aux &&
-		    (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
-			evlist->stats.total_aux_lost += 1;
+		if (tool->aux == perf_event__process_aux) {
+			if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
+				evlist->stats.total_aux_lost += 1;
+			if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
+				evlist->stats.total_aux_partial += 1;
+		}
 		return tool->aux(tool, event, sample, machine);
 	case PERF_RECORD_ITRACE_START:
 		return tool->itrace_start(tool, event, sample, machine);
@@ -1548,6 +1551,14 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
 			    stats->nr_events[PERF_RECORD_AUX]);
 	}
 
+	if (session->tool->aux == perf_event__process_aux &&
+	    stats->total_aux_partial != 0) {
+		ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
+		            "Are you running a KVM guest in the background?\n\n",
+			    stats->total_aux_partial,
+			    stats->nr_events[PERF_RECORD_AUX]);
+	}
+
 	if (stats->nr_unknown_events != 0) {
 		ui__warning("Found %u unknown events!\n\n"
 			    "Is this an older tool processing a perf.data "
-- 
2.11.0

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

* Re: [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
  2017-02-20 15:18 ` [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
@ 2017-02-20 15:39   ` Adrian Hunter
  2017-02-20 16:09     ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 22+ messages in thread
From: Adrian Hunter @ 2017-02-20 15:39 UTC (permalink / raw)
  To: Alexander Shishkin, Arnaldo Carvalho de Melo
  Cc: linux-kernel, vince, eranian, Peter Zijlstra, Ingo Molnar

On 20/02/17 17:18, Alexander Shishkin wrote:
> Alexander Shishkin <alexander.shishkin@linux.intel.com> writes:
> 
>> With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
>> patchset does three things:
>>  * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
>>    in it (due to VMX root mode kicking in),
> 
> Hi Arnaldo & Adrian,
> 
> In the above context, will something like this be fine?

Looks fine to me.

Acked-by: Adrian Hunter <adrian.hunter@intel.com>


> 
> Regards,
> --
> Alex
> 
>>From 5aba03e79c1119408b44435af8c4cee2480b0775 Mon Sep 17 00:00:00 2001
> From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Date: Mon, 20 Feb 2017 17:08:53 +0200
> Subject: [PATCH] perf tools: Handle partial AUX records and print a warning
> 
> This patch decodes the 'partial' flag in AUX records and prints
> a warning to the user, so that they don't have to guess why their
> PT traces contain gaps (or missing altogether):
> 
>> Warning:
>> AUX data had gaps in it 6 times out of 8!
>>
>> Are you running a KVM guest in the background?
> 
> Currently this is the only reason for partial records.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> ---
>  tools/include/uapi/linux/perf_event.h |  1 +
>  tools/perf/util/event.c               |  5 +++--
>  tools/perf/util/event.h               |  1 +
>  tools/perf/util/session.c             | 17 ++++++++++++++---
>  4 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index c66a485a24..8306415207 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -885,6 +885,7 @@ enum perf_callchain_context {
>   */
>  #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
>  #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
> +#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
>  
>  #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
>  #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
> diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
> index 4ea7ce72ed..ba193cd019 100644
> --- a/tools/perf/util/event.c
> +++ b/tools/perf/util/event.c
> @@ -1153,11 +1153,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
>  
>  size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
>  {
> -	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
> +	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
>  		       event->aux.aux_offset, event->aux.aux_size,
>  		       event->aux.flags,
>  		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
> -		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
> +		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
> +		       event->aux.flags & PERF_AUX_FLAG_PARTIAL   ? "P" : "");
>  }
>  
>  size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
> diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
> index c735c53a26..d7e53fe176 100644
> --- a/tools/perf/util/event.h
> +++ b/tools/perf/util/event.h
> @@ -269,6 +269,7 @@ struct events_stats {
>  	u64 total_lost;
>  	u64 total_lost_samples;
>  	u64 total_aux_lost;
> +	u64 total_aux_partial;
>  	u64 total_invalid_chains;
>  	u32 nr_events[PERF_RECORD_HEADER_MAX];
>  	u32 nr_non_filtered_samples;
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 4cdbc8f5f1..abdb797fa4 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -1258,9 +1258,12 @@ static int machines__deliver_event(struct machines *machines,
>  	case PERF_RECORD_UNTHROTTLE:
>  		return tool->unthrottle(tool, event, sample, machine);
>  	case PERF_RECORD_AUX:
> -		if (tool->aux == perf_event__process_aux &&
> -		    (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
> -			evlist->stats.total_aux_lost += 1;
> +		if (tool->aux == perf_event__process_aux) {
> +			if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
> +				evlist->stats.total_aux_lost += 1;
> +			if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
> +				evlist->stats.total_aux_partial += 1;
> +		}
>  		return tool->aux(tool, event, sample, machine);
>  	case PERF_RECORD_ITRACE_START:
>  		return tool->itrace_start(tool, event, sample, machine);
> @@ -1548,6 +1551,14 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
>  			    stats->nr_events[PERF_RECORD_AUX]);
>  	}
>  
> +	if (session->tool->aux == perf_event__process_aux &&
> +	    stats->total_aux_partial != 0) {
> +		ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
> +		            "Are you running a KVM guest in the background?\n\n",
> +			    stats->total_aux_partial,
> +			    stats->nr_events[PERF_RECORD_AUX]);
> +	}
> +
>  	if (stats->nr_unknown_events != 0) {
>  		ui__warning("Found %u unknown events!\n\n"
>  			    "Is this an older tool processing a perf.data "
> 

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

* Re: [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
  2017-02-20 15:39   ` Adrian Hunter
@ 2017-02-20 16:09     ` Arnaldo Carvalho de Melo
  2017-02-20 16:31       ` Alexander Shishkin
  2017-03-16 16:41       ` Alexander Shishkin
  0 siblings, 2 replies; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-02-20 16:09 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Adrian Hunter, Arnaldo Carvalho de Melo, linux-kernel, vince,
	eranian, Peter Zijlstra, Ingo Molnar

Em Mon, Feb 20, 2017 at 05:39:43PM +0200, Adrian Hunter escreveu:
> On 20/02/17 17:18, Alexander Shishkin wrote:
> > Alexander Shishkin <alexander.shishkin@linux.intel.com> writes:
> > 
> >> With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
> >> patchset does three things:
> >>  * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
> >>    in it (due to VMX root mode kicking in),
> > 
> > In the above context, will something like this be fine?
 
> Looks fine to me.
 
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> 
> > From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> > Subject: [PATCH] perf tools: Handle partial AUX records and print a warning

> > This patch decodes the 'partial' flag in AUX records and prints
> > a warning to the user, so that they don't have to guess why their
> > PT traces contain gaps (or missing altogether):

> >> Warning:
> >> AUX data had gaps in it 6 times out of 8!

The above should be left for a more verbose mode?

> >> Are you running a KVM guest in the background?

The warning should be a bit more precise, as you said, tuning
vmm_exclusive is key here, i.e.:

"Are you running a KVM guest in the background with
kvm_intel.vmm_exclusive=1?"

And that we can even figure out, its just a matter of reading:

[root@jouet ~]# cat /sys/module/kvm_intel/parameters/vmm_exclusive
Y

I have tested after setting that using:

 modprobe kvm_intel vmm_exclusive=n

And I was able to get Intel PT records from a workload.

So perhaps we can get this patch in, which improves the situation, and
then, on top of it do these extra checks and give proper hints, ok?

- Arnaldo
 
> > Currently this is the only reason for partial records.
> > 
> > Cc: Adrian Hunter <adrian.hunter@intel.com>
> > Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> > ---
> >  tools/include/uapi/linux/perf_event.h |  1 +
> >  tools/perf/util/event.c               |  5 +++--
> >  tools/perf/util/event.h               |  1 +
> >  tools/perf/util/session.c             | 17 ++++++++++++++---
> >  4 files changed, 19 insertions(+), 5 deletions(-)
> > 
> > diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> > index c66a485a24..8306415207 100644
> > --- a/tools/include/uapi/linux/perf_event.h
> > +++ b/tools/include/uapi/linux/perf_event.h
> > @@ -885,6 +885,7 @@ enum perf_callchain_context {
> >   */
> >  #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
> >  #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
> > +#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
> >  
> >  #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
> >  #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
> > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
> > index 4ea7ce72ed..ba193cd019 100644
> > --- a/tools/perf/util/event.c
> > +++ b/tools/perf/util/event.c
> > @@ -1153,11 +1153,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
> >  
> >  size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
> >  {
> > -	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
> > +	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
> >  		       event->aux.aux_offset, event->aux.aux_size,
> >  		       event->aux.flags,
> >  		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
> > -		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
> > +		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
> > +		       event->aux.flags & PERF_AUX_FLAG_PARTIAL   ? "P" : "");
> >  }
> >  
> >  size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
> > diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
> > index c735c53a26..d7e53fe176 100644
> > --- a/tools/perf/util/event.h
> > +++ b/tools/perf/util/event.h
> > @@ -269,6 +269,7 @@ struct events_stats {
> >  	u64 total_lost;
> >  	u64 total_lost_samples;
> >  	u64 total_aux_lost;
> > +	u64 total_aux_partial;
> >  	u64 total_invalid_chains;
> >  	u32 nr_events[PERF_RECORD_HEADER_MAX];
> >  	u32 nr_non_filtered_samples;
> > diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> > index 4cdbc8f5f1..abdb797fa4 100644
> > --- a/tools/perf/util/session.c
> > +++ b/tools/perf/util/session.c
> > @@ -1258,9 +1258,12 @@ static int machines__deliver_event(struct machines *machines,
> >  	case PERF_RECORD_UNTHROTTLE:
> >  		return tool->unthrottle(tool, event, sample, machine);
> >  	case PERF_RECORD_AUX:
> > -		if (tool->aux == perf_event__process_aux &&
> > -		    (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
> > -			evlist->stats.total_aux_lost += 1;
> > +		if (tool->aux == perf_event__process_aux) {
> > +			if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
> > +				evlist->stats.total_aux_lost += 1;
> > +			if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
> > +				evlist->stats.total_aux_partial += 1;
> > +		}
> >  		return tool->aux(tool, event, sample, machine);
> >  	case PERF_RECORD_ITRACE_START:
> >  		return tool->itrace_start(tool, event, sample, machine);
> > @@ -1548,6 +1551,14 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
> >  			    stats->nr_events[PERF_RECORD_AUX]);
> >  	}
> >  
> > +	if (session->tool->aux == perf_event__process_aux &&
> > +	    stats->total_aux_partial != 0) {
> > +		ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
> > +		            "Are you running a KVM guest in the background?\n\n",
> > +			    stats->total_aux_partial,
> > +			    stats->nr_events[PERF_RECORD_AUX]);
> > +	}
> > +
> >  	if (stats->nr_unknown_events != 0) {
> >  		ui__warning("Found %u unknown events!\n\n"
> >  			    "Is this an older tool processing a perf.data "
> > 

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

* Re: [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
  2017-02-20 16:09     ` Arnaldo Carvalho de Melo
@ 2017-02-20 16:31       ` Alexander Shishkin
  2017-03-16 16:41       ` Alexander Shishkin
  1 sibling, 0 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 16:31 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Adrian Hunter, Arnaldo Carvalho de Melo, linux-kernel, vince,
	eranian, Peter Zijlstra, Ingo Molnar

Arnaldo Carvalho de Melo <acme@kernel.org> writes:

> Em Mon, Feb 20, 2017 at 05:39:43PM +0200, Adrian Hunter escreveu:
>> On 20/02/17 17:18, Alexander Shishkin wrote:
>> > Alexander Shishkin <alexander.shishkin@linux.intel.com> writes:
>> > 
>> >> With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
>> >> patchset does three things:
>> >>  * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
>> >>    in it (due to VMX root mode kicking in),
>> > 
>> > In the above context, will something like this be fine?
>  
>> Looks fine to me.
>  
>> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>> 
>> > From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> > Subject: [PATCH] perf tools: Handle partial AUX records and print a warning
>
>> > This patch decodes the 'partial' flag in AUX records and prints
>> > a warning to the user, so that they don't have to guess why their
>> > PT traces contain gaps (or missing altogether):
>
>> >> Warning:
>> >> AUX data had gaps in it 6 times out of 8!
>
> The above should be left for a more verbose mode?
>
>> >> Are you running a KVM guest in the background?
>
> The warning should be a bit more precise, as you said, tuning
> vmm_exclusive is key here, i.e.:
>
> "Are you running a KVM guest in the background with
> kvm_intel.vmm_exclusive=1?"

You'll still get gaps with vmm_exclusive=0 if you run perf record -a or
if you try to trace the actual kvm.

> And that we can even figure out, its just a matter of reading:
>
> [root@jouet ~]# cat /sys/module/kvm_intel/parameters/vmm_exclusive
> Y
>
> I have tested after setting that using:
>
>  modprobe kvm_intel vmm_exclusive=n
>
> And I was able to get Intel PT records from a workload.
>
> So perhaps we can get this patch in, which improves the situation, and
> then, on top of it do these extra checks and give proper hints, ok?

Sure.

Thanks,
--
Alex

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

* Re: [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
@ 2017-02-20 17:01   ` kbuild test robot
  2017-02-20 17:17     ` Alexander Shishkin
  2017-02-20 20:42   ` Mathieu Poirier
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: kbuild test robot @ 2017-02-20 17:01 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: kbuild-all, Peter Zijlstra, Ingo Molnar, linux-kernel, vince,
	eranian, Arnaldo Carvalho de Melo, Will Deacon, Mathieu Poirier,
	Alexander Shishkin

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

Hi Will,

[auto build test ERROR on tip/perf/core]
[also build test ERROR on v4.10 next-20170220]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Alexander-Shishkin/perf-pt-coresight-AUX-flags-and-VMX-update/20170220-220625
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

   In file included from ./arch/arm64/include/generated/asm/local.h:1:0,
                    from drivers/hwtracing/coresight/coresight-etb10.c:15:
   drivers/hwtracing/coresight/coresight-etb10.c: In function 'etb_update_buffer':
>> drivers/hwtracing/coresight/coresight-etb10.c:431:17: error: 'struct cs_buffers' has no member named 'lost'
      local_inc(&buf->lost);
                    ^
   include/asm-generic/local.h:30:40: note: in definition of macro 'local_inc'
    #define local_inc(l) atomic_long_inc(&(l)->a)
                                           ^

vim +431 drivers/hwtracing/coresight/coresight-etb10.c

2997aa40 Mathieu Poirier 2016-02-17  425  		read_ptr = (write_ptr + drvdata->buffer_depth) -
2997aa40 Mathieu Poirier 2016-02-17  426  					to_read / ETB_FRAME_SIZE_WORDS;
2997aa40 Mathieu Poirier 2016-02-17  427  		/* Wrap around if need be*/
bedffda8 Mathieu Poirier 2016-05-03  428  		if (read_ptr > (drvdata->buffer_depth - 1))
bedffda8 Mathieu Poirier 2016-05-03  429  			read_ptr -= drvdata->buffer_depth;
2997aa40 Mathieu Poirier 2016-02-17  430  		/* let the decoder know we've skipped ahead */
2997aa40 Mathieu Poirier 2016-02-17 @431  		local_inc(&buf->lost);
2997aa40 Mathieu Poirier 2016-02-17  432  	}
2997aa40 Mathieu Poirier 2016-02-17  433  
2997aa40 Mathieu Poirier 2016-02-17  434  	/* finally tell HW where we want to start reading from */

:::::: The code at line 431 was first introduced by commit
:::::: 2997aa4063d97fdb39450c6078bd81a7b0504f22 coresight: etb10: implementing AUX API

:::::: TO: Mathieu Poirier <mathieu.poirier@linaro.org>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 53487 bytes --]

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

* Re: [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-20 17:01   ` kbuild test robot
@ 2017-02-20 17:17     ` Alexander Shishkin
  0 siblings, 0 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-20 17:17 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Peter Zijlstra, Ingo Molnar, linux-kernel, vince,
	eranian, Arnaldo Carvalho de Melo, Will Deacon, Mathieu Poirier

kbuild test robot <lkp@intel.com> writes:

> All errors (new ones prefixed by >>):
>
>    In file included from ./arch/arm64/include/generated/asm/local.h:1:0,
>                     from drivers/hwtracing/coresight/coresight-etb10.c:15:
>    drivers/hwtracing/coresight/coresight-etb10.c: In function 'etb_update_buffer':
>>> drivers/hwtracing/coresight/coresight-etb10.c:431:17: error: 'struct cs_buffers' has no member named 'lost'
>       local_inc(&buf->lost);
>                     ^
>    include/asm-generic/local.h:30:40: note: in definition of macro 'local_inc'

Ah shoot. Peter, can you fold this in:

>From 8272adc208eb2ad874e3952766282624d035ea50 Mon Sep 17 00:00:00 2001
From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Date: Mon, 20 Feb 2017 19:15:27 +0200
Subject: [PATCH] fixup! perf: Keep AUX flags in the output handle

---
 drivers/hwtracing/coresight/coresight-etb10.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 82c8ddcf09..979ea6ec79 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -428,7 +428,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 		if (read_ptr > (drvdata->buffer_depth - 1))
 			read_ptr -= drvdata->buffer_depth;
 		/* let the decoder know we've skipped ahead */
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	/* finally tell HW where we want to start reading from */
-- 
2.11.0

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

* Re: [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
  2017-02-20 17:01   ` kbuild test robot
@ 2017-02-20 20:42   ` Mathieu Poirier
  2017-02-21 10:42   ` Will Deacon
  2017-03-16 11:22   ` [tip:perf/core] perf/core: " tip-bot for Will Deacon
  3 siblings, 0 replies; 22+ messages in thread
From: Mathieu Poirier @ 2017-02-20 20:42 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Peter Zijlstra, Ingo Molnar, linux-kernel, Vince Weaver,
	Stephane Eranian, Arnaldo Carvalho de Melo, Will Deacon

On 20 February 2017 at 06:33, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> From: Will Deacon <will.deacon@arm.com>
>
> In preparation for adding more flags to perf AUX records, introduce a
> separate API for setting the flags for a session, rather than appending
> more bool arguments to perf_aux_output_end. This allows to set each
> flag at the time a corresponding condition is detected, instead of
> tracking it in each driver's private state.
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> ---
>  arch/x86/events/intel/bts.c                      | 16 +++++------
>  arch/x86/events/intel/pt.c                       | 17 ++++++------
>  arch/x86/events/intel/pt.h                       |  1 -
>  drivers/hwtracing/coresight/coresight-etb10.c    |  7 +++--
>  drivers/hwtracing/coresight/coresight-etm-perf.c |  9 +++----
>  drivers/hwtracing/coresight/coresight-priv.h     |  2 --
>  drivers/hwtracing/coresight/coresight-tmc-etf.c  |  7 +++--

For the CS files:
Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org>

>  include/linux/coresight.h                        |  2 +-
>  include/linux/perf_event.h                       |  8 +++---
>  kernel/events/ring_buffer.c                      | 34 ++++++++++++++++--------
>  10 files changed, 55 insertions(+), 48 deletions(-)
>
> diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
> index 982c9e31da..8ae8c5ce3a 100644
> --- a/arch/x86/events/intel/bts.c
> +++ b/arch/x86/events/intel/bts.c
> @@ -63,7 +63,6 @@ struct bts_buffer {
>         unsigned int    cur_buf;
>         bool            snapshot;
>         local_t         data_size;
> -       local_t         lost;
>         local_t         head;
>         unsigned long   end;
>         void            **data_pages;
> @@ -199,7 +198,8 @@ static void bts_update(struct bts_ctx *bts)
>                         return;
>
>                 if (ds->bts_index >= ds->bts_absolute_maximum)
> -                       local_inc(&buf->lost);
> +                       perf_aux_output_flag(&bts->handle,
> +                                            PERF_AUX_FLAG_TRUNCATED);
>
>                 /*
>                  * old and head are always in the same physical buffer, so we
> @@ -276,7 +276,7 @@ static void bts_event_start(struct perf_event *event, int flags)
>         return;
>
>  fail_end_stop:
> -       perf_aux_output_end(&bts->handle, 0, false);
> +       perf_aux_output_end(&bts->handle, 0);
>
>  fail_stop:
>         event->hw.state = PERF_HES_STOPPED;
> @@ -319,9 +319,8 @@ static void bts_event_stop(struct perf_event *event, int flags)
>                                 bts->handle.head =
>                                         local_xchg(&buf->data_size,
>                                                    buf->nr_pages << PAGE_SHIFT);
> -
> -                       perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
> -                                           !!local_xchg(&buf->lost, 0));
> +                       perf_aux_output_end(&bts->handle,
> +                                           local_xchg(&buf->data_size, 0));
>                 }
>
>                 cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
> @@ -484,8 +483,7 @@ int intel_bts_interrupt(void)
>         if (old_head == local_read(&buf->head))
>                 return handled;
>
> -       perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
> -                           !!local_xchg(&buf->lost, 0));
> +       perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0));
>
>         buf = perf_aux_output_begin(&bts->handle, event);
>         if (buf)
> @@ -500,7 +498,7 @@ int intel_bts_interrupt(void)
>                          * cleared handle::event
>                          */
>                         barrier();
> -                       perf_aux_output_end(&bts->handle, 0, false);
> +                       perf_aux_output_end(&bts->handle, 0);
>                 }
>         }
>
> diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
> index d92a60ef08..a2d0050fde 100644
> --- a/arch/x86/events/intel/pt.c
> +++ b/arch/x86/events/intel/pt.c
> @@ -823,7 +823,8 @@ static void pt_handle_status(struct pt *pt)
>                  */
>                 if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
>                     buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
> -                       local_inc(&buf->lost);
> +                       perf_aux_output_flag(&pt->handle,
> +                                            PERF_AUX_FLAG_TRUNCATED);
>                         advance++;
>                 }
>         }
> @@ -916,8 +917,10 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
>
>         /* can't stop in the middle of an output region */
>         if (buf->output_off + handle->size + 1 <
> -           sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
> +           sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
> +               perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
>                 return -EINVAL;
> +       }
>
>
>         /* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
> @@ -1269,8 +1272,7 @@ void intel_pt_interrupt(void)
>
>         pt_update_head(pt);
>
> -       perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
> -                           local_xchg(&buf->lost, 0));
> +       perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
>
>         if (!event->hw.state) {
>                 int ret;
> @@ -1285,7 +1287,7 @@ void intel_pt_interrupt(void)
>                 /* snapshot counters don't use PMI, so it's safe */
>                 ret = pt_buffer_reset_markers(buf, &pt->handle);
>                 if (ret) {
> -                       perf_aux_output_end(&pt->handle, 0, true);
> +                       perf_aux_output_end(&pt->handle, 0);
>                         return;
>                 }
>
> @@ -1357,7 +1359,7 @@ static void pt_event_start(struct perf_event *event, int mode)
>         return;
>
>  fail_end_stop:
> -       perf_aux_output_end(&pt->handle, 0, true);
> +       perf_aux_output_end(&pt->handle, 0);
>  fail_stop:
>         hwc->state = PERF_HES_STOPPED;
>  }
> @@ -1398,8 +1400,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
>                         pt->handle.head =
>                                 local_xchg(&buf->data_size,
>                                            buf->nr_pages << PAGE_SHIFT);
> -               perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
> -                                   local_xchg(&buf->lost, 0));
> +               perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
>         }
>  }
>
> diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
> index fa81f8d8ed..25fa9710f4 100644
> --- a/arch/x86/events/intel/pt.h
> +++ b/arch/x86/events/intel/pt.h
> @@ -144,7 +144,6 @@ struct pt_buffer {
>         size_t                  output_off;
>         unsigned long           nr_pages;
>         local_t                 data_size;
> -       local_t                 lost;
>         local64_t               head;
>         bool                    snapshot;
>         unsigned long           stop_pos, intr_pos;
> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
> index d7325c6534..82c8ddcf09 100644
> --- a/drivers/hwtracing/coresight/coresight-etb10.c
> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
> @@ -321,7 +321,7 @@ static int etb_set_buffer(struct coresight_device *csdev,
>
>  static unsigned long etb_reset_buffer(struct coresight_device *csdev,
>                                       struct perf_output_handle *handle,
> -                                     void *sink_config, bool *lost)
> +                                     void *sink_config)
>  {
>         unsigned long size = 0;
>         struct cs_buffers *buf = sink_config;
> @@ -343,7 +343,6 @@ static unsigned long etb_reset_buffer(struct coresight_device *csdev,
>                  * resetting parameters here and squaring off with the ring
>                  * buffer API in the tracer PMU is fine.
>                  */
> -               *lost = !!local_xchg(&buf->lost, 0);
>                 size = local_xchg(&buf->data_size, 0);
>         }
>
> @@ -385,7 +384,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
>                         (unsigned long)write_ptr);
>
>                 write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1);
> -               local_inc(&buf->lost);
> +               perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
>         }
>
>         /*
> @@ -396,7 +395,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
>          */
>         status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
>         if (status & ETB_STATUS_RAM_FULL) {
> -               local_inc(&buf->lost);
> +               perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
>                 to_read = capacity;
>                 read_ptr = write_ptr;
>         } else {
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index 70eaa74dc2..47ea0eee67 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -301,7 +301,8 @@ static void etm_event_start(struct perf_event *event, int flags)
>         return;
>
>  fail_end_stop:
> -       perf_aux_output_end(handle, 0, true);
> +       perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
> +       perf_aux_output_end(handle, 0);
>  fail:
>         event->hw.state = PERF_HES_STOPPED;
>         goto out;
> @@ -309,7 +310,6 @@ static void etm_event_start(struct perf_event *event, int flags)
>
>  static void etm_event_stop(struct perf_event *event, int mode)
>  {
> -       bool lost;
>         int cpu = smp_processor_id();
>         unsigned long size;
>         struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
> @@ -347,10 +347,9 @@ static void etm_event_stop(struct perf_event *event, int mode)
>                         return;
>
>                 size = sink_ops(sink)->reset_buffer(sink, handle,
> -                                                   event_data->snk_config,
> -                                                   &lost);
> +                                                   event_data->snk_config);
>
> -               perf_aux_output_end(handle, size, lost);
> +               perf_aux_output_end(handle, size);
>         }
>
>         /* Disabling the path make its elements available to other sessions */
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index ef9d8e93e3..5f662d8205 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -76,7 +76,6 @@ enum cs_mode {
>   * @nr_pages:  max number of pages granted to us
>   * @offset:    offset within the current buffer
>   * @data_size: how much we collected in this run
> - * @lost:      other than zero if we had a HW buffer wrap around
>   * @snapshot:  is this run in snapshot mode
>   * @data_pages:        a handle the ring buffer
>   */
> @@ -85,7 +84,6 @@ struct cs_buffers {
>         unsigned int            nr_pages;
>         unsigned long           offset;
>         local_t                 data_size;
> -       local_t                 lost;
>         bool                    snapshot;
>         void                    **data_pages;
>  };
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> index 1549436e24..aec61a6d5c 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> @@ -329,7 +329,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
>
>  static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
>                                           struct perf_output_handle *handle,
> -                                         void *sink_config, bool *lost)
> +                                         void *sink_config)
>  {
>         long size = 0;
>         struct cs_buffers *buf = sink_config;
> @@ -350,7 +350,6 @@ static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
>                  * resetting parameters here and squaring off with the ring
>                  * buffer API in the tracer PMU is fine.
>                  */
> -               *lost = !!local_xchg(&buf->lost, 0);
>                 size = local_xchg(&buf->data_size, 0);
>         }
>
> @@ -389,7 +388,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
>          */
>         status = readl_relaxed(drvdata->base + TMC_STS);
>         if (status & TMC_STS_FULL) {
> -               local_inc(&buf->lost);
> +               perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
>                 to_read = drvdata->size;
>         } else {
>                 to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size);
> @@ -434,7 +433,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
>                         read_ptr -= drvdata->size;
>                 /* Tell the HW */
>                 writel_relaxed(read_ptr, drvdata->base + TMC_RRP);
> -               local_inc(&buf->lost);
> +               perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
>         }
>
>         cur = buf->cur;
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 2a5982c37d..035c16c9a5 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -201,7 +201,7 @@ struct coresight_ops_sink {
>                           void *sink_config);
>         unsigned long (*reset_buffer)(struct coresight_device *csdev,
>                                       struct perf_output_handle *handle,
> -                                     void *sink_config, bool *lost);
> +                                     void *sink_config);
>         void (*update_buffer)(struct coresight_device *csdev,
>                               struct perf_output_handle *handle,
>                               void *sink_config);
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index a39564314e..cdbaa88dc8 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -812,6 +812,7 @@ struct perf_output_handle {
>         struct ring_buffer              *rb;
>         unsigned long                   wakeup;
>         unsigned long                   size;
> +       u64                             aux_flags;
>         union {
>                 void                    *addr;
>                 unsigned long           head;
> @@ -860,10 +861,11 @@ perf_cgroup_from_task(struct task_struct *task, struct perf_event_context *ctx)
>  extern void *perf_aux_output_begin(struct perf_output_handle *handle,
>                                    struct perf_event *event);
>  extern void perf_aux_output_end(struct perf_output_handle *handle,
> -                               unsigned long size, bool truncated);
> +                               unsigned long size);
>  extern int perf_aux_output_skip(struct perf_output_handle *handle,
>                                 unsigned long size);
>  extern void *perf_get_aux(struct perf_output_handle *handle);
> +extern void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags);
>
>  extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
>  extern void perf_pmu_unregister(struct pmu *pmu);
> @@ -1278,8 +1280,8 @@ static inline void *
>  perf_aux_output_begin(struct perf_output_handle *handle,
>                       struct perf_event *event)                         { return NULL; }
>  static inline void
> -perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
> -                   bool truncated)                                     { }
> +perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
> +                                                                       { }
>  static inline int
>  perf_aux_output_skip(struct perf_output_handle *handle,
>                      unsigned long size)                                { return -EINVAL; }
> diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
> index 6415807169..f3ebafe060 100644
> --- a/kernel/events/ring_buffer.c
> +++ b/kernel/events/ring_buffer.c
> @@ -297,6 +297,19 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
>                 rb->paused = 1;
>  }
>
> +void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags)
> +{
> +       /*
> +        * OVERWRITE is determined by perf_aux_output_end() and can't
> +        * be passed in directly.
> +        */
> +       if (WARN_ON_ONCE(flags & PERF_AUX_FLAG_OVERWRITE))
> +               return;
> +
> +       handle->aux_flags |= flags;
> +}
> +EXPORT_SYMBOL_GPL(perf_aux_output_flag);
> +
>  /*
>   * This is called before hardware starts writing to the AUX area to
>   * obtain an output handle and make sure there's room in the buffer.
> @@ -360,6 +373,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
>         handle->event = event;
>         handle->head = aux_head;
>         handle->size = 0;
> +       handle->aux_flags = 0;
>
>         /*
>          * In overwrite mode, AUX data stores do not depend on aux_tail,
> @@ -409,34 +423,32 @@ EXPORT_SYMBOL_GPL(perf_aux_output_begin);
>   * of the AUX buffer management code is that after pmu::stop(), the AUX
>   * transaction must be stopped and therefore drop the AUX reference count.
>   */
> -void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
> -                        bool truncated)
> +void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
>  {
>         struct ring_buffer *rb = handle->rb;
> -       bool wakeup = truncated;
> +       bool wakeup = !!handle->aux_flags;
>         unsigned long aux_head;
> -       u64 flags = 0;
> -
> -       if (truncated)
> -               flags |= PERF_AUX_FLAG_TRUNCATED;
>
>         /* in overwrite mode, driver provides aux_head via handle */
>         if (rb->aux_overwrite) {
> -               flags |= PERF_AUX_FLAG_OVERWRITE;
> +               handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE;
>
>                 aux_head = handle->head;
>                 local_set(&rb->aux_head, aux_head);
>         } else {
> +               handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
> +
>                 aux_head = local_read(&rb->aux_head);
>                 local_add(size, &rb->aux_head);
>         }
>
> -       if (size || flags) {
> +       if (size || handle->aux_flags) {
>                 /*
>                  * Only send RECORD_AUX if we have something useful to communicate
>                  */
>
> -               perf_event_aux_event(handle->event, aux_head, size, flags);
> +               perf_event_aux_event(handle->event, aux_head, size,
> +                                    handle->aux_flags);
>         }
>
>         aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
> @@ -447,7 +459,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
>         }
>
>         if (wakeup) {
> -               if (truncated)
> +               if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)
>                         handle->event->pending_disable = 1;
>                 perf_output_wakeup(handle);
>         }
> --
> 2.11.0
>

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

* Re: [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
  2017-02-20 17:01   ` kbuild test robot
  2017-02-20 20:42   ` Mathieu Poirier
@ 2017-02-21 10:42   ` Will Deacon
  2017-02-21 10:54     ` Alexander Shishkin
  2017-03-16 11:22   ` [tip:perf/core] perf/core: " tip-bot for Will Deacon
  3 siblings, 1 reply; 22+ messages in thread
From: Will Deacon @ 2017-02-21 10:42 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Peter Zijlstra, Ingo Molnar, linux-kernel, vince, eranian,
	Arnaldo Carvalho de Melo, Mathieu Poirier

Hi Alexander,

Thanks for picking this up/adapting it. Just one comment below

On Mon, Feb 20, 2017 at 03:33:50PM +0200, Alexander Shishkin wrote:
> From: Will Deacon <will.deacon@arm.com>
> 
> In preparation for adding more flags to perf AUX records, introduce a
> separate API for setting the flags for a session, rather than appending
> more bool arguments to perf_aux_output_end. This allows to set each
> flag at the time a corresponding condition is detected, instead of
> tracking it in each driver's private state.
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> ---

--->8

> +void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags)
> +{
> +	/*
> +	 * OVERWRITE is determined by perf_aux_output_end() and can't
> +	 * be passed in directly.
> +	 */
> +	if (WARN_ON_ONCE(flags & PERF_AUX_FLAG_OVERWRITE))
> +		return;

Now that you've added this check...

> +	handle->aux_flags |= flags;
> +}
> +EXPORT_SYMBOL_GPL(perf_aux_output_flag);
> +
>  /*
>   * This is called before hardware starts writing to the AUX area to
>   * obtain an output handle and make sure there's room in the buffer.
> @@ -360,6 +373,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
>  	handle->event = event;
>  	handle->head = aux_head;
>  	handle->size = 0;
> +	handle->aux_flags = 0;
>  
>  	/*
>  	 * In overwrite mode, AUX data stores do not depend on aux_tail,
> @@ -409,34 +423,32 @@ EXPORT_SYMBOL_GPL(perf_aux_output_begin);
>   * of the AUX buffer management code is that after pmu::stop(), the AUX
>   * transaction must be stopped and therefore drop the AUX reference count.
>   */
> -void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
> -			 bool truncated)
> +void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
>  {
>  	struct ring_buffer *rb = handle->rb;
> -	bool wakeup = truncated;
> +	bool wakeup = !!handle->aux_flags;
>  	unsigned long aux_head;
> -	u64 flags = 0;
> -
> -	if (truncated)
> -		flags |= PERF_AUX_FLAG_TRUNCATED;
>  
>  	/* in overwrite mode, driver provides aux_head via handle */
>  	if (rb->aux_overwrite) {
> -		flags |= PERF_AUX_FLAG_OVERWRITE;
> +		handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE;
>  
>  		aux_head = handle->head;
>  		local_set(&rb->aux_head, aux_head);
>  	} else {
> +		handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
> +

... I don't think you need this addition anymore. It's harmless, though.

Will

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

* Re: [PATCH 2/4] perf: Keep AUX flags in the output handle
  2017-02-21 10:42   ` Will Deacon
@ 2017-02-21 10:54     ` Alexander Shishkin
  0 siblings, 0 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-02-21 10:54 UTC (permalink / raw)
  To: Will Deacon
  Cc: Peter Zijlstra, Ingo Molnar, linux-kernel, vince, eranian,
	Arnaldo Carvalho de Melo, Mathieu Poirier

Will Deacon <will.deacon@arm.com> writes:

> Hi Alexander,

Hi Will,

>> +		handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
>> +
>
> ... I don't think you need this addition anymore. It's harmless, though.

Right, assuming the PMU driver isn't doing anything fishy to
handle->aux_flags directly.

Regards,
--
Alex

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

* [tip:perf/core] perf/core: Keep AUX flags in the output handle
  2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
                     ` (2 preceding siblings ...)
  2017-02-21 10:42   ` Will Deacon
@ 2017-03-16 11:22   ` tip-bot for Will Deacon
  3 siblings, 0 replies; 22+ messages in thread
From: tip-bot for Will Deacon @ 2017-03-16 11:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, acme, eranian, peterz, linux-kernel, jolsa, tglx,
	mathieu.poirier, alexander.shishkin, vincent.weaver, acme,
	torvalds, will.deacon, mingo

Commit-ID:  f4c0b0aa58d9b7e30ab0a95e33da84d53b3d764a
Gitweb:     http://git.kernel.org/tip/f4c0b0aa58d9b7e30ab0a95e33da84d53b3d764a
Author:     Will Deacon <will.deacon@arm.com>
AuthorDate: Mon, 20 Feb 2017 15:33:50 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 16 Mar 2017 09:51:10 +0100

perf/core: Keep AUX flags in the output handle

In preparation for adding more flags to perf AUX records, introduce a
separate API for setting the flags for a session, rather than appending
more bool arguments to perf_aux_output_end. This allows to set each
flag at the time a corresponding condition is detected, instead of
tracking it in each driver's private state.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: vince@deater.net
Link: http://lkml.kernel.org/r/20170220133352.17995-3-alexander.shishkin@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/events/intel/bts.c                      | 16 +++++------
 arch/x86/events/intel/pt.c                       | 17 ++++++------
 arch/x86/events/intel/pt.h                       |  1 -
 drivers/hwtracing/coresight/coresight-etb10.c    |  9 +++----
 drivers/hwtracing/coresight/coresight-etm-perf.c |  9 +++----
 drivers/hwtracing/coresight/coresight-priv.h     |  2 --
 drivers/hwtracing/coresight/coresight-tmc-etf.c  |  7 +++--
 include/linux/coresight.h                        |  2 +-
 include/linux/perf_event.h                       |  8 +++---
 kernel/events/ring_buffer.c                      | 34 ++++++++++++++++--------
 10 files changed, 56 insertions(+), 49 deletions(-)

diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
index 982c9e3..8ae8c5c 100644
--- a/arch/x86/events/intel/bts.c
+++ b/arch/x86/events/intel/bts.c
@@ -63,7 +63,6 @@ struct bts_buffer {
 	unsigned int	cur_buf;
 	bool		snapshot;
 	local_t		data_size;
-	local_t		lost;
 	local_t		head;
 	unsigned long	end;
 	void		**data_pages;
@@ -199,7 +198,8 @@ static void bts_update(struct bts_ctx *bts)
 			return;
 
 		if (ds->bts_index >= ds->bts_absolute_maximum)
-			local_inc(&buf->lost);
+			perf_aux_output_flag(&bts->handle,
+			                     PERF_AUX_FLAG_TRUNCATED);
 
 		/*
 		 * old and head are always in the same physical buffer, so we
@@ -276,7 +276,7 @@ static void bts_event_start(struct perf_event *event, int flags)
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(&bts->handle, 0, false);
+	perf_aux_output_end(&bts->handle, 0);
 
 fail_stop:
 	event->hw.state = PERF_HES_STOPPED;
@@ -319,9 +319,8 @@ static void bts_event_stop(struct perf_event *event, int flags)
 				bts->handle.head =
 					local_xchg(&buf->data_size,
 						   buf->nr_pages << PAGE_SHIFT);
-
-			perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-					    !!local_xchg(&buf->lost, 0));
+			perf_aux_output_end(&bts->handle,
+			                    local_xchg(&buf->data_size, 0));
 		}
 
 		cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
@@ -484,8 +483,7 @@ int intel_bts_interrupt(void)
 	if (old_head == local_read(&buf->head))
 		return handled;
 
-	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-			    !!local_xchg(&buf->lost, 0));
+	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0));
 
 	buf = perf_aux_output_begin(&bts->handle, event);
 	if (buf)
@@ -500,7 +498,7 @@ int intel_bts_interrupt(void)
 			 * cleared handle::event
 			 */
 			barrier();
-			perf_aux_output_end(&bts->handle, 0, false);
+			perf_aux_output_end(&bts->handle, 0);
 		}
 	}
 
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 5900471..0218728 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -753,7 +753,8 @@ static void pt_handle_status(struct pt *pt)
 		 */
 		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
 		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
-			local_inc(&buf->lost);
+			perf_aux_output_flag(&pt->handle,
+			                     PERF_AUX_FLAG_TRUNCATED);
 			advance++;
 		}
 	}
@@ -846,8 +847,10 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
 
 	/* can't stop in the middle of an output region */
 	if (buf->output_off + handle->size + 1 <
-	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
+	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		return -EINVAL;
+	}
 
 
 	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
@@ -1192,8 +1195,7 @@ void intel_pt_interrupt(void)
 
 	pt_update_head(pt);
 
-	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-			    local_xchg(&buf->lost, 0));
+	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
 
 	if (!event->hw.state) {
 		int ret;
@@ -1208,7 +1210,7 @@ void intel_pt_interrupt(void)
 		/* snapshot counters don't use PMI, so it's safe */
 		ret = pt_buffer_reset_markers(buf, &pt->handle);
 		if (ret) {
-			perf_aux_output_end(&pt->handle, 0, true);
+			perf_aux_output_end(&pt->handle, 0);
 			return;
 		}
 
@@ -1280,7 +1282,7 @@ static void pt_event_start(struct perf_event *event, int mode)
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(&pt->handle, 0, true);
+	perf_aux_output_end(&pt->handle, 0);
 fail_stop:
 	hwc->state = PERF_HES_STOPPED;
 }
@@ -1321,8 +1323,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
 			pt->handle.head =
 				local_xchg(&buf->data_size,
 					   buf->nr_pages << PAGE_SHIFT);
-		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-				    local_xchg(&buf->lost, 0));
+		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
 	}
 }
 
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 53473c2..b528e8f 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -143,7 +143,6 @@ struct pt_buffer {
 	size_t			output_off;
 	unsigned long		nr_pages;
 	local_t			data_size;
-	local_t			lost;
 	local64_t		head;
 	bool			snapshot;
 	unsigned long		stop_pos, intr_pos;
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index d7325c65..979ea6e 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -321,7 +321,7 @@ static int etb_set_buffer(struct coresight_device *csdev,
 
 static unsigned long etb_reset_buffer(struct coresight_device *csdev,
 				      struct perf_output_handle *handle,
-				      void *sink_config, bool *lost)
+				      void *sink_config)
 {
 	unsigned long size = 0;
 	struct cs_buffers *buf = sink_config;
@@ -343,7 +343,6 @@ static unsigned long etb_reset_buffer(struct coresight_device *csdev,
 		 * resetting parameters here and squaring off with the ring
 		 * buffer API in the tracer PMU is fine.
 		 */
-		*lost = !!local_xchg(&buf->lost, 0);
 		size = local_xchg(&buf->data_size, 0);
 	}
 
@@ -385,7 +384,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 			(unsigned long)write_ptr);
 
 		write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1);
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	/*
@@ -396,7 +395,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 	 */
 	status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
 	if (status & ETB_STATUS_RAM_FULL) {
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		to_read = capacity;
 		read_ptr = write_ptr;
 	} else {
@@ -429,7 +428,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
 		if (read_ptr > (drvdata->buffer_depth - 1))
 			read_ptr -= drvdata->buffer_depth;
 		/* let the decoder know we've skipped ahead */
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	/* finally tell HW where we want to start reading from */
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 26cfac3..288a423 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -302,7 +302,8 @@ out:
 	return;
 
 fail_end_stop:
-	perf_aux_output_end(handle, 0, true);
+	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
+	perf_aux_output_end(handle, 0);
 fail:
 	event->hw.state = PERF_HES_STOPPED;
 	goto out;
@@ -310,7 +311,6 @@ fail:
 
 static void etm_event_stop(struct perf_event *event, int mode)
 {
-	bool lost;
 	int cpu = smp_processor_id();
 	unsigned long size;
 	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
@@ -348,10 +348,9 @@ static void etm_event_stop(struct perf_event *event, int mode)
 			return;
 
 		size = sink_ops(sink)->reset_buffer(sink, handle,
-						    event_data->snk_config,
-						    &lost);
+						    event_data->snk_config);
 
-		perf_aux_output_end(handle, size, lost);
+		perf_aux_output_end(handle, size);
 	}
 
 	/* Disabling the path make its elements available to other sessions */
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index ef9d8e9..5f662d8 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -76,7 +76,6 @@ enum cs_mode {
  * @nr_pages:	max number of pages granted to us
  * @offset:	offset within the current buffer
  * @data_size:	how much we collected in this run
- * @lost:	other than zero if we had a HW buffer wrap around
  * @snapshot:	is this run in snapshot mode
  * @data_pages:	a handle the ring buffer
  */
@@ -85,7 +84,6 @@ struct cs_buffers {
 	unsigned int		nr_pages;
 	unsigned long		offset;
 	local_t			data_size;
-	local_t			lost;
 	bool			snapshot;
 	void			**data_pages;
 };
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 1549436..aec61a6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -329,7 +329,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
 
 static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
 					  struct perf_output_handle *handle,
-					  void *sink_config, bool *lost)
+					  void *sink_config)
 {
 	long size = 0;
 	struct cs_buffers *buf = sink_config;
@@ -350,7 +350,6 @@ static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
 		 * resetting parameters here and squaring off with the ring
 		 * buffer API in the tracer PMU is fine.
 		 */
-		*lost = !!local_xchg(&buf->lost, 0);
 		size = local_xchg(&buf->data_size, 0);
 	}
 
@@ -389,7 +388,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
 	 */
 	status = readl_relaxed(drvdata->base + TMC_STS);
 	if (status & TMC_STS_FULL) {
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 		to_read = drvdata->size;
 	} else {
 		to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size);
@@ -434,7 +433,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
 			read_ptr -= drvdata->size;
 		/* Tell the HW */
 		writel_relaxed(read_ptr, drvdata->base + TMC_RRP);
-		local_inc(&buf->lost);
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	}
 
 	cur = buf->cur;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2a5982c..035c16c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -201,7 +201,7 @@ struct coresight_ops_sink {
 			  void *sink_config);
 	unsigned long (*reset_buffer)(struct coresight_device *csdev,
 				      struct perf_output_handle *handle,
-				      void *sink_config, bool *lost);
+				      void *sink_config);
 	void (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f19a823..b6e75c9 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -801,6 +801,7 @@ struct perf_output_handle {
 	struct ring_buffer		*rb;
 	unsigned long			wakeup;
 	unsigned long			size;
+	u64				aux_flags;
 	union {
 		void			*addr;
 		unsigned long		head;
@@ -849,10 +850,11 @@ perf_cgroup_from_task(struct task_struct *task, struct perf_event_context *ctx)
 extern void *perf_aux_output_begin(struct perf_output_handle *handle,
 				   struct perf_event *event);
 extern void perf_aux_output_end(struct perf_output_handle *handle,
-				unsigned long size, bool truncated);
+				unsigned long size);
 extern int perf_aux_output_skip(struct perf_output_handle *handle,
 				unsigned long size);
 extern void *perf_get_aux(struct perf_output_handle *handle);
+extern void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags);
 
 extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
 extern void perf_pmu_unregister(struct pmu *pmu);
@@ -1268,8 +1270,8 @@ static inline void *
 perf_aux_output_begin(struct perf_output_handle *handle,
 		      struct perf_event *event)				{ return NULL; }
 static inline void
-perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
-		    bool truncated)					{ }
+perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
+									{ }
 static inline int
 perf_aux_output_skip(struct perf_output_handle *handle,
 		     unsigned long size)				{ return -EINVAL; }
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 257fa46..9654e55 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -297,6 +297,19 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
 		rb->paused = 1;
 }
 
+void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags)
+{
+	/*
+	 * OVERWRITE is determined by perf_aux_output_end() and can't
+	 * be passed in directly.
+	 */
+	if (WARN_ON_ONCE(flags & PERF_AUX_FLAG_OVERWRITE))
+		return;
+
+	handle->aux_flags |= flags;
+}
+EXPORT_SYMBOL_GPL(perf_aux_output_flag);
+
 /*
  * This is called before hardware starts writing to the AUX area to
  * obtain an output handle and make sure there's room in the buffer.
@@ -360,6 +373,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
 	handle->event = event;
 	handle->head = aux_head;
 	handle->size = 0;
+	handle->aux_flags = 0;
 
 	/*
 	 * In overwrite mode, AUX data stores do not depend on aux_tail,
@@ -408,34 +422,32 @@ err:
  * of the AUX buffer management code is that after pmu::stop(), the AUX
  * transaction must be stopped and therefore drop the AUX reference count.
  */
-void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
-			 bool truncated)
+void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
 	struct ring_buffer *rb = handle->rb;
-	bool wakeup = truncated;
+	bool wakeup = !!handle->aux_flags;
 	unsigned long aux_head;
-	u64 flags = 0;
-
-	if (truncated)
-		flags |= PERF_AUX_FLAG_TRUNCATED;
 
 	/* in overwrite mode, driver provides aux_head via handle */
 	if (rb->aux_overwrite) {
-		flags |= PERF_AUX_FLAG_OVERWRITE;
+		handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE;
 
 		aux_head = handle->head;
 		local_set(&rb->aux_head, aux_head);
 	} else {
+		handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
+
 		aux_head = local_read(&rb->aux_head);
 		local_add(size, &rb->aux_head);
 	}
 
-	if (size || flags) {
+	if (size || handle->aux_flags) {
 		/*
 		 * Only send RECORD_AUX if we have something useful to communicate
 		 */
 
-		perf_event_aux_event(handle->event, aux_head, size, flags);
+		perf_event_aux_event(handle->event, aux_head, size,
+		                     handle->aux_flags);
 	}
 
 	aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
@@ -446,7 +458,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
 	}
 
 	if (wakeup) {
-		if (truncated)
+		if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)
 			handle->event->pending_disable = 1;
 		perf_output_wakeup(handle);
 	}

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

* [tip:perf/core] perf/core: Add a flag for partial AUX records
  2017-02-20 13:33 ` [PATCH 3/4] perf: Add a flag for partial AUX records Alexander Shishkin
@ 2017-03-16 11:23   ` tip-bot for Alexander Shishkin
  2017-03-16 14:24     ` Vince Weaver
  0 siblings, 1 reply; 22+ messages in thread
From: tip-bot for Alexander Shishkin @ 2017-03-16 11:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, linux-kernel, jolsa, vincent.weaver, mathieu.poirier, acme,
	hpa, torvalds, peterz, alexander.shishkin, eranian, acme, mingo

Commit-ID:  ae0c2d995d648d5165545d5e05e2869642009b38
Gitweb:     http://git.kernel.org/tip/ae0c2d995d648d5165545d5e05e2869642009b38
Author:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
AuthorDate: Mon, 20 Feb 2017 15:33:51 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 16 Mar 2017 09:51:11 +0100

perf/core: Add a flag for partial AUX records

The Intel PT driver needs to be able to communicate partial AUX transactions,
that is, transactions with gaps in data for reasons other than no room
left in the buffer (i.e. truncated transactions). Therefore, this condition
does not imply a wakeup for the consumer.

To this end, add a new "partial" AUX flag.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: vince@deater.net
Link: http://lkml.kernel.org/r/20170220133352.17995-4-alexander.shishkin@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/uapi/linux/perf_event.h | 1 +
 kernel/events/ring_buffer.c     | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index bec0aad..d09a9cd 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -915,6 +915,7 @@ enum perf_callchain_context {
  */
 #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
 #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
+#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
 
 #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
 #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 9654e55..2831480 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -424,8 +424,8 @@ err:
  */
 void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
+	bool wakeup = !!(handle->aux_flags & PERF_AUX_FLAG_TRUNCATED);
 	struct ring_buffer *rb = handle->rb;
-	bool wakeup = !!handle->aux_flags;
 	unsigned long aux_head;
 
 	/* in overwrite mode, driver provides aux_head via handle */

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

* [tip:perf/core] perf/x86/intel/pt: Handle VMX better
  2017-02-20 13:33 ` [PATCH 4/4] perf/x86/intel/pt: Handle VMX better Alexander Shishkin
@ 2017-03-16 11:24   ` tip-bot for Alexander Shishkin
  0 siblings, 0 replies; 22+ messages in thread
From: tip-bot for Alexander Shishkin @ 2017-03-16 11:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, peterz, mingo, torvalds, jolsa,
	alexander.shishkin, vincent.weaver, acme, hpa, tglx, eranian

Commit-ID:  ee368428aac96d94a9804b9109a81355451c3cd9
Gitweb:     http://git.kernel.org/tip/ee368428aac96d94a9804b9109a81355451c3cd9
Author:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
AuthorDate: Mon, 20 Feb 2017 15:33:52 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 16 Mar 2017 09:51:11 +0100

perf/x86/intel/pt: Handle VMX better

Since commit:

  1c5ac21a0e ("perf/x86/intel/pt: Don't die on VMXON")

... PT events depend on re-scheduling to get enabled after a VMX session
has taken place. This is, in particular, a problem for CPU context events,
which don't normally get re-scheduled, unless there is a reason.

This patch changes the VMX handling so that PT event gets re-enabled
when VMX root mode exits.

Also, notify the user when there's a gap in PT data due to VMX root
mode by flagging AUX records as partial.

In combination with vmm_exclusive=0 parameter of the kvm_intel driver,
this will result in trace gaps only for the duration of the guest's
timeslices.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: vince@deater.net
Link: http://lkml.kernel.org/r/20170220133352.17995-5-alexander.shishkin@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/events/intel/pt.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 0218728..354e9ff 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -411,6 +411,7 @@ static u64 pt_config_filters(struct perf_event *event)
 
 static void pt_config(struct perf_event *event)
 {
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	u64 reg;
 
 	if (!event->hw.itrace_started) {
@@ -429,11 +430,15 @@ static void pt_config(struct perf_event *event)
 	reg |= (event->attr.config & PT_CONFIG_MASK);
 
 	event->hw.config = reg;
-	wrmsrl(MSR_IA32_RTIT_CTL, reg);
+	if (READ_ONCE(pt->vmx_on))
+		perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
+	else
+		wrmsrl(MSR_IA32_RTIT_CTL, reg);
 }
 
 static void pt_config_stop(struct perf_event *event)
 {
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	u64 ctl = READ_ONCE(event->hw.config);
 
 	/* may be already stopped by a PMI */
@@ -441,7 +446,8 @@ static void pt_config_stop(struct perf_event *event)
 		return;
 
 	ctl &= ~RTIT_CTL_TRACEEN;
-	wrmsrl(MSR_IA32_RTIT_CTL, ctl);
+	if (!READ_ONCE(pt->vmx_on))
+		wrmsrl(MSR_IA32_RTIT_CTL, ctl);
 
 	WRITE_ONCE(event->hw.config, ctl);
 
@@ -1174,12 +1180,6 @@ void intel_pt_interrupt(void)
 	if (!READ_ONCE(pt->handle_nmi))
 		return;
 
-	/*
-	 * If VMX is on and PT does not support it, don't touch anything.
-	 */
-	if (READ_ONCE(pt->vmx_on))
-		return;
-
 	if (!event)
 		return;
 
@@ -1239,12 +1239,19 @@ void intel_pt_handle_vmx(int on)
 	local_irq_save(flags);
 	WRITE_ONCE(pt->vmx_on, on);
 
-	if (on) {
-		/* prevent pt_config_stop() from writing RTIT_CTL */
-		event = pt->handle.event;
-		if (event)
-			event->hw.config = 0;
-	}
+	/*
+	 * If an AUX transaction is in progress, it will contain
+	 * gap(s), so flag it PARTIAL to inform the user.
+	 */
+	event = pt->handle.event;
+	if (event)
+		perf_aux_output_flag(&pt->handle,
+		                     PERF_AUX_FLAG_PARTIAL);
+
+	/* Turn PTs back on */
+	if (!on && event)
+		wrmsrl(MSR_IA32_RTIT_CTL, event->hw.config);
+
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(intel_pt_handle_vmx);
@@ -1259,9 +1266,6 @@ static void pt_event_start(struct perf_event *event, int mode)
 	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	struct pt_buffer *buf;
 
-	if (READ_ONCE(pt->vmx_on))
-		return;
-
 	buf = perf_aux_output_begin(&pt->handle, event);
 	if (!buf)
 		goto fail_stop;

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

* Re: [tip:perf/core] perf/core: Add a flag for partial AUX records
  2017-03-16 11:23   ` [tip:perf/core] perf/core: " tip-bot for Alexander Shishkin
@ 2017-03-16 14:24     ` Vince Weaver
  0 siblings, 0 replies; 22+ messages in thread
From: Vince Weaver @ 2017-03-16 14:24 UTC (permalink / raw)
  To: hpa, torvalds, eranian, peterz, alexander.shishkin, mingo, acme,
	tglx, jolsa, linux-kernel, vincent.weaver, mathieu.poirier, acme
  Cc: linux-tip-commits

On Thu, 16 Mar 2017, tip-bot for Alexander Shishkin wrote:

> Commit-ID:  ae0c2d995d648d5165545d5e05e2869642009b38

> perf/core: Add a flag for partial AUX records
> 
> The Intel PT driver needs to be able to communicate partial AUX transactions,
> that is, transactions with gaps in data for reasons other than no room
> left in the buffer (i.e. truncated transactions). Therefore, this condition
> does not imply a wakeup for the consumer.
> 
> To this end, add a new "partial" AUX flag.

...

> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index bec0aad..d09a9cd 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -915,6 +915,7 @@ enum perf_callchain_context {
>   */
>  #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
>  #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
> +#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */


was this included in the wrong patch?  It adds the flag but nothing uses 
it?  Though it appears a later patch makes use of it.  

This makes it confusing when trying to update the perf_event_open.2 
manpage, as the git commit that adds the new ABI to perf_event.h doesn't 
seem to have anything to do with any behavior affected by it.

>  #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
>  #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
> diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
> index 9654e55..2831480 100644
> --- a/kernel/events/ring_buffer.c
> +++ b/kernel/events/ring_buffer.c
> @@ -424,8 +424,8 @@ err:
>   */
>  void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
>  {
> +	bool wakeup = !!(handle->aux_flags & PERF_AUX_FLAG_TRUNCATED);
>  	struct ring_buffer *rb = handle->rb;
> -	bool wakeup = !!handle->aux_flags;
>  	unsigned long aux_head;
>  

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

* Re: [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update
  2017-02-20 16:09     ` Arnaldo Carvalho de Melo
  2017-02-20 16:31       ` Alexander Shishkin
@ 2017-03-16 16:41       ` Alexander Shishkin
  2017-03-21  6:50         ` [tip:perf/core] tools lib api fs: Introduce sysfs__read_bool tip-bot for Alexander Shishkin
                           ` (2 more replies)
  1 sibling, 3 replies; 22+ messages in thread
From: Alexander Shishkin @ 2017-03-16 16:41 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Adrian Hunter, Arnaldo Carvalho de Melo, linux-kernel, vince,
	eranian, Peter Zijlstra, Ingo Molnar

Arnaldo Carvalho de Melo <acme@kernel.org> writes:

> Em Mon, Feb 20, 2017 at 05:39:43PM +0200, Adrian Hunter escreveu:
>> On 20/02/17 17:18, Alexander Shishkin wrote:
>> > Alexander Shishkin <alexander.shishkin@linux.intel.com> writes:
>> > 
>> >> With the vmm_exclusive=0, PT seems to be much more usable on BDW now. This
>> >> patchset does three things:
>> >>  * adds a flag to PERF_RECORD_AUX, signalling that a transaction has gaps
>> >>    in it (due to VMX root mode kicking in),
>> > 
>> > In the above context, will something like this be fine?
>  
>> Looks fine to me.
>  
>> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>> 
>> > From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> > Subject: [PATCH] perf tools: Handle partial AUX records and print a warning
>
>> > This patch decodes the 'partial' flag in AUX records and prints
>> > a warning to the user, so that they don't have to guess why their
>> > PT traces contain gaps (or missing altogether):
>
>> >> Warning:
>> >> AUX data had gaps in it 6 times out of 8!
>
> The above should be left for a more verbose mode?

Other similar warnings come at the default verbosity level (that is,
same as this one), so I thought I'd just follow their example. It's
useful information though, you can make deductions based on how many
records are 'partial'. If it's all of them, then you should likely stop
trying to trace kvm process, for example.

>> >> Are you running a KVM guest in the background?
>
> The warning should be a bit more precise, as you said, tuning
> vmm_exclusive is key here, i.e.:
>
> "Are you running a KVM guest in the background with
> kvm_intel.vmm_exclusive=1?"
>
> And that we can even figure out, its just a matter of reading:
>
> [root@jouet ~]# cat /sys/module/kvm_intel/parameters/vmm_exclusive
> Y

Indeed, how about something like below? I'm kind of new to wording
user-friendly warnings, but the general idea is like what you're
suggesting.

>From cdd8fc60c2f82250871b84b4ac0841f740719f49 Mon Sep 17 00:00:00 2001
From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Date: Mon, 20 Feb 2017 17:08:53 +0200
Subject: [PATCH] perf tools: Handle partial AUX records and print a warning

This patch decodes the 'partial' flag in AUX records and prints
a warning to the user, so that they don't have to guess why their
PT traces contain gaps (or missing altogether):

> Warning:
> AUX data had gaps in it 8 times out of 8!
>
> Are you running a KVM guest in the background?

Trying to be even more helpful, we will detect if the user's
kvm driver sets up exclusive VMX root mode for the entire
lifespan of the kvm process:

> Reloading kvm_intel module with vmm_exclusive=0
> will reduce the gaps to only guest's timeslices.

Note however, that you'll still have gaps in cpu-wide traces
even with vmm_exclusive=0, but the number of gaps will be
below 100% (as opposed to the above example).

Currently this is the only reason for partial records.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 tools/include/uapi/linux/perf_event.h |  1 +
 tools/lib/api/fs/fs.c                 | 29 +++++++++++++++++++++++++++++
 tools/lib/api/fs/fs.h                 |  1 +
 tools/perf/util/event.c               |  5 +++--
 tools/perf/util/event.h               |  1 +
 tools/perf/util/session.c             | 27 ++++++++++++++++++++++++---
 6 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index bec0aad0e1..d09a9cd021 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -915,6 +915,7 @@ enum perf_callchain_context {
  */
 #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
 #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
+#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
 
 #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
 #define PERF_FLAG_FD_OUTPUT		(1UL << 1)
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 4b6bfc43cc..809c7721cd 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -439,6 +439,35 @@ int sysfs__read_str(const char *entry, char **buf, size_t *sizep)
 	return filename__read_str(path, buf, sizep);
 }
 
+int sysfs__read_bool(const char *entry, bool *value)
+{
+	char *buf;
+	size_t size;
+	int ret;
+
+	ret = sysfs__read_str(entry, &buf, &size);
+	if (ret < 0)
+		return ret;
+
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		*value = true;
+		break;
+	case '0':
+	case 'n':
+	case 'N':
+		*value = false;
+		break;
+	default:
+		ret = -1;
+	}
+
+	free(buf);
+
+	return ret;
+}
 int sysctl__read_int(const char *sysctl, int *value)
 {
 	char path[PATH_MAX];
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index 6b332dc744..956c21127d 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -37,4 +37,5 @@ int sysctl__read_int(const char *sysctl, int *value);
 int sysfs__read_int(const char *entry, int *value);
 int sysfs__read_ull(const char *entry, unsigned long long *value);
 int sysfs__read_str(const char *entry, char **buf, size_t *sizep);
+int sysfs__read_bool(const char *entry, bool *value);
 #endif /* __API_FS__ */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d082cb7044..a042822834 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1288,11 +1288,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
 
 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
 {
-	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
+	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
 		       event->aux.aux_offset, event->aux.aux_size,
 		       event->aux.flags,
 		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
-		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
+		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
+		       event->aux.flags & PERF_AUX_FLAG_PARTIAL   ? "P" : "");
 }
 
 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index e1d8166ebb..eb7a7b2007 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -276,6 +276,7 @@ struct events_stats {
 	u64 total_lost;
 	u64 total_lost_samples;
 	u64 total_aux_lost;
+	u64 total_aux_partial;
 	u64 total_invalid_chains;
 	u32 nr_events[PERF_RECORD_HEADER_MAX];
 	u32 nr_non_filtered_samples;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ae42e742d4..24259bc2c5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <traceevent/event-parse.h>
+#include <api/fs/fs.h>
 
 #include <byteswap.h>
 #include <unistd.h>
@@ -1260,9 +1261,12 @@ static int machines__deliver_event(struct machines *machines,
 	case PERF_RECORD_UNTHROTTLE:
 		return tool->unthrottle(tool, event, sample, machine);
 	case PERF_RECORD_AUX:
-		if (tool->aux == perf_event__process_aux &&
-		    (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
-			evlist->stats.total_aux_lost += 1;
+		if (tool->aux == perf_event__process_aux) {
+			if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
+				evlist->stats.total_aux_lost += 1;
+			if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
+				evlist->stats.total_aux_partial += 1;
+		}
 		return tool->aux(tool, event, sample, machine);
 	case PERF_RECORD_ITRACE_START:
 		return tool->itrace_start(tool, event, sample, machine);
@@ -1555,6 +1559,23 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
 			    stats->nr_events[PERF_RECORD_AUX]);
 	}
 
+	if (session->tool->aux == perf_event__process_aux &&
+	    stats->total_aux_partial != 0) {
+		bool vmm_exclusive = false;
+
+		(void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
+		                       &vmm_exclusive);
+
+		ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
+		            "Are you running a KVM guest in the background?%s\n\n",
+			    stats->total_aux_partial,
+			    stats->nr_events[PERF_RECORD_AUX],
+			    vmm_exclusive ?
+			    "\nReloading kvm_intel module with vmm_exclusive=0\n"
+			    "will reduce the gaps to only guest's timeslices." :
+			    "");
+	}
+
 	if (stats->nr_unknown_events != 0) {
 		ui__warning("Found %u unknown events!\n\n"
 			    "Is this an older tool processing a perf.data "
-- 
2.11.0

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

* [tip:perf/core] tools lib api fs: Introduce sysfs__read_bool
  2017-03-16 16:41       ` Alexander Shishkin
@ 2017-03-21  6:50         ` tip-bot for Alexander Shishkin
  2017-03-21  6:51         ` [tip:perf/core] tools include: Sync {,tools/}include/uapi/linux/perf_event.h tip-bot for Alexander Shishkin
  2017-03-21  6:51         ` [tip:perf/core] perf tools: Handle partial AUX records and print a warning tip-bot for Alexander Shishkin
  2 siblings, 0 replies; 22+ messages in thread
From: tip-bot for Alexander Shishkin @ 2017-03-21  6:50 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, adrian.hunter, acme, a.p.zijlstra, alexander.shishkin,
	tglx, eranian, vince, hpa, linux-kernel

Commit-ID:  b9835a90084bd3cc45d7ab80c37f282046bc13d3
Gitweb:     http://git.kernel.org/tip/b9835a90084bd3cc45d7ab80c37f282046bc13d3
Author:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
AuthorDate: Thu, 16 Mar 2017 18:41:59 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 17 Mar 2017 11:49:09 -0300

tools lib api fs: Introduce sysfs__read_bool

Will be used in a upcoming patch warning about PERF_RECORD_AUX data
gaps, reading the "module/kvm_intel/parameters/vmm_exclusive" sysfs
entry.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vince@deater.net>
Link: http://lkml.kernel.org/r/8760j941ig.fsf@ashishki-desk.ger.corp.intel.com
[ split from a larger patch ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/api/fs/fs.c | 29 +++++++++++++++++++++++++++++
 tools/lib/api/fs/fs.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 4b6bfc4..809c772 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -439,6 +439,35 @@ int sysfs__read_str(const char *entry, char **buf, size_t *sizep)
 	return filename__read_str(path, buf, sizep);
 }
 
+int sysfs__read_bool(const char *entry, bool *value)
+{
+	char *buf;
+	size_t size;
+	int ret;
+
+	ret = sysfs__read_str(entry, &buf, &size);
+	if (ret < 0)
+		return ret;
+
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		*value = true;
+		break;
+	case '0':
+	case 'n':
+	case 'N':
+		*value = false;
+		break;
+	default:
+		ret = -1;
+	}
+
+	free(buf);
+
+	return ret;
+}
 int sysctl__read_int(const char *sysctl, int *value)
 {
 	char path[PATH_MAX];
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index 6b332dc..956c211 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -37,4 +37,5 @@ int sysctl__read_int(const char *sysctl, int *value);
 int sysfs__read_int(const char *entry, int *value);
 int sysfs__read_ull(const char *entry, unsigned long long *value);
 int sysfs__read_str(const char *entry, char **buf, size_t *sizep);
+int sysfs__read_bool(const char *entry, bool *value);
 #endif /* __API_FS__ */

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

* [tip:perf/core] tools include: Sync {,tools/}include/uapi/linux/perf_event.h
  2017-03-16 16:41       ` Alexander Shishkin
  2017-03-21  6:50         ` [tip:perf/core] tools lib api fs: Introduce sysfs__read_bool tip-bot for Alexander Shishkin
@ 2017-03-21  6:51         ` tip-bot for Alexander Shishkin
  2017-03-21  6:51         ` [tip:perf/core] perf tools: Handle partial AUX records and print a warning tip-bot for Alexander Shishkin
  2 siblings, 0 replies; 22+ messages in thread
From: tip-bot for Alexander Shishkin @ 2017-03-21  6:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: eranian, a.p.zijlstra, tglx, linux-kernel, mingo, hpa, vince,
	acme, adrian.hunter, alexander.shishkin

Commit-ID:  38a33f07122f6e6194bf5402c0cd057d1cc50be8
Gitweb:     http://git.kernel.org/tip/38a33f07122f6e6194bf5402c0cd057d1cc50be8
Author:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
AuthorDate: Thu, 16 Mar 2017 18:41:59 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 17 Mar 2017 11:49:09 -0300

tools include: Sync {,tools/}include/uapi/linux/perf_event.h

To get PERF_AUX_FLAG_PARTIAL, introduced in:

  ae0c2d995d64 ("perf/core: Add a flag for partial AUX records")

and that will be used to warn the user about gaps in AUX records due
to VMX being used in KVM guests.

Silences the kernel/tools file copy detector:

  Warning: include/uapi/linux/perf_event.h differs from kernel

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vince@deater.net>
Link: http://lkml.kernel.org/r/8760j941ig.fsf@ashishki-desk.ger.corp.intel.com
[ Split from a larger patch ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/include/uapi/linux/perf_event.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index bec0aad..d09a9cd 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -915,6 +915,7 @@ enum perf_callchain_context {
  */
 #define PERF_AUX_FLAG_TRUNCATED		0x01	/* record was truncated to fit */
 #define PERF_AUX_FLAG_OVERWRITE		0x02	/* snapshot from overwrite mode */
+#define PERF_AUX_FLAG_PARTIAL		0x04	/* record contains gaps */
 
 #define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
 #define PERF_FLAG_FD_OUTPUT		(1UL << 1)

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

* [tip:perf/core] perf tools: Handle partial AUX records and print a warning
  2017-03-16 16:41       ` Alexander Shishkin
  2017-03-21  6:50         ` [tip:perf/core] tools lib api fs: Introduce sysfs__read_bool tip-bot for Alexander Shishkin
  2017-03-21  6:51         ` [tip:perf/core] tools include: Sync {,tools/}include/uapi/linux/perf_event.h tip-bot for Alexander Shishkin
@ 2017-03-21  6:51         ` tip-bot for Alexander Shishkin
  2 siblings, 0 replies; 22+ messages in thread
From: tip-bot for Alexander Shishkin @ 2017-03-21  6:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, vince, hpa, tglx, adrian.hunter, a.p.zijlstra,
	acme, alexander.shishkin, eranian, mingo

Commit-ID:  05a1f47ed47a83736aca117aeee96e926cc0dfd0
Gitweb:     http://git.kernel.org/tip/05a1f47ed47a83736aca117aeee96e926cc0dfd0
Author:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
AuthorDate: Thu, 16 Mar 2017 18:41:59 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 17 Mar 2017 11:52:18 -0300

perf tools: Handle partial AUX records and print a warning

This patch decodes the 'partial' flag in AUX records and prints
a warning to the user, so that they don't have to guess why their
PT traces contain gaps (or missing altogether):

  Warning:
  AUX data had gaps in it 8 times out of 8!

  Are you running a KVM guest in the background?

Trying to be even more helpful, we will detect if the user's kvm driver sets up
exclusive VMX root mode for the entire lifespan of the kvm process:

  Reloading kvm_intel module with vmm_exclusive=0
  will reduce the gaps to only guest's timeslices.

Note however, that you'll still have gaps in cpu-wide traces even with
vmm_exclusive=0, but the number of gaps will be below 100% (as opposed to the
above example).

Currently this is the only reason for partial records.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vince@deater.net>
Link: http://lkml.kernel.org/r/8760j941ig.fsf@ashishki-desk.ger.corp.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c   |  5 +++--
 tools/perf/util/event.h   |  1 +
 tools/perf/util/session.c | 27 ++++++++++++++++++++++++---
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 33fc2e9..76b9c6b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1288,11 +1288,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
 
 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
 {
-	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
+	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
 		       event->aux.aux_offset, event->aux.aux_size,
 		       event->aux.flags,
 		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
-		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
+		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
+		       event->aux.flags & PERF_AUX_FLAG_PARTIAL   ? "P" : "");
 }
 
 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index e1d8166..eb7a7b2 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -276,6 +276,7 @@ struct events_stats {
 	u64 total_lost;
 	u64 total_lost_samples;
 	u64 total_aux_lost;
+	u64 total_aux_partial;
 	u64 total_invalid_chains;
 	u32 nr_events[PERF_RECORD_HEADER_MAX];
 	u32 nr_non_filtered_samples;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ae42e74..24259bc2 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <traceevent/event-parse.h>
+#include <api/fs/fs.h>
 
 #include <byteswap.h>
 #include <unistd.h>
@@ -1260,9 +1261,12 @@ static int machines__deliver_event(struct machines *machines,
 	case PERF_RECORD_UNTHROTTLE:
 		return tool->unthrottle(tool, event, sample, machine);
 	case PERF_RECORD_AUX:
-		if (tool->aux == perf_event__process_aux &&
-		    (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
-			evlist->stats.total_aux_lost += 1;
+		if (tool->aux == perf_event__process_aux) {
+			if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
+				evlist->stats.total_aux_lost += 1;
+			if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
+				evlist->stats.total_aux_partial += 1;
+		}
 		return tool->aux(tool, event, sample, machine);
 	case PERF_RECORD_ITRACE_START:
 		return tool->itrace_start(tool, event, sample, machine);
@@ -1555,6 +1559,23 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
 			    stats->nr_events[PERF_RECORD_AUX]);
 	}
 
+	if (session->tool->aux == perf_event__process_aux &&
+	    stats->total_aux_partial != 0) {
+		bool vmm_exclusive = false;
+
+		(void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
+		                       &vmm_exclusive);
+
+		ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
+		            "Are you running a KVM guest in the background?%s\n\n",
+			    stats->total_aux_partial,
+			    stats->nr_events[PERF_RECORD_AUX],
+			    vmm_exclusive ?
+			    "\nReloading kvm_intel module with vmm_exclusive=0\n"
+			    "will reduce the gaps to only guest's timeslices." :
+			    "");
+	}
+
 	if (stats->nr_unknown_events != 0) {
 		ui__warning("Found %u unknown events!\n\n"
 			    "Is this an older tool processing a perf.data "

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

end of thread, other threads:[~2017-03-21  6:51 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-20 13:33 [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
2017-02-20 13:33 ` [PATCH 1/4] perf: Export AUX buffer helpers to modules Alexander Shishkin
2017-02-20 13:33 ` [PATCH 2/4] perf: Keep AUX flags in the output handle Alexander Shishkin
2017-02-20 17:01   ` kbuild test robot
2017-02-20 17:17     ` Alexander Shishkin
2017-02-20 20:42   ` Mathieu Poirier
2017-02-21 10:42   ` Will Deacon
2017-02-21 10:54     ` Alexander Shishkin
2017-03-16 11:22   ` [tip:perf/core] perf/core: " tip-bot for Will Deacon
2017-02-20 13:33 ` [PATCH 3/4] perf: Add a flag for partial AUX records Alexander Shishkin
2017-03-16 11:23   ` [tip:perf/core] perf/core: " tip-bot for Alexander Shishkin
2017-03-16 14:24     ` Vince Weaver
2017-02-20 13:33 ` [PATCH 4/4] perf/x86/intel/pt: Handle VMX better Alexander Shishkin
2017-03-16 11:24   ` [tip:perf/core] " tip-bot for Alexander Shishkin
2017-02-20 15:18 ` [PATCH 0/4] perf, pt, coresight: AUX flags and VMX update Alexander Shishkin
2017-02-20 15:39   ` Adrian Hunter
2017-02-20 16:09     ` Arnaldo Carvalho de Melo
2017-02-20 16:31       ` Alexander Shishkin
2017-03-16 16:41       ` Alexander Shishkin
2017-03-21  6:50         ` [tip:perf/core] tools lib api fs: Introduce sysfs__read_bool tip-bot for Alexander Shishkin
2017-03-21  6:51         ` [tip:perf/core] tools include: Sync {,tools/}include/uapi/linux/perf_event.h tip-bot for Alexander Shishkin
2017-03-21  6:51         ` [tip:perf/core] perf tools: Handle partial AUX records and print a warning tip-bot for Alexander Shishkin

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.