Skip to contentSkip to conversation

Add perf context support for ARMv7

PATCH Superseded Julien Desfossez 2 participants 4 messages Jun 27, 2016 3 messages not in the archive

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH v3 2/2 Add perf context support for ARMv7

Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call every time a counter needs to be read which has a significant performance impact.

ARMv7 does not have way to read PMU from userspace because it requires write access to the debug coprocessor to select which PMU counter to read which defeats user-space/kernel protection. For that reason, the bits required to allow user-space access to those registers are not enabled in the kernel and Perf does not expose any information in the shared mmap page, so we do not know what is the counter index. Also, for ARMv7 we cannot set the exclude_kernel flag, so the counter stays active even when the process is executing in kernel context (system calls mainly).

This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code.

---
 configure.ac                               |  1 +
 liblttng-ust-ctl/ustctl.c                  |  2 +-
 liblttng-ust/lttng-context-perf-counters.c | 79 ++++++++++++++++++++++++++----
 3 files changed, 71 insertions(+), 11 deletions(-)
configure.ac +1 -0
index 105b46f..a966732 100644
@@ -222,6 +222,7 @@ AS_CASE([$host_cpu],
 	[i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
+	[armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no])
 AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS])
 
liblttng-ust-ctl/ustctl.c +1 -1
index 0165786..97445d5 100644
@@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream,
 	return client_cb->instance_id(buf, handle, id);
 }
 
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__)
 
 int ustctl_has_perf_counters(void)
 {
liblttng-ust/lttng-context-perf-counters.c +69 -10

135 lines not on this page · raw message

Signature · 6 lines
1.9.1

_______________________________________________
lttng-dev mailing list
[email protected]
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw
In reply to a message not in the archive
Quoted 152 lines · ----- On Jun 27, 2016, at 5:34 PM, Julien Desfossez [email protected]…

Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call every time a counter needs to be read which has a significant performance impact.

ARMv7 does not have way to read PMU from userspace because it requires write access to the debug coprocessor to select which PMU counter to read which defeats user-space/kernel protection. For that reason, the bits required to allow user-space access to those registers are not enabled in the kernel and Perf does not expose any information in the shared mmap page, so we do not know what is the counter index. Also, for ARMv7 we cannot set the exclude_kernel flag, so the counter stays active even when the process is executing in kernel context (system calls mainly).

This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code.

---

configure.ac                               |  1 +
liblttng-ust-ctl/ustctl.c                  |  2 +-
liblttng-ust/lttng-context-perf-counters.c | 79 ++++++++++++++++++++++++++----
3 files changed, 71 insertions(+), 11 deletions(-)
configure.ac +1 -0
index 105b46f..a966732 100644
@@ -222,6 +222,7 @@ AS_CASE([$host_cpu],
 	[i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
+	[armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes],
 	[UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no])
 AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS])
 
liblttng-ust-ctl/ustctl.c +1 -1
index 0165786..97445d5 100644
@@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream
 *stream,
 	return client_cb->instance_id(buf, handle, id);
 }
 
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__)
 
 int ustctl_has_perf_counters(void)

{

liblttng-ust/lttng-context-perf-counters.c +0 -6
index e546aee..1af1509 100644
@@ -96,17 +96,13 @@ static bool arch_perf_use_read(void)
 	return false;
 }
 
-#else /* defined(__x86_64__) || defined(__i386__) */
-
-#error "Perf event counters are only supported on x86 so far."
-
-#endif /* #else defined(__x86_64__) || defined(__i386__) */
-

static

liblttng-ust/lttng-context-perf-counters.c +2 -1
-uint64_t read_perf_counter(struct perf_event_mmap_page *pc)
+uint64_t read_perf_counter(
+		struct lttng_perf_counter_thread_field *thread_field)
{
	uint32_t seq, idx;
	uint64_t count;
liblttng-ust/lttng-context-perf-counters.c +1 -0
+	struct perf_event_mmap_page *pc = thread_field->pc;
	if (caa_unlikely(!pc))
		return 0;
liblttng-ust/lttng-context-perf-counters.c +28 -0
@@ -127,6 +123,35 @@ uint64_t read_perf_counter(struct perf_event_mmap_page *pc)
 	return count;
 }
 
+#elif defined (__ARM_ARCH_7A__)
+
+static bool arch_perf_use_read(void)
+{
+	return true;
+}
+
+static
+uint64_t read_perf_counter(
+		struct lttng_perf_counter_thread_field *thread_field)
+{
+	uint64_t count;
+
+	if (caa_unlikely(thread_field->fd < 0))
+		return 0;
+
+	if (caa_unlikely(read(thread_field->fd, &count, sizeof(count))
+				< sizeof(count)))
+		return 0;
+
+	return count;
+}
+
+#else /* defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__)
 */
+
+#error "Perf event counters are only supported on x86 and ARMv7 so far."
+
+#endif /* #else defined(__x86_64__) || defined(__i386__) ||

defined(__ARM_ARCH_7A__) */
+
static
int sys_perf_event_open(struct perf_event_attr *attr,
pid_t pid, int cpu, int group_fd,

liblttng-ust/lttng-context-perf-counters.c +0 -0
@@ -149,6 +174,20 @@ int open_perf_fd(struct perf_event_attr *attr)
 }
 

static

liblttng-ust/lttng-context-perf-counters.c +14 -0
+void close_perf_fd(int fd)
+{
+	int ret;
+
+	if (fd < 0)
+		return;
+
+	ret = close(fd);
+	if (ret) {
+		perror("Error closing LTTng-UST perf memory mapping FD");
+	}
+}
+
+static

struct perf_event_mmap_page *setup_perf(
struct lttng_perf_counter_thread_field *thread_field)
{

liblttng-ust/lttng-context-perf-counters.c +0 -1
@@ -164,11 +203,11 @@ struct perf_event_mmap_page *setup_perf(
 		thread_field->fd = -1;
 	}
 
-end:
 	return perf_addr;
 }
 

static
+<<<<<<< HEAD
void close_perf_fd(int fd)

{
	int ret;
liblttng-ust/lttng-context-perf-counters.c +0 -0
@@ -182,6 +221,8 @@ void close_perf_fd(int fd)
 }
 
Quoted 3 lines

static
+=======
+>>>>>>> b0fa947... Add perf context support for ARMv7

There are conflict hunks in the patch.

Please fix.

Mathieu

Quoted 50 lines

void unmap_perf_page(struct perf_event_mmap_page *pc)

{
	int ret;
liblttng-ust/lttng-context-perf-counters.c +1 -1
@@ -298,7 +339,7 @@ uint64_t wrapper_perf_counter_read(struct lttng_ctx_field
 *field)
 
 	perf_field = field->u.perf_counter;
 	perf_thread_field = get_thread_field(perf_field);
-	return read_perf_counter(perf_thread_field->pc);
+	return read_perf_counter(perf_thread_field);
 }
 

static

liblttng-ust/lttng-context-perf-counters.c +18 -0
@@ -369,6 +410,24 @@ void lttng_destroy_perf_counter_field(struct
 lttng_ctx_field *field)
 	free(perf_field);
 }
 
+#ifdef __ARM_ARCH_7A__
+
+static
+int perf_get_exclude_kernel(void)
+{
+	return 0;
+}
+
+#else /* __ARM_ARCH_7A__ */
+
+static
+int perf_get_exclude_kernel(void)
+{
+	return 1;
+}
+
+#endif /* __ARM_ARCH_7A__ */
+
 /* Called with UST lock held */
 int lttng_add_perf_counter_to_ctx(uint32_t type,

uint64_t config,

liblttng-ust/lttng-context-perf-counters.c +1 -2
@@ -419,7 +478,7 @@ int lttng_add_perf_counter_to_ctx(uint32_t type,
 
 	perf_field->attr.type = type;
 	perf_field->attr.config = config;
-	perf_field->attr.exclude_kernel = 1;
+	perf_field->attr.exclude_kernel = perf_get_exclude_kernel();
 	CDS_INIT_LIST_HEAD(&perf_field->thread_field_list);
 	field->u.perf_counter = perf_field;
 
--

1.9.1

Signature · 7 lines
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
_______________________________________________
lttng-dev mailing list
[email protected]
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

A message that is not in the archive (sent off-list or not yet received): [email protected]

#6 lore raw
Quoted 1 line · ----- On Jun 27, 2016, at 5:35 PM, Julien Desfossez [email protected]…

Please disregard that, wrong patch sent, wait for v4...

Oops, looked at the patch too quickly ;)

Signature · 7 lines
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
_______________________________________________
lttng-dev mailing list
[email protected]
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev