free(newalias);
 }
 
+static void perf_pmu__del_aliases(struct perf_pmu *pmu)
+{
+       struct perf_pmu_alias *alias, *tmp;
+
+       list_for_each_entry_safe(alias, tmp, &pmu->aliases, list) {
+               list_del(&alias->list);
+               perf_pmu_free_alias(alias);
+       }
+}
+
 /* Merge an alias, search in alias list. If this name is already
  * present merge both of them to combine all information.
  */
 
        if (is_hybrid)
                list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus);
+       else
+               INIT_LIST_HEAD(&pmu->hybrid_list);
 
        pmu->default_config = perf_pmu__get_default_config(pmu);
 
        return -ENOMEM;
 }
 
+static void perf_pmu__del_caps(struct perf_pmu *pmu)
+{
+       struct perf_pmu_caps *caps, *tmp;
+
+       list_for_each_entry_safe(caps, tmp, &pmu->caps, list) {
+               list_del(&caps->list);
+               free(caps->name);
+               free(caps->value);
+               free(caps);
+       }
+}
+
 /*
  * Reading/parsing the given pmu capabilities, which should be located at:
  * /sys/bus/event_source/devices/<dev>/caps as sysfs group attributes.
                return 0;
        return scnprintf(buf, size, "%s%s/%s", base_path, pmu_name, filename);
 }
+
+static void perf_pmu__delete(struct perf_pmu *pmu)
+{
+       perf_pmu__del_formats(&pmu->format);
+       perf_pmu__del_aliases(pmu);
+       perf_pmu__del_caps(pmu);
+
+       perf_cpu_map__put(pmu->cpus);
+
+       free(pmu->default_config);
+       free(pmu->name);
+       free(pmu->alias_name);
+       free(pmu);
+}
+
+void perf_pmu__destroy(void)
+{
+       struct perf_pmu *pmu, *tmp;
+
+       list_for_each_entry_safe(pmu, tmp, &pmus, list) {
+               list_del(&pmu->list);
+               list_del(&pmu->hybrid_list);
+
+               perf_pmu__delete(pmu);
+       }
+}