perf: Fix topology_sibling_cpumask check warning on ARM
authorKan Liang <kan.liang@linux.intel.com>
Thu, 12 Sep 2024 14:50:25 +0000 (07:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 22 Sep 2024 16:03:22 +0000 (09:03 -0700)
The below warning is triggered when building with arm
multi_v7_defconfig.

  kernel/events/core.c: In function 'perf_event_setup_cpumask':
  kernel/events/core.c:14012:13: warning: the comparison will always evaluate as 'true' for the address of 'thread_sibling' will never be NULL [-Waddress]
  14012 |         if (!topology_sibling_cpumask(cpu)) {

The perf_event_init_cpu() may be invoked at the early boot stage, while
the topology_*_cpumask hasn't been initialized yet.  The check is to
specially handle the case, and initialize the perf_online_<domain>_masks
on the boot CPU.

X86 uses a per-cpu cpumask pointer, which could be NULL at the early
boot stage.  However, ARM uses a global variable, which never be NULL.

Use perf_online_mask as an indicator instead.  Only initialize the
perf_online_<domain>_masks when perf_online_mask is empty.

Fix a typo as well.

Fixes: 4ba4f1afb6a9 ("perf: Generic hotplug support for a PMU with a scope")
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Closes: https://lore.kernel.org/lkml/20240911153854.240bbc1f@canb.auug.org.au/
Reported-by: Steven Price <steven.price@arm.com>
Closes: https://lore.kernel.org/lkml/1835eb6d-3e05-47f3-9eae-507ce165c3bf@arm.com/
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Steven Price <steven.price@arm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/events/core.c

index 0016f5ff9ba2a353b510a8b05988902a85010168..5afde9f7b52a56241c80f96072405cc78c3211ba 100644 (file)
@@ -14002,21 +14002,19 @@ static void perf_event_setup_cpumask(unsigned int cpu)
        struct cpumask *pmu_cpumask;
        unsigned int scope;
 
-       cpumask_set_cpu(cpu, perf_online_mask);
-
        /*
         * Early boot stage, the cpumask hasn't been set yet.
         * The perf_online_<domain>_masks includes the first CPU of each domain.
-        * Always uncondifionally set the boot CPU for the perf_online_<domain>_masks.
+        * Always unconditionally set the boot CPU for the perf_online_<domain>_masks.
         */
-       if (!topology_sibling_cpumask(cpu)) {
+       if (cpumask_empty(perf_online_mask)) {
                for (scope = PERF_PMU_SCOPE_NONE + 1; scope < PERF_PMU_MAX_SCOPE; scope++) {
                        pmu_cpumask = perf_scope_cpumask(scope);
                        if (WARN_ON_ONCE(!pmu_cpumask))
                                continue;
                        cpumask_set_cpu(cpu, pmu_cpumask);
                }
-               return;
+               goto end;
        }
 
        for (scope = PERF_PMU_SCOPE_NONE + 1; scope < PERF_PMU_MAX_SCOPE; scope++) {
@@ -14031,6 +14029,8 @@ static void perf_event_setup_cpumask(unsigned int cpu)
                    cpumask_any_and(pmu_cpumask, cpumask) >= nr_cpu_ids)
                        cpumask_set_cpu(cpu, pmu_cpumask);
        }
+end:
+       cpumask_set_cpu(cpu, perf_online_mask);
 }
 
 int perf_event_init_cpu(unsigned int cpu)