bool loaded;
 };
 
+static int pmu_aliases_parse(struct perf_pmu *pmu);
+
 static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list, char *name)
 {
        struct perf_pmu_format *format;
        }
 }
 
-static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *pmu, const char *name)
+static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
+                                                  const char *name,
+                                                  bool load)
 {
        struct perf_pmu_alias *alias;
 
+       if (load && !pmu->sysfs_aliases_loaded)
+               pmu_aliases_parse(pmu);
+
        list_for_each_entry(alias, &pmu->aliases, list) {
                if (!strcasecmp(alias->name, name))
                        return alias;
        const char *long_desc = NULL, *topic = NULL, *unit = NULL, *pmu_name = NULL;
        bool deprecated = false, perpkg = false;
 
-       if (perf_pmu__find_alias(pmu, name)) {
+       if (perf_pmu__find_alias(pmu, name, /*load=*/ false)) {
                /* Alias was already created/loaded. */
                return 0;
        }
 }
 
 /*
- * Process all the sysfs attributes located under the directory
- * specified in 'dir' parameter.
+ * Reading the pmu event aliases definition, which should be located at:
+ * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
  */
-static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
+static int pmu_aliases_parse(struct perf_pmu *pmu)
 {
+       char path[PATH_MAX];
        struct dirent *evt_ent;
        DIR *event_dir;
-       int fd;
+       size_t len;
+       int fd, dir_fd;
 
-       event_dir = fdopendir(dirfd);
-       if (!event_dir)
+       len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
+       if (!len)
+               return 0;
+       scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name);
+
+       dir_fd = open(path, O_DIRECTORY);
+       if (dir_fd == -1) {
+               pmu->sysfs_aliases_loaded = true;
+               return 0;
+       }
+
+       event_dir = fdopendir(dir_fd);
+       if (!event_dir){
+               close (dir_fd);
                return -EINVAL;
+       }
 
        while ((evt_ent = readdir(event_dir))) {
                char *name = evt_ent->d_name;
                if (pmu_alias_info_file(name))
                        continue;
 
-               fd = openat(dirfd, name, O_RDONLY);
+               fd = openat(dir_fd, name, O_RDONLY);
                if (fd == -1) {
                        pr_debug("Cannot open %s\n", name);
                        continue;
        }
 
        closedir(event_dir);
-       return 0;
-}
-
-/*
- * Reading the pmu event aliases definition, which should be located at:
- * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
- */
-static int pmu_aliases(struct perf_pmu *pmu, int dirfd, const char *name)
-{
-       int fd;
-
-       fd = perf_pmu__pathname_fd(dirfd, name, "events", O_DIRECTORY);
-       if (fd < 0)
-               return 0;
-
-       /* it'll close the fd */
-       if (pmu_aliases_parse(pmu, fd))
-               return -1;
-
+       close (dir_fd);
+       pmu->sysfs_aliases_loaded = true;
        return 0;
 }
 
                free(pmu);
                return NULL;
        }
-       /*
-        * Check the aliases first to avoid unnecessary work.
-        */
-       if (pmu_aliases(pmu, dirfd, name)) {
-               free(pmu);
-               return NULL;
-       }
        pmu->is_core = is_pmu_core(name);
        pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
 
                return NULL;
        }
 
-       alias = perf_pmu__find_alias(pmu, name);
+       alias = perf_pmu__find_alias(pmu, name, /*load=*/ true);
        if (alias || pmu->cpu_aliases_added)
                return alias;
 
            pmu_events_table__find_event(pmu->events_table, pmu, name,
                                         pmu_add_cpu_aliases_map_callback,
                                         pmu) == 0) {
-               alias = perf_pmu__find_alias(pmu, name);
+               alias = perf_pmu__find_alias(pmu, name, /*load=*/ false);
        }
        return alias;
 }
 
 bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
 {
-       if (perf_pmu__find_alias(pmu, name) != NULL)
+       if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)
                return true;
        if (pmu->cpu_aliases_added || !pmu->events_table)
                return false;
 
 size_t perf_pmu__num_events(struct perf_pmu *pmu)
 {
-       size_t nr = pmu->sysfs_aliases;
+       size_t nr;
+
+       if (!pmu->sysfs_aliases_loaded)
+               pmu_aliases_parse(pmu);
+
+       nr = pmu->sysfs_aliases;
 
        if (pmu->cpu_aliases_added)
                 nr += pmu->loaded_json_aliases;