lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAM9d7cip5Sm9cJdJHN4gvC+9zBTDjywmdHLK2A457Z8K1Po0vg@mail.gmail.com>
Date:   Thu, 7 Sep 2023 14:31:29 -0700
From:   Namhyung Kim <namhyung@...nel.org>
To:     Aditya Gupta <adityag@...ux.ibm.com>
Cc:     acme@...nel.org, jolsa@...nel.org, irogers@...gle.com,
        linux-perf-users@...r.kernel.org, maddy@...ux.ibm.com,
        atrajeev@...ux.vnet.ibm.com, kjain@...ux.ibm.com,
        disgoel@...ux.vnet.ibm.com, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/4] perf check: introduce check subcommand

Hello,

On Sun, Sep 3, 2023 at 4:47 AM Aditya Gupta <adityag@...ux.ibm.com> wrote:
>
> Currently the presence of a feature is checked with a combination of
> perf version --build-options and greps, such as:
>
>     perf version --build-options | grep " on .* HAVE_FEATURE"
>
> Instead of this, introduce a subcommand "perf check --feature", with which
> scripts can test for presence of a feature, such as:
>
>     perf check --feature HAVE_FEATURE
>
> 'perf check --feature' command is expected to have exit status of 1 if feature is
> built-in, and 0 if not, -2 if feature is not known.
>
> A global array 'supported_features' has also been introduced that can be
> used by other commands like 'perf version --build-options', so that
> new features can be added in one place, with the array
>
> Signed-off-by: Aditya Gupta <adityag@...ux.ibm.com>
> ---
>  tools/perf/Build                        |  1 +
>  tools/perf/Documentation/perf-check.txt | 53 ++++++++++++++
>  tools/perf/builtin-check.c              | 95 +++++++++++++++++++++++++
>  tools/perf/builtin.h                    | 47 ++++++++++++
>  tools/perf/perf.c                       |  1 +
>  5 files changed, 197 insertions(+)
>  create mode 100644 tools/perf/Documentation/perf-check.txt
>  create mode 100644 tools/perf/builtin-check.c
>
> diff --git a/tools/perf/Build b/tools/perf/Build
> index aa7623622834..a55a797c1b5f 100644
> --- a/tools/perf/Build
> +++ b/tools/perf/Build
> @@ -1,5 +1,6 @@
>  perf-y += builtin-bench.o
>  perf-y += builtin-annotate.o
> +perf-y += builtin-check.o
>  perf-y += builtin-config.o
>  perf-y += builtin-diff.o
>  perf-y += builtin-evlist.o
> diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
> new file mode 100644
> index 000000000000..ee4331838be5
> --- /dev/null
> +++ b/tools/perf/Documentation/perf-check.txt
> @@ -0,0 +1,53 @@
> +perf-check(1)
> +===============
> +
> +NAME
> +----
> +perf-check - check features in perf
> +
> +SYNOPSIS
> +--------
> +'perf check' [--feature]
> +
> +DESCRIPTION
> +-----------
> +With no options given, the 'perf check' just prints the perf version
> +on the standard output.
> +
> +If the option '--feature' is given, then status of feature is printed
> +on the standard output, ie. whether it is compiled-in/built-in or not
> +
> +OPTIONS
> +-------
> +--feature::
> +        Print whether a feature is compiled-in or not. A feature name/macro is
> +        required to be passed after this flag
> +
> +        Example Usage:
> +                perf check --feature libtraceevent
> +                perf check --feature HAVE_LIBTRACEEVENT
> +
> +        Supported feature names/macro:
> +                dwarf      /  HAVE_DWARF_SUPPORT
> +                dwarf_getlocations  /  HAVE_DWARF_GETLOCATIONS_SUPPORT
> +                libaudit   /  HAVE_LIBAUDIT_SUPPORT
> +                syscall_table       /  HAVE_SYSCALL_TABLE_SUPPORT
> +                libbfd     /  HAVE_LIBBFD_SUPPORT
> +                debuginfod /  HAVE_DEBUGINFOD_SUPPORT
> +                libelf     /  HAVE_LIBELF_SUPPORT
> +                libnuma    /  HAVE_LIBNUMA_SUPPORT
> +                numa_num_possible_cpus  /  HAVE_LIBNUMA_SUPPORT
> +                libperl    /  HAVE_LIBPERL_SUPPORT
> +                libpython  /  HAVE_LIBPYTHON_SUPPORT
> +                libslang   /  HAVE_SLANG_SUPPORT
> +                libcrypto  /  HAVE_LIBCRYPTO_SUPPORT
> +                libunwind  /  HAVE_LIBUNWIND_SUPPORT
> +                libdw-dwarf-unwind  /  HAVE_DWARF_SUPPORT
> +                zlib       /  HAVE_ZLIB_SUPPORT
> +                lzma       /  HAVE_LZMA_SUPPORT
> +                get_cpuid  /  HAVE_AUXTRACE_SUPPORT
> +                bpf        /  HAVE_LIBBPF_SUPPORT
> +                aio        /  HAVE_AIO_SUPPORT
> +                zstd       /  HAVE_ZSTD_SUPPORT
> +                libpfm4    /  HAVE_LIBPFM
> +                libtraceevent      /  HAVE_LIBTRACEEVENT
> diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
> new file mode 100644
> index 000000000000..3dee72426c30
> --- /dev/null
> +++ b/tools/perf/builtin-check.c
> @@ -0,0 +1,95 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include "builtin.h"
> +#include "color.h"
> +#include "util/debug.h"
> +#include "util/header.h"
> +#include <tools/config.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <subcmd/parse-options.h>
> +
> +struct check {
> +       const char *feature;
> +};
> +
> +static struct check check;
> +
> +static struct option check_options[] = {
> +       OPT_STRING(0, "feature", &check.feature, NULL, "check if a feature is built in"),
> +       OPT_END(),
> +};
> +
> +static const char * const check_usage[] = {
> +       "perf check [<options>]",
> +       NULL
> +};
> +
> +static void on_off_print(const char *status)
> +{
> +       printf("[ ");
> +
> +       if (!strcmp(status, "OFF"))
> +               color_fprintf(stdout, PERF_COLOR_RED, "%-3s", status);
> +       else
> +               color_fprintf(stdout, PERF_COLOR_GREEN, "%-3s", status);
> +
> +       printf(" ]");
> +}
> +
> +static void status_print(const char *name, const char *macro,
> +                        const char *status)
> +{
> +       printf("%22s: ", name);
> +       on_off_print(status);
> +       printf("  # %s\n", macro);
> +}
> +
> +#define STATUS(feature)                                   \
> +do {                                                      \
> +       if (feature.is_builtin)                               \
> +               status_print(feature.name, feature.macro, "on");  \
> +       else                                                  \
> +               status_print(feature.name, feature.macro, "OFF"); \
> +} while (0)
> +
> +/**
> + * check whether "feature" is built-in with perf
> + * returns:./perf annotate --data-type --type-stat -k vmlinux -d '[kernel.kallsyms]' --objdump=llvm-objdump
> + *   -1: Feature not known
> + *    0: Built-in
> + *    1: NOT Built in
> + */
> +static int has_support(const char *feature)
> +{
> +       int res = -1;
> +
> +       for (int i = 0; supported_features[i].name; ++i) {
> +               if ((strcmp(feature, supported_features[i].name) == 0) ||
> +                       (strcmp(feature, supported_features[i].macro) == 0)) {
> +                       res = supported_features[i].is_builtin;
> +                       STATUS(supported_features[i]);
> +                       break;
> +               }
> +       }
> +
> +       if (res == -1) {
> +               color_fprintf(stdout, PERF_COLOR_RED, "Feature not known: %s", feature);
> +               return -2;

return -1 ??  It doesn't match with the comment.


> +       }
> +
> +       return !res;
> +}
> +
> +int cmd_check(int argc, const char **argv)
> +{
> +       argc = parse_options(argc, argv, check_options, check_usage,
> +                            PARSE_OPT_STOP_AT_NON_OPTION);
> +
> +       printf("perf check %s\n", perf_version_string);
> +
> +       if (check.feature)
> +               return has_support(check.feature);
> +
> +       return 0;
> +}
> diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
> index f2ab5bae2150..6683ea6d3b60 100644
> --- a/tools/perf/builtin.h
> +++ b/tools/perf/builtin.h
> @@ -2,6 +2,52 @@
>  #ifndef BUILTIN_H
>  #define BUILTIN_H
>
> +#include <stddef.h>
> +#include <linux/compiler.h>
> +#include <tools/config.h>
> +
> +struct feature_support {
> +       const char *name;
> +       const char *macro;
> +       int is_builtin;
> +};
> +
> +#define FEATURE_SUPPORT(name_, macro_) { \
> +       .name = name_,                       \
> +       .macro = #macro_,                    \
> +       .is_builtin = IS_BUILTIN(macro_) }
> +
> +static struct feature_support supported_features[] __maybe_unused = {

Hmm.. do you want it in a header file?
I'm afraid it'd duplicate the entire array for any .c files that
include this header.


> +       FEATURE_SUPPORT("dwarf", HAVE_DWARF_SUPPORT),
> +       FEATURE_SUPPORT("dwarf_getlocations", HAVE_DWARF_GETLOCATIONS_SUPPORT),
> +#ifndef HAVE_SYSCALL_TABLE_SUPPORT

Do we really need this #ifndef?

Thanks,
Namhyung


> +       FEATURE_SUPPORT("libaudit", HAVE_LIBAUDIT_SUPPORT),
> +#endif
> +       FEATURE_SUPPORT("syscall_table", HAVE_SYSCALL_TABLE_SUPPORT),
> +       FEATURE_SUPPORT("libbfd", HAVE_LIBBFD_SUPPORT),
> +       FEATURE_SUPPORT("debuginfod", HAVE_DEBUGINFOD_SUPPORT),
> +       FEATURE_SUPPORT("libelf", HAVE_LIBELF_SUPPORT),
> +       FEATURE_SUPPORT("libnuma", HAVE_LIBNUMA_SUPPORT),
> +       FEATURE_SUPPORT("numa_num_possible_cpus", HAVE_LIBNUMA_SUPPORT),
> +       FEATURE_SUPPORT("libperl", HAVE_LIBPERL_SUPPORT),
> +       FEATURE_SUPPORT("libpython", HAVE_LIBPYTHON_SUPPORT),
> +       FEATURE_SUPPORT("libslang", HAVE_SLANG_SUPPORT),
> +       FEATURE_SUPPORT("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
> +       FEATURE_SUPPORT("libunwind", HAVE_LIBUNWIND_SUPPORT),
> +       FEATURE_SUPPORT("libdw-dwarf-unwind", HAVE_DWARF_SUPPORT),
> +       FEATURE_SUPPORT("zlib", HAVE_ZLIB_SUPPORT),
> +       FEATURE_SUPPORT("lzma", HAVE_LZMA_SUPPORT),
> +       FEATURE_SUPPORT("get_cpuid", HAVE_AUXTRACE_SUPPORT),
> +       FEATURE_SUPPORT("bpf", HAVE_LIBBPF_SUPPORT),
> +       FEATURE_SUPPORT("aio", HAVE_AIO_SUPPORT),
> +       FEATURE_SUPPORT("zstd", HAVE_ZSTD_SUPPORT),
> +       FEATURE_SUPPORT("libpfm4", HAVE_LIBPFM),
> +       FEATURE_SUPPORT("libtraceevent", HAVE_LIBTRACEEVENT),
> +
> +       // this should remain at end, to know the array end
> +       FEATURE_SUPPORT(NULL, _)
> +};
> +
>  void list_common_cmds_help(void);
>  const char *help_unknown_cmd(const char *cmd);
>
> @@ -9,6 +55,7 @@ int cmd_annotate(int argc, const char **argv);
>  int cmd_bench(int argc, const char **argv);
>  int cmd_buildid_cache(int argc, const char **argv);
>  int cmd_buildid_list(int argc, const char **argv);
> +int cmd_check(int argc, const char **argv);
>  int cmd_config(int argc, const char **argv);
>  int cmd_c2c(int argc, const char **argv);
>  int cmd_diff(int argc, const char **argv);
> diff --git a/tools/perf/perf.c b/tools/perf/perf.c
> index d3fc8090413c..83dc0ac42fdb 100644
> --- a/tools/perf/perf.c
> +++ b/tools/perf/perf.c
> @@ -50,6 +50,7 @@ static struct cmd_struct commands[] = {
>         { "archive",    NULL,   0 },
>         { "buildid-cache", cmd_buildid_cache, 0 },
>         { "buildid-list", cmd_buildid_list, 0 },
> +       { "check", cmd_check, 0 },
>         { "config",     cmd_config,     0 },
>         { "c2c",        cmd_c2c,        0 },
>         { "diff",       cmd_diff,       0 },
> --
> 2.41.0
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ