perf/core: move all of the pmu devices into their own location In sysfs, for some reason, all pmu devices seem to show up in the "root" of /sys/devices/ making for a confusing mess as these devices are not really at the root of the system at all. Create a fake root devices, "pmu_bus" and place them all under there if they do not already have a parent device set, cleaning up sysfs to look more sane. But because not all userspace tools have caught up and were incorrectly looking in the root of sysfs, create a config option to preserve the old locations for a few years until they can be properly updated. Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: "Liang, Kan" <kan.liang@linux.intel.com> Cc: linux-perf-users@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/init/Kconfig b/init/Kconfig index 2937c4d..a27f58c 100644 --- a/init/Kconfig +++ b/init/Kconfig
@@ -2148,6 +2148,27 @@ Say Y if unsure. +config PERF_EVENTS_SYSFS_OLD_LAYOUT + bool "Place kernel performance events in the root of the device tree" + default y + depends on PERF_EVENTS + help + Kernel event devices were originally placed in the root of + /sys/devices in sysfs incorrectly, and as they have grown over time, + the proliferation of them has caused confusion. Some older userspace + tools default to looking only in the root of sysfs for these devices + instead of properly searching /sys/bus/event_source/devices/ as the + documentation requested. Luckily most tools have been fixed up over + time as other event devices were placed properly in the device tree + hierarchy, but there are still some lingering toosl that have not + noticed. Select this option to allow those older + tools to continue to work properly. + + This option will be removed in a few years once all of the older + tools are finally updated. + + Say Y if unsure. + config DEBUG_PERF_USE_VMALLOC default n bool "Debug: use vmalloc to back perf mmap() buffers"
diff --git a/kernel/events/core.c b/kernel/events/core.c index 7935d56..55edade 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c
@@ -12697,6 +12697,11 @@ static const struct attribute_group *pmu_dev_groups[] = { }; static int pmu_bus_running; + +static struct device pmu_bus_root = { + .init_name = "pmu_bus", +}; + static const struct bus_type pmu_bus = { .name = "event_source", .dev_groups = pmu_dev_groups, @@ -12707,6 +12712,12 @@ static void pmu_dev_release(struct device *dev) kfree(dev); } +#if defined(PERF_EVENTS_SYSFS_OLD_LAYOUT) +#define PERF_ROOT_DEVICE NULL +#else +#define PERF_ROOT_DEVICE &pmu_bus_root +#endif + static int pmu_dev_alloc(struct pmu *pmu) { int ret = -ENOMEM; @@ -12720,7 +12731,10 @@ static int pmu_dev_alloc(struct pmu *pmu) dev_set_drvdata(pmu->dev, pmu); pmu->dev->bus = &pmu_bus; - pmu->dev->parent = pmu->parent; + if (pmu->parent) + pmu->dev->parent = pmu->parent; + else + pmu->dev->parent = PERF_ROOT_DEVICE; pmu->dev->release = pmu_dev_release; ret = dev_set_name(pmu->dev, "%s", pmu->name); @@ -15319,9 +15333,17 @@ static int __init perf_event_sysfs_init(void) mutex_lock(&pmus_lock); - ret = bus_register(&pmu_bus); - if (ret) + ret = device_register(&pmu_bus_root); + if (ret) { + put_device(&pmu_bus_root); goto unlock; + } + + ret = bus_register(&pmu_bus); + if (ret) { + device_unregister(&pmu_bus_root); + goto unlock; + } list_for_each_entry(pmu, &pmus, entry) { if (pmu->dev)