[lttng-dev] [RFC lttng-tools] Do not list or allow unsupported perf events

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Sun Sep 13 11:53:40 EDT 2015


CCing the new lttng-tools maintainer, Jérémie. More below,

----- On Sep 10, 2015, at 3:21 PM, Tony Jones tonyj at suse.com wrote:

> Query the perf api to determine the list of events that are actually
> supported by the PMU.  Reject events that are not supported.   On an
> AMD Opteron 6128 the following currently listed events are not supported:
> 
>	perf:bus-cycles, perf:L1-dcache-store-misses,
>	perf:L1-icache-stores, perf:L1-icache-store-misses,
>	perf:L1-icache-prefetch-misses, perf:LLC-store-misses,
>	perf:LLC-prefetches, perf:LLC-prefetch-misses, perf:dTLB-stores,
>	perf:dTLB-store-misses, perf:dTLB-prefetches,
>	perf:dTLB-prefetch-misses
> 
> It's not clear to me (hence the RFC) why parts of the perf ABI definitions
> had been replicated into add_context.c rather than just including
> perf_event.h (other than to avoid an autotools dependancy/check on
> perf_event.h which this patch still needs). It is also possible that
> querying the available events would be better handled over the lttng
> user->kernel ABI.
> 
> Thoughts?

It might make sense to add a dependency on perf_event.h.

I'm wondering if your detection technique below really try to
allocate a PMU counter for a short period of time ? This could
be an issue since there is a limited amount of counters available.

Thoughts ?

Thanks,

Mathieu

> ---
> src/bin/lttng/commands/add_context.c | 92 ++++++++++--------------------------
> 1 file changed, 25 insertions(+), 67 deletions(-)
> 
> diff --git a/src/bin/lttng/commands/add_context.c
> b/src/bin/lttng/commands/add_context.c
> index cf3f3ef..6f52edb 100644
> --- a/src/bin/lttng/commands/add_context.c
> +++ b/src/bin/lttng/commands/add_context.c
> @@ -26,6 +26,8 @@
> #include <sys/types.h>
> #include <unistd.h>
> 
> +#include <linux/perf_event.h>
> +
> #include <urcu/list.h>
> 
> #include <common/mi-lttng.h>
> @@ -77,72 +79,6 @@ enum context_type {
> 	CONTEXT_PERF_THREAD_COUNTER = 14,
> };
> 
> -/*
> - * Taken from the Perf ABI (all enum perf_*)
> - */
> -enum perf_type {
> -	PERF_TYPE_HARDWARE = 0,
> -	PERF_TYPE_SOFTWARE = 1,
> -	PERF_TYPE_HW_CACHE = 3,
> -};
> -
> -enum perf_count_hard {
> -	PERF_COUNT_HW_CPU_CYCLES		= 0,
> -	PERF_COUNT_HW_INSTRUCTIONS		= 1,
> -	PERF_COUNT_HW_CACHE_REFERENCES		= 2,
> -	PERF_COUNT_HW_CACHE_MISSES		= 3,
> -	PERF_COUNT_HW_BRANCH_INSTRUCTIONS	= 4,
> -	PERF_COUNT_HW_BRANCH_MISSES		= 5,
> -	PERF_COUNT_HW_BUS_CYCLES		= 6,
> -	PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	= 7,
> -	PERF_COUNT_HW_STALLED_CYCLES_BACKEND	= 8,
> -};
> -
> -enum perf_count_soft {
> -	PERF_COUNT_SW_CPU_CLOCK        = 0,
> -	PERF_COUNT_SW_TASK_CLOCK       = 1,
> -	PERF_COUNT_SW_PAGE_FAULTS      = 2,
> -	PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
> -	PERF_COUNT_SW_CPU_MIGRATIONS   = 4,
> -	PERF_COUNT_SW_PAGE_FAULTS_MIN  = 5,
> -	PERF_COUNT_SW_PAGE_FAULTS_MAJ  = 6,
> -	PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
> -	PERF_COUNT_SW_EMULATION_FAULTS = 8,
> -};
> -
> -/*
> - * Generalized hardware cache events:
> - *
> - *       { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
> - *       { read, write, prefetch } x
> - *       { accesses, misses }
> - */
> -enum perf_hw_cache_id {
> -	PERF_COUNT_HW_CACHE_L1D			= 0,
> -	PERF_COUNT_HW_CACHE_L1I			= 1,
> -	PERF_COUNT_HW_CACHE_LL			= 2,
> -	PERF_COUNT_HW_CACHE_DTLB		= 3,
> -	PERF_COUNT_HW_CACHE_ITLB		= 4,
> -	PERF_COUNT_HW_CACHE_BPU			= 5,
> -
> -	PERF_COUNT_HW_CACHE_MAX,		/* non-ABI */
> -};
> -
> -enum perf_hw_cache_op_id {
> -	PERF_COUNT_HW_CACHE_OP_READ		= 0,
> -	PERF_COUNT_HW_CACHE_OP_WRITE		= 1,
> -	PERF_COUNT_HW_CACHE_OP_PREFETCH		= 2,
> -
> -	PERF_COUNT_HW_CACHE_OP_MAX,		/* non-ABI */
> -};
> -
> -enum perf_hw_cache_op_result_id {
> -	PERF_COUNT_HW_CACHE_RESULT_ACCESS	= 0,
> -	PERF_COUNT_HW_CACHE_RESULT_MISS		= 1,
> -
> -	PERF_COUNT_HW_CACHE_RESULT_MAX,		/* non-ABI */
> -};
> -
> static struct poptOption long_options[] = {
> 	/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
> 	{"help",           'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
> @@ -461,6 +397,25 @@ struct ctx_type_list {
> 	.head = CDS_LIST_HEAD_INIT(ctx_type_list.head),
> };
> 
> +static int is_event_supported(const struct ctx_opts *ctx)
> +{
> +	int fd;
> +	struct perf_event_attr attr = {
> +		.type = ctx->u.perf.type,
> +		.config = ctx->u.perf.config,
> +		.disabled = 1
> +	};
> +
> +	if (ctx->ctx_type == CONTEXT_PERF_CPU_COUNTER ||
> +	    ctx->ctx_type == CONTEXT_PERF_THREAD_COUNTER) {
> +		if ((fd = syscall(__NR_perf_event_open, &attr,  0, -1, -1, 0)) < 0)
> +			return 0;
> +
> +		close(fd);
> +	}
> +	return 1;
> +}
> +
> /*
>  * Pretty print context type.
>  */
> @@ -473,6 +428,8 @@ static void print_ctx_type(FILE *ofp)
> 	fprintf(ofp, "%s", indent);
> 	len = indent_len;
> 	while (ctx_opts[i].symbol != NULL) {
> +		if (!is_event_supported(&ctx_opts[i]))
> +			goto next;
> 		if (!ctx_opts[i].hide_help) {
> 			if (len > indent_len) {
> 				if (len + strlen(ctx_opts[i].symbol) + 2
> @@ -486,6 +443,7 @@ static void print_ctx_type(FILE *ofp)
> 			}
> 			len += fprintf(ofp, "%s", ctx_opts[i].symbol);
> 		}
> +next:
> 		i++;
> 	}
> }
> @@ -538,7 +496,7 @@ static int find_ctx_type_idx(const char *opt)
> 	int ret = -1, i = 0;
> 
> 	while (ctx_opts[i].symbol != NULL) {
> -		if (strcmp(opt, ctx_opts[i].symbol) == 0) {
> +		if (strcmp(opt, ctx_opts[i].symbol) == 0 && is_event_supported(&ctx_opts[i]))
> {
> 			ret = i;
> 			goto end;
> 		}
> --
> 2.4.6

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list