]> Git Repo - linux.git/commitdiff
Merge tag 'perf-tools-fixes-for-v6.6-2-2023-10-20' into perf-tools-next
authorNamhyung Kim <[email protected]>
Mon, 30 Oct 2023 20:39:28 +0000 (13:39 -0700)
committerNamhyung Kim <[email protected]>
Mon, 30 Oct 2023 20:46:27 +0000 (13:46 -0700)
To get the latest fixes in the perf tools including perf stat output,
dlfilter and LLVM feature detection.

Signed-off-by: Namhyung Kim <[email protected]>
1  2 
tools/perf/util/dlfilter.c
tools/perf/util/pmu.c

index 5e54832137a99e842ff71a2ef881885671f1bb23,4a1dc21b0450bcc8812cd662c629de9b664ec9cf..908e16813722d76f275d50e81aa0a596dec554fe
@@@ -52,10 -52,8 +52,10 @@@ static void al_to_d_al(struct addr_loca
                d_al->sym_end = sym->end;
                if (al->addr < sym->end)
                        d_al->symoff = al->addr - sym->start;
 -              else
 +              else if (al->map)
                        d_al->symoff = al->addr - map__start(al->map) - sym->start;
 +              else
 +                      d_al->symoff = 0;
                d_al->sym_binding = sym->binding;
        } else {
                d_al->sym = NULL;
@@@ -284,13 -282,21 +284,21 @@@ static struct perf_event_attr *dlfilter
        return &d->evsel->core.attr;
  }
  
+ static __s32 code_read(__u64 ip, struct map *map, struct machine *machine, void *buf, __u32 len)
+ {
+       u64 offset = map__map_ip(map, ip);
+       if (ip + len >= map__end(map))
+               len = map__end(map) - ip;
+       return dso__data_read_offset(map__dso(map), machine, offset, buf, len);
+ }
  static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len)
  {
        struct dlfilter *d = (struct dlfilter *)ctx;
        struct addr_location *al;
        struct addr_location a;
-       struct map *map;
-       u64 offset;
        __s32 ret;
  
        if (!d->ctx_valid)
        if (!al)
                return -1;
  
-       map = al->map;
-       if (map && ip >= map__start(map) && ip < map__end(map) &&
+       if (al->map && ip >= map__start(al->map) && ip < map__end(al->map) &&
            machine__kernel_ip(d->machine, ip) == machine__kernel_ip(d->machine, d->sample->ip))
-               goto have_map;
+               return code_read(ip, al->map, d->machine, buf, len);
  
        addr_location__init(&a);
        thread__find_map_fb(al->thread, d->sample->cpumode, ip, &a);
-       if (!a.map) {
-               ret = -1;
-               goto out;
-       }
+       ret = a.map ? code_read(ip, a.map, d->machine, buf, len) : -1;
  
-       map = a.map;
- have_map:
-       offset = map__map_ip(map, ip);
-       if (ip + len >= map__end(map))
-               len = map__end(map) - ip;
-       ret = dso__data_read_offset(map__dso(map), d->machine, offset, buf, len);
- out:
        addr_location__exit(&a);
        return ret;
  }
  
diff --combined tools/perf/util/pmu.c
index a967d25e899b731d9404142189d81f1ef818b0ca,d515ba8a0e160c97d69c7c1e83b964fa7120021c..d3c9aa4326bee4ba3d3b6594349d4e0426c2aae3
@@@ -28,7 -28,6 +28,7 @@@
  #include "strbuf.h"
  #include "fncache.h"
  #include "util/evsel_config.h"
 +#include <regex.h>
  
  struct perf_pmu perf_pmu__fake = {
        .name = "fake",
@@@ -53,7 -52,7 +53,7 @@@ struct perf_pmu_alias 
         */
        char *topic;
        /** @terms: Owned list of the original parsed parameters. */
 -      struct list_head terms;
 +      struct parse_events_terms terms;
        /** @list: List element of struct perf_pmu aliases. */
        struct list_head list;
        /**
@@@ -156,7 -155,7 +156,7 @@@ static void __perf_pmu_format__load(str
        format->loaded = true;
  }
  
 -static void perf_pmu_format__load(struct perf_pmu *pmu, struct perf_pmu_format *format)
 +static void perf_pmu_format__load(const struct perf_pmu *pmu, struct perf_pmu_format *format)
  {
        char path[PATH_MAX];
        FILE *file = NULL;
@@@ -296,7 -295,7 +296,7 @@@ static int perf_pmu__parse_scale(struc
        len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
        if (!len)
                return 0;
-       scnprintf(path + len, sizeof(path) - len, "%s/%s.scale", pmu->name, alias->name);
+       scnprintf(path + len, sizeof(path) - len, "%s/events/%s.scale", pmu->name, alias->name);
  
        fd = open(path, O_RDONLY);
        if (fd == -1)
@@@ -331,7 -330,7 +331,7 @@@ static int perf_pmu__parse_unit(struct 
        len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
        if (!len)
                return 0;
-       scnprintf(path + len, sizeof(path) - len, "%s/%s.unit", pmu->name, alias->name);
+       scnprintf(path + len, sizeof(path) - len, "%s/events/%s.unit", pmu->name, alias->name);
  
        fd = open(path, O_RDONLY);
        if (fd == -1)
@@@ -365,7 -364,7 +365,7 @@@ perf_pmu__parse_per_pkg(struct perf_pm
        len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
        if (!len)
                return 0;
-       scnprintf(path + len, sizeof(path) - len, "%s/%s.per-pkg", pmu->name, alias->name);
+       scnprintf(path + len, sizeof(path) - len, "%s/events/%s.per-pkg", pmu->name, alias->name);
  
        fd = open(path, O_RDONLY);
        if (fd == -1)
@@@ -386,7 -385,7 +386,7 @@@ static int perf_pmu__parse_snapshot(str
        len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
        if (!len)
                return 0;
-       scnprintf(path + len, sizeof(path) - len, "%s/%s.snapshot", pmu->name, alias->name);
+       scnprintf(path + len, sizeof(path) - len, "%s/events/%s.snapshot", pmu->name, alias->name);
  
        fd = open(path, O_RDONLY);
        if (fd == -1)
@@@ -405,7 -404,7 +405,7 @@@ static void perf_pmu_free_alias(struct 
        zfree(&newalias->long_desc);
        zfree(&newalias->topic);
        zfree(&newalias->pmu_name);
 -      parse_events_terms__purge(&newalias->terms);
 +      parse_events_terms__exit(&newalias->terms);
        free(newalias);
  }
  
@@@ -485,7 -484,7 +485,7 @@@ static int update_alias(const struct pm
        assign_str(pe->name, "topic", &data->alias->topic, pe->topic);
        data->alias->per_pkg = pe->perpkg;
        if (pe->event) {
 -              parse_events_terms__purge(&data->alias->terms);
 +              parse_events_terms__exit(&data->alias->terms);
                ret = parse_events_terms(&data->alias->terms, pe->event, /*input=*/NULL);
        }
        if (!ret && pe->unit) {
@@@ -525,7 -524,7 +525,7 @@@ static int perf_pmu__new_alias(struct p
        if (!alias)
                return -ENOMEM;
  
 -      INIT_LIST_HEAD(&alias->terms);
 +      parse_events_terms__init(&alias->terms);
        alias->scale = 1.0;
        alias->unit[0] = '\0';
        alias->per_pkg = perpkg;
        return 0;
  }
  
 -static inline bool pmu_alias_info_file(char *name)
 +static inline bool pmu_alias_info_file(const char *name)
  {
        size_t len;
  
@@@ -657,17 -656,17 +657,17 @@@ static int pmu_aliases_parse(struct per
        return 0;
  }
  
 -static int pmu_alias_terms(struct perf_pmu_alias *alias,
 -                         struct list_head *terms)
 +static int pmu_alias_terms(struct perf_pmu_alias *alias, struct list_head *terms)
  {
        struct parse_events_term *term, *cloned;
 -      LIST_HEAD(list);
 -      int ret;
 +      struct parse_events_terms clone_terms;
 +
 +      parse_events_terms__init(&clone_terms);
 +      list_for_each_entry(term, &alias->terms.terms, list) {
 +              int ret = parse_events_term__clone(&cloned, term);
  
 -      list_for_each_entry(term, &alias->terms, list) {
 -              ret = parse_events_term__clone(&cloned, term);
                if (ret) {
 -                      parse_events_terms__purge(&list);
 +                      parse_events_terms__exit(&clone_terms);
                        return ret;
                }
                /*
                 * which we don't want for implicit terms in aliases.
                 */
                cloned->weak = true;
 -              list_add_tail(&cloned->list, &list);
 +              list_add_tail(&cloned->list, &clone_terms.terms);
        }
 -      list_splice(&list, terms);
 +      list_splice_init(&clone_terms.terms, terms);
 +      parse_events_terms__exit(&clone_terms);
        return 0;
  }
  
@@@ -777,6 -775,11 +777,6 @@@ char *perf_pmu__getcpuid(struct perf_pm
        return cpuid;
  }
  
 -__weak const struct pmu_events_table *pmu_events_table__find(void)
 -{
 -      return perf_pmu__find_events_table(NULL);
 -}
 -
  __weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
  {
        return perf_pmu__find_metrics_table(NULL);
@@@ -871,28 -874,6 +871,28 @@@ out
        return res;
  }
  
 +bool pmu_uncore_identifier_match(const char *compat, const char *id)
 +{
 +      regex_t re;
 +      regmatch_t pmatch[1];
 +      int match;
 +
 +      if (regcomp(&re, compat, REG_EXTENDED) != 0) {
 +              /* Warn unable to generate match particular string. */
 +              pr_info("Invalid regular expression %s\n", compat);
 +              return false;
 +      }
 +
 +      match = !regexec(&re, id, 1, pmatch, 0);
 +      if (match) {
 +              /* Ensure a full match. */
 +              match = pmatch[0].rm_so == 0 && (size_t)pmatch[0].rm_eo == strlen(id);
 +      }
 +      regfree(&re);
 +
 +      return match;
 +}
 +
  static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,
                                        const struct pmu_events_table *table __maybe_unused,
                                        void *vdata)
@@@ -933,8 -914,8 +933,8 @@@ static int pmu_add_sys_aliases_iter_fn(
        if (!pe->compat || !pe->pmu)
                return 0;
  
 -      if (!strcmp(pmu->id, pe->compat) &&
 -          pmu_uncore_alias_match(pe->pmu, pmu->name)) {
 +      if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&
 +                      pmu_uncore_identifier_match(pe->compat, pmu->id)) {
                perf_pmu__new_alias(pmu,
                                pe->name,
                                pe->desc,
@@@ -954,27 -935,22 +954,27 @@@ void pmu_add_sys_aliases(struct perf_pm
        pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, pmu);
  }
  
 -struct perf_event_attr * __weak
 -perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 +static char *pmu_find_alias_name(struct perf_pmu *pmu, int dirfd)
  {
 -      return NULL;
 -}
 +      FILE *file = perf_pmu__open_file_at(pmu, dirfd, "alias");
 +      char *line = NULL;
 +      size_t line_len = 0;
 +      ssize_t ret;
  
 -const char * __weak
 -pmu_find_real_name(const char *name)
 -{
 -      return name;
 -}
 +      if (!file)
 +              return NULL;
  
 -const char * __weak
 -pmu_find_alias_name(const char *name __maybe_unused)
 -{
 -      return NULL;
 +      ret = getline(&line, &line_len, file);
 +      if (ret < 0) {
 +              fclose(file);
 +              return NULL;
 +      }
 +      /* Remove trailing newline. */
 +      if (ret > 0 && line[ret - 1] == '\n')
 +              line[--ret] = '\0';
 +
 +      fclose(file);
 +      return line;
  }
  
  static int pmu_max_precise(int dirfd, struct perf_pmu *pmu)
        return max_precise;
  }
  
 -struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *lookup_name)
 +void __weak
 +perf_pmu__arch_init(struct perf_pmu *pmu __maybe_unused)
 +{
 +}
 +
 +struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *name)
  {
        struct perf_pmu *pmu;
        __u32 type;
 -      const char *name = pmu_find_real_name(lookup_name);
 -      const char *alias_name;
  
        pmu = zalloc(sizeof(*pmu));
        if (!pmu)
        pmu->is_core = is_pmu_core(name);
        pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
  
 -      alias_name = pmu_find_alias_name(name);
 -      if (alias_name) {
 -              pmu->alias_name = strdup(alias_name);
 -              if (!pmu->alias_name)
 -                      goto err;
 -      }
 -
        pmu->type = type;
        pmu->is_uncore = pmu_is_uncore(dirfd, name);
        if (pmu->is_uncore)
                pmu->id = pmu_id(name);
        pmu->max_precise = pmu_max_precise(dirfd, pmu);
 +      pmu->alias_name = pmu_find_alias_name(pmu, dirfd);
        pmu->events_table = perf_pmu__find_events_table(pmu);
        pmu_add_sys_aliases(pmu);
        list_add_tail(&pmu->list, pmus);
  
 -      pmu->default_config = perf_pmu__get_default_config(pmu);
 +      perf_pmu__arch_init(pmu);
  
        return pmu;
  err:
@@@ -1131,7 -1110,7 +1131,7 @@@ void evsel__set_config_if_unset(struct 
  }
  
  static struct perf_pmu_format *
 -pmu_find_format(struct list_head *formats, const char *name)
 +pmu_find_format(const struct list_head *formats, const char *name)
  {
        struct perf_pmu_format *format;
  
@@@ -1209,12 -1188,12 +1209,12 @@@ static __u64 pmu_format_max_value(cons
   *   in a config string) later on in the term list.
   */
  static int pmu_resolve_param_term(struct parse_events_term *term,
 -                                struct list_head *head_terms,
 +                                struct parse_events_terms *head_terms,
                                  __u64 *value)
  {
        struct parse_events_term *t;
  
 -      list_for_each_entry(t, head_terms, list) {
 +      list_for_each_entry(t, &head_terms->terms, list) {
                if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM &&
                    t->config && !strcmp(t->config, term->config)) {
                        t->used = true;
        return -1;
  }
  
 -static char *pmu_formats_string(struct list_head *formats)
 +static char *pmu_formats_string(const struct list_head *formats)
  {
        struct perf_pmu_format *format;
        char *str = NULL;
@@@ -1255,10 -1234,10 +1255,10 @@@ error
   * Setup one of config[12] attr members based on the
   * user input data - term parameter.
   */
 -static int pmu_config_term(struct perf_pmu *pmu,
 +static int pmu_config_term(const struct perf_pmu *pmu,
                           struct perf_event_attr *attr,
                           struct parse_events_term *term,
 -                         struct list_head *head_terms,
 +                         struct parse_events_terms *head_terms,
                           bool zero, struct parse_events_error *err)
  {
        struct perf_pmu_format *format;
        return 0;
  }
  
 -int perf_pmu__config_terms(struct perf_pmu *pmu,
 +int perf_pmu__config_terms(const struct perf_pmu *pmu,
                           struct perf_event_attr *attr,
 -                         struct list_head *head_terms,
 +                         struct parse_events_terms *terms,
                           bool zero, struct parse_events_error *err)
  {
        struct parse_events_term *term;
  
 -      list_for_each_entry(term, head_terms, list) {
 -              if (pmu_config_term(pmu, attr, term, head_terms, zero, err))
 +      list_for_each_entry(term, &terms->terms, list) {
 +              if (pmu_config_term(pmu, attr, term, terms, zero, err))
                        return -EINVAL;
        }
  
   * 2) pmu format definitions - specified by pmu parameter
   */
  int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
 -                   struct list_head *head_terms,
 +                   struct parse_events_terms *head_terms,
                     struct parse_events_error *err)
  {
 -      bool zero = !!pmu->default_config;
 +      bool zero = !!pmu->perf_event_attr_init_default;
  
        return perf_pmu__config_terms(pmu, attr, head_terms, zero, err);
  }
@@@ -1493,7 -1472,7 +1493,7 @@@ static int check_info_data(struct perf_
   * Find alias in the terms list and replace it with the terms
   * defined for the alias
   */
 -int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
 +int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms,
                          struct perf_pmu_info *info, struct parse_events_error *err)
  {
        struct parse_events_term *term, *h;
        info->scale    = 0.0;
        info->snapshot = false;
  
 -      list_for_each_entry_safe(term, h, head_terms, list) {
 +      list_for_each_entry_safe(term, h, &head_terms->terms, list) {
                alias = pmu_find_alias(pmu, term);
                if (!alias)
                        continue;
@@@ -1655,7 -1634,7 +1655,7 @@@ static char *format_alias(char *buf, in
                : (int)strlen(pmu->name);
        int used = snprintf(buf, len, "%.*s/%s", pmu_name_len, pmu->name, alias->name);
  
 -      list_for_each_entry(term, &alias->terms, list) {
 +      list_for_each_entry(term, &alias->terms.terms, list) {
                if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
                        used += snprintf(buf + used, sub_non_neg(len, used),
                                        ",%s=%s", term->config,
@@@ -1714,7 -1693,7 +1714,7 @@@ int perf_pmu__for_each_event(struct per
                info.desc = event->desc;
                info.long_desc = event->long_desc;
                info.encoding_desc = buf + buf_used;
 -              parse_events_term__to_strbuf(&event->terms, &sb);
 +              parse_events_terms__to_strbuf(&event->terms, &sb);
                buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,
                                "%s/%s/", info.pmu_name, sb.buf) + 1;
                info.topic = event->topic;
@@@ -1770,7 -1749,7 +1770,7 @@@ bool perf_pmu__is_software(const struc
        return !strcmp(pmu->name, "kprobe") || !strcmp(pmu->name, "uprobe");
  }
  
 -FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
 +FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name)
  {
        char path[PATH_MAX];
  
        return fopen(path, "r");
  }
  
 -FILE *perf_pmu__open_file_at(struct perf_pmu *pmu, int dirfd, const char *name)
 +FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const char *name)
  {
        int fd;
  
        return fdopen(fd, "r");
  }
  
 -int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
 +int perf_pmu__scan_file(const struct perf_pmu *pmu, const char *name, const char *fmt,
                        ...)
  {
        va_list args;
        return ret;
  }
  
 -int perf_pmu__scan_file_at(struct perf_pmu *pmu, int dirfd, const char *name,
 +int perf_pmu__scan_file_at(const struct perf_pmu *pmu, int dirfd, const char *name,
                           const char *fmt, ...)
  {
        va_list args;
        return ret;
  }
  
 -bool perf_pmu__file_exists(struct perf_pmu *pmu, const char *name)
 +bool perf_pmu__file_exists(const struct perf_pmu *pmu, const char *name)
  {
        char path[PATH_MAX];
  
@@@ -2064,8 -2043,26 +2064,8 @@@ void perf_pmu__delete(struct perf_pmu *
  
        perf_cpu_map__put(pmu->cpus);
  
 -      zfree(&pmu->default_config);
        zfree(&pmu->name);
        zfree(&pmu->alias_name);
        zfree(&pmu->id);
        free(pmu);
  }
 -
 -struct perf_pmu *pmu__find_core_pmu(void)
 -{
 -      struct perf_pmu *pmu = NULL;
 -
 -      while ((pmu = perf_pmus__scan_core(pmu))) {
 -              /*
 -               * The cpumap should cover all CPUs. Otherwise, some CPUs may
 -               * not support some events or have different event IDs.
 -               */
 -              if (RC_CHK_ACCESS(pmu->cpus)->nr != cpu__max_cpu().cpu)
 -                      return NULL;
 -
 -              return pmu;
 -      }
 -      return NULL;
 -}
This page took 0.091658 seconds and 4 git commands to generate.