[lttng-dev] [PATCH lttng-ust v2 1/2] Keep perf context FD open for other architectures
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Mon Jun 27 21:09:28 UTC 2016
----- On Jun 23, 2016, at 6:52 PM, Julien Desfossez jdesfossez at efficios.com wrote:
> Instead of closing the perf context after the page has been mapped, keep
> it open so it can be used with the read() system call if the
> architecture does not support direct access from user-space.
>
> Signed-off-by: Julien Desfossez <jdesfossez at efficios.com>
> ---
> liblttng-ust/lttng-context-perf-counters.c | 53 +++++++++++++++++++++++-------
> 1 file changed, 41 insertions(+), 12 deletions(-)
>
> diff --git a/liblttng-ust/lttng-context-perf-counters.c
> b/liblttng-ust/lttng-context-perf-counters.c
> index 97ddf97..725b1b4 100644
> --- a/liblttng-ust/lttng-context-perf-counters.c
> +++ b/liblttng-ust/lttng-context-perf-counters.c
> @@ -55,6 +55,7 @@ struct lttng_perf_counter_thread_field {
> struct perf_event_mmap_page *pc;
> struct cds_list_head thread_field_node; /* Per-field list of thread fields
> (node) */
> struct cds_list_head rcu_field_node; /* RCU per-thread list of fields (node) */
> + int fd; /* Perf FD */
> };
>
> struct lttng_perf_counter_thread {
> @@ -131,24 +132,50 @@ int sys_perf_event_open(struct perf_event_attr *attr,
> }
>
> static
> -struct perf_event_mmap_page *setup_perf(struct perf_event_attr *attr)
> +int open_perf_fd(struct perf_event_attr *attr)
> {
> - void *perf_addr;
> - int fd, ret;
> + int fd;
>
> fd = sys_perf_event_open(attr, 0, -1, -1, 0);
> if (fd < 0)
> - return NULL;
> + return -1;
> +
> + return fd;
> +}
> +
> +static
> +struct perf_event_mmap_page *setup_perf(
> + struct lttng_perf_counter_thread_field *thread_field)
> +{
> + void *perf_addr;
>
> perf_addr = mmap(NULL, sizeof(struct perf_event_mmap_page),
> - PROT_READ, MAP_SHARED, fd, 0);
> + PROT_READ, MAP_SHARED, thread_field->fd, 0);
> if (perf_addr == MAP_FAILED)
> - return NULL;
> + perf_addr = NULL;
> +
> + /* No need to keep the FD open on x86 */
> +#if defined(__x86_64__) || defined(__i386__)
> + close_perf_fd(thread_field->fd);
> + thread_field->fd = -1;
> +#endif
No #if/#endif whatsoever in the code please. We don't want lttng
to end up looking like glibc. ;)
If needed, move that at the beginning of the file with e.g.
#if defined(__x86_64__) || defined(__i386__)
static bool arch_perf_use_read(void)
{
return true;
}
#else
static bool arch_perf_use_read(void)
{
return false;
}
#endif
> +
> +end:
> + return perf_addr;
> +}
> +
> +static
> +void close_perf_fd(int fd)
> +{
> + int ret;
> +
> + if (fd < 0)
> + return;
> +
> ret = close(fd);
> if (ret) {
You can remove those extra { }.
> perror("Error closing LTTng-UST perf memory mapping FD");
> }
> - return perf_addr;
> }
>
> static
> @@ -221,7 +248,9 @@ struct lttng_perf_counter_thread_field *
> if (!thread_field)
> abort();
> thread_field->field = perf_field;
> - thread_field->pc = setup_perf(&perf_field->attr);
> + thread_field->fd = open_perf_fd(&perf_field->attr);
> + if (thread_field->fd >= 0)
> + thread_field->pc = setup_perf(thread_field);
> /* Note: thread_field->pc can be NULL if setup_perf() fails. */
Do we need to update this comment to state that thread_field->fd can
also be -1 if open_perf_fd fails ?
Thanks,
Mathieu
> ust_lock_nocheck();
> cds_list_add_rcu(&thread_field->rcu_field_node,
> @@ -293,6 +322,7 @@ static
> void lttng_destroy_perf_thread_field(
> struct lttng_perf_counter_thread_field *thread_field)
> {
> + close_perf_fd(thread_field->fd);
> unmap_perf_page(thread_field->pc);
> cds_list_del_rcu(&thread_field->rcu_field_node);
> cds_list_del(&thread_field->thread_field_node);
> @@ -341,7 +371,6 @@ int lttng_add_perf_counter_to_ctx(uint32_t type,
> {
> struct lttng_ctx_field *field;
> struct lttng_perf_counter_field *perf_field;
> - struct perf_event_mmap_page *tmp_pc;
> char *name_alloc;
> int ret;
>
> @@ -389,12 +418,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type,
> field->u.perf_counter = perf_field;
>
> /* Ensure that this perf counter can be used in this process. */
> - tmp_pc = setup_perf(&perf_field->attr);
> - if (!tmp_pc) {
> + ret = open_perf_fd(&perf_field->attr);
> + if (ret < 0) {
> ret = -ENODEV;
> goto setup_error;
> }
> - unmap_perf_page(tmp_pc);
> + close_perf_fd(ret);
>
> /*
> * Contexts can only be added before tracing is started, so we
> --
> 1.9.1
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list