[lttng-dev] [PATCH lttng-tools v4] Create a dedicated test suite for Perf

Jérémie Galarneau jeremie.galarneau at efficios.com
Thu Nov 10 20:05:36 UTC 2016


Merged in master and stable-2.9.

Thanks!
Jérémie

On 12 September 2016 at 16:57, Julien Desfossez <jdesfossez at efficios.com> wrote:
> Introduce the perf_regression test suite that must be run manually to
> check if the support for the Perf-related features are available on the
> current machine. This test cannot be run automatically since there are
> some platforms where it can fail (VMs, some SoCs, etc).
>
> For now, the test only makes sure that we can trace events with perf
> contexts enabled by raw ID in kernel and user-space. The test only works
> if libpfm is installed on the system and fails if it is not installed.
>
> Signed-off-by: Julien Desfossez <jdesfossez at efficios.com>
> ---
>  .gitignore                  |   2 +
>  README.md                   |   2 +
>  configure.ac                |  10 ++++
>  tests/Makefile.am           |   8 +--
>  tests/perf/Makefile.am      |   6 ++
>  tests/perf/find_event.c     |  84 ++++++++++++++++++++++++++
>  tests/perf/test_perf_raw.in | 139 ++++++++++++++++++++++++++++++++++++++++++++
>  tests/perf_regression       |   1 +
>  8 files changed, 248 insertions(+), 4 deletions(-)
>  create mode 100644 tests/perf/Makefile.am
>  create mode 100644 tests/perf/find_event.c
>  create mode 100644 tests/perf/test_perf_raw.in
>  create mode 100644 tests/perf_regression
>
> diff --git a/.gitignore b/.gitignore
> index 263b2a0..93ef389 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -107,6 +107,8 @@ tests/regression/ust/python-logging/test_python_logging
>  /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef
>  /tests/regression/tools/live/live_test
>  /tests/unit/ini_config/ini_config
> +/tests/perf/find_event
> +/tests/perf/test_perf_raw
>
>  # man pages
>  /doc/man/*.1
> diff --git a/README.md b/README.md
> index 22de252..4d72ed4 100644
> --- a/README.md
> +++ b/README.md
> @@ -57,6 +57,8 @@ The following items are _optional_ dependencies:
>      pages with the `--help` option or with the `lttng help` command.
>      Note that without `man`, you cannot get offline help with
>      LTTng-tools commands, not even their usage.
> +  - **libpfm >= 4.0**: needed to run the perf regression test suite.
> +    - Debian/Ubuntu package: `libpfm4-dev`
>
>  LTTng-tools supports both the [LTTng Linux Kernel tracer](https://lttng.org)
>  and [LTTng user space tracer](https://lttng.org) released as part of the same
> diff --git a/configure.ac b/configure.ac
> index 5cfe973..d4e12a7 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -480,6 +480,13 @@ AC_CHECK_LIB([c], [open_memstream],
>  ]
>  )
>
> +# check for libpfm
> +AC_CHECK_LIB([pfm], [pfm_initialize],
> +            [
> +             have_libpfm=yes
> +             ])
> +AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBPFM], [test "x$have_libpfm" = "xyes"])
> +
>  AC_ARG_ENABLE([git-version],
>                [AC_HELP_STRING([--disable-git-version],
>                                [Do not use the git version for the build])],
> @@ -1022,6 +1029,7 @@ AC_CONFIG_FILES([
>         tests/stress/Makefile
>         tests/unit/Makefile
>         tests/unit/ini_config/Makefile
> +       tests/perf/Makefile
>         tests/utils/Makefile
>         tests/utils/tap/Makefile
>         tests/utils/testapp/Makefile
> @@ -1032,6 +1040,8 @@ AC_CONFIG_FILES([
>
>  # Inject variable into python test script.
>  AC_CONFIG_FILES([tests/regression/ust/python-logging/test_python_logging],[chmod +x tests/regression/ust/python-logging/test_python_logging])
> +# Inject LTTNG_TOOLS_BUILD_WITH_LIBPFM variable in test script.
> +AC_CONFIG_FILES([tests/perf/test_perf_raw],[chmod +x tests/perf/test_perf_raw])
>
>  AC_OUTPUT
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 3600e99..d460fb6 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -1,8 +1,8 @@
>  SUBDIRS =
> -DIST_SUBDIRS = utils regression unit stress destructive
> +DIST_SUBDIRS = utils regression unit stress destructive perf
>
>  if BUILD_TESTS
> -SUBDIRS += . utils regression unit stress destructive
> +SUBDIRS += . utils regression unit stress destructive perf
>  if HAS_PGREP
>  check-am:
>         $(top_srcdir)/tests/utils/warn_processes.sh $(PGREP)
> @@ -14,8 +14,8 @@ else
>  endif
>
>
> -dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests
> -EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests
> +dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests perf_regression
> +EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests perf_regression
>
>  all-local:
>         @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
> diff --git a/tests/perf/Makefile.am b/tests/perf/Makefile.am
> new file mode 100644
> index 0000000..40bb754
> --- /dev/null
> +++ b/tests/perf/Makefile.am
> @@ -0,0 +1,6 @@
> +if LTTNG_TOOLS_BUILD_WITH_LIBPFM
> +LIBS += -lpfm
> +
> +noinst_PROGRAMS = find_event
> +find_event_SOURCES = find_event.c
> +endif
> diff --git a/tests/perf/find_event.c b/tests/perf/find_event.c
> new file mode 100644
> index 0000000..2b92a9b
> --- /dev/null
> +++ b/tests/perf/find_event.c
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (c)  2016 Julien Desfossez <jdesfossez at efficios.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * as published by the Free Software Foundation; only version 2
> + * of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <stdio.h>
> +#include <perfmon/pfmlib.h>
> +#include <string.h>
> +
> +int main(int argc, char **argv)
> +{
> +       int ret, i;
> +       unsigned int j;
> +       pfm_pmu_info_t pinfo;
> +
> +       if (argc != 2) {
> +               fprintf(stderr, "Usage: %s <pmu counter to find>\n"
> +                               "ex: %s UNHALTED_REFERENCE_CYCLES\n"
> +                               "Returns the first occurence it finds with "
> +                               "return code 0.\n"
> +                               "If not found returns 1, on error returns -1\n",
> +                               argv[0], argv[0]);
> +               ret = -1;
> +               goto end;
> +       }
> +
> +       memset(&pinfo, 0, sizeof(pinfo));
> +       pinfo.size = sizeof(pinfo);
> +
> +       ret = pfm_initialize();
> +       if (ret != PFM_SUCCESS) {
> +               fprintf(stderr, "Failed to initialise libpfm: %s",
> +                               pfm_strerror(ret));
> +               ret = -1;
> +               goto end;
> +       }
> +
> +       pfm_for_all_pmus(j) {
> +               ret = pfm_get_pmu_info(j, &pinfo);
> +               if (ret != PFM_SUCCESS) {
> +                       continue;
> +               }
> +
> +               for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
> +                       pfm_event_info_t info;
> +
> +                       ret = pfm_get_event_info(i, PFM_OS_NONE, &info);
> +                       if (ret != PFM_SUCCESS) {
> +                               fprintf(stderr, "Cannot get event info: %s\n",
> +                                               pfm_strerror(ret));
> +                               ret = -1;
> +                               goto end;
> +                       }
> +
> +                       if (info.pmu != j) {
> +                               continue;
> +                       }
> +
> +                       if (strcmp(info.name, argv[1]) == 0) {
> +                               fprintf(stdout, "r%" PRIx64 "\n", info.code);
> +                               ret = 0;
> +                               goto end;
> +                       }
> +               }
> +       }
> +
> +       ret = 1;
> +
> +end:
> +       return ret;
> +}
> diff --git a/tests/perf/test_perf_raw.in b/tests/perf/test_perf_raw.in
> new file mode 100644
> index 0000000..a5f9f55
> --- /dev/null
> +++ b/tests/perf/test_perf_raw.in
> @@ -0,0 +1,139 @@
> +#!/bin/bash
> +#
> +# Copyright (C) - 2016 Julien Desfossez <jdesfossez at efficios.com>
> +#
> +# This program is free software; you can redistribute it and/or modify it
> +# under the terms of the GNU General Public License, version 2 only, as
> +# published by the Free Software Foundation.
> +#
> +# This program is distributed in the hope that it will be useful, but WITHOUT
> +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> +# more details.
> +#
> +# You should have received a copy of the GNU General Public License along with
> +# this program; if not, write to the Free Software Foundation, Inc., 51
> +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> +
> +TEST_DESC="Perf counters"
> +
> +CURDIR=$(dirname $0)/
> +TESTDIR=$CURDIR/..
> +LTTNG_BIN="lttng"
> +SESSION_NAME="perf_counters"
> +NUM_TESTS=20
> +NR_ITER=1
> +NR_USEC_WAIT=1
> +TESTAPP_PATH="$TESTDIR/utils/testapp"
> +TESTAPP_NAME="gen-ust-events"
> +TESTAPP_BIN="$TESTAPP_PATH/$TESTAPP_NAME/$TESTAPP_NAME"
> +# Empty if libpfm is installed, "#" otherwise
> +HAVE_LIBPFM="@LTTNG_TOOLS_BUILD_WITH_LIBPFM_TRUE@"
> +
> +source $TESTDIR/utils/utils.sh
> +
> +function enable_ust_lttng_event_per_chan()
> +{
> +       sess_name="$1"
> +       event_name="$2"
> +       chan_name="$3"
> +
> +       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" -s $sess_name -c $chan_name -u >/dev/null 2>&1
> +       ok $? "Enable event $event_name for session $sess_name in channel $chan_name"
> +}
> +
> +function have_libpfm()
> +{
> +       test -z $HAVE_LIBPFM
> +       ok $? "Have libpfm installed"
> +}
> +
> +function test_ust_raw()
> +{
> +       TRACE_PATH=$(mktemp -d)
> +       SESSION_NAME="ust_perf"
> +       CHAN_NAME="mychan"
> +       EVENT_NAME="tp:tptest"
> +       PMU="UNHALTED_REFERENCE_CYCLES"
> +       PERFID=$($CURDIR/find_event $PMU)
> +       test $? -eq "0"
> +       ok $? "Find PMU $PMU"
> +
> +       create_lttng_session_ok $SESSION_NAME $TRACE_PATH
> +
> +       enable_ust_lttng_channel_ok $SESSION_NAME $CHAN_NAME
> +
> +       enable_ust_lttng_event_per_chan $SESSION_NAME $EVENT_NAME $CHAN_NAME
> +
> +       add_context_ust_ok $SESSION_NAME $CHAN_NAME "perf:thread:raw:${PERFID}:test"
> +
> +       start_lttng_tracing_ok
> +
> +       $TESTAPP_BIN $NR_ITER $NR_USEC_WAIT >/dev/null 2>&1
> +
> +       stop_lttng_tracing_ok
> +
> +       destroy_lttng_session_ok $SESSION_NAME
> +
> +       validate_trace "perf_thread_raw_${PERFID}_test" $TRACE_PATH
> +
> +       rm -rf $TRACE_PATH
> +}
> +
> +function test_kernel_raw()
> +{
> +       TRACE_PATH=$(mktemp -d)
> +       SESSION_NAME="kernel_perf"
> +       CHAN_NAME="mychan"
> +       EVENT_NAME="lttng_test_filter_event"
> +       PMU="UNHALTED_REFERENCE_CYCLES"
> +       PERFID=$($CURDIR/find_event $PMU)
> +       test $? -eq "0"
> +       ok $? "Find PMU $PMU"
> +
> +       create_lttng_session_ok $SESSION_NAME $TRACE_PATH
> +
> +       lttng_enable_kernel_channel_ok $SESSION_NAME $CHAN_NAME
> +
> +       enable_kernel_lttng_event_ok $SESSION_NAME $EVENT_NAME $CHAN_NAME
> +
> +       add_context_kernel_ok $SESSION_NAME $CHAN_NAME "perf:cpu:raw:${PERFID}:test"
> +
> +       start_lttng_tracing_ok
> +
> +       echo -n 10 > /proc/lttng-test-filter-event
> +
> +       stop_lttng_tracing_ok
> +
> +       destroy_lttng_session_ok $SESSION_NAME
> +
> +       validate_trace "perf_cpu_raw_${PERFID}_test" $TRACE_PATH
> +
> +       rm -rf $TRACE_PATH
> +}
> +
> +if [ "$(id -u)" == "0" ]; then
> +       isroot=1
> +else
> +       isroot=0
> +fi
> +
> +# MUST set TESTDIR before calling those functions
> +plan_tests $NUM_TESTS
> +
> +print_test_banner "$TEST_DESC"
> +
> +start_lttng_sessiond
> +
> +have_libpfm
> +
> +test_ust_raw
> +
> +skip $isroot "Root access is needed for kernel testing, skipping." 9 ||
> +{
> +       modprobe lttng-test
> +       test_kernel_raw
> +       rmmod lttng-test
> +}
> +
> +stop_lttng_sessiond
> diff --git a/tests/perf_regression b/tests/perf_regression
> new file mode 100644
> index 0000000..c4b9b86
> --- /dev/null
> +++ b/tests/perf_regression
> @@ -0,0 +1 @@
> +perf/test_perf_raw
> --
> 2.7.4
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev



-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com


More information about the lttng-dev mailing list