[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