[PATCH] perf: Use cpumask_intersects()

From: Costa Shulyupin
Date: Mon Oct 07 2024 - 08:16:44 EST


Replace `cpumask_any_and(a, b) >= nr_cpu_ids`
with the more readable `!cpumask_intersects(a, b)`.

Comparison between cpumask_any_and() and cpumask_intersects()

The cpumask_any_and() function expands using FIND_FIRST_BIT(),
resulting in a loop that iterates through each bit of the bitmask:

for (idx = 0; idx * BITS_PER_LONG < sz; idx++) {
val = (FETCH);
if (val) {
sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz);
break;
}
}

The cpumask_intersects() function expands using __bitmap_intersects(),
resulting in that the first loop iterates through each long word
of the bitmask, and the second through each bit within a long word:

unsigned int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k)
if (bitmap1[k] & bitmap2[k])
return true;

if (bits % BITS_PER_LONG)
if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
return true;

Conclusion: cpumask_intersects() is at least as efficient
as cpumask_any_and(), if not more so, as it typically performs
fewer loops and comparisons.

Signed-off-by: Costa Shulyupin <costa.shul@xxxxxxxxxx>
---
kernel/events/core.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index e3589c4287cb..da106d0ee909 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -11905,11 +11905,9 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
if (pmu->scope != PERF_PMU_SCOPE_NONE && event->cpu >= 0) {
const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(pmu->scope, event->cpu);
struct cpumask *pmu_cpumask = perf_scope_cpumask(pmu->scope);
- int cpu;

if (pmu_cpumask && cpumask) {
- cpu = cpumask_any_and(pmu_cpumask, cpumask);
- if (cpu >= nr_cpu_ids)
+ if (!cpumask_intersects(pmu_cpumask, cpumask))
ret = -ENODEV;
else
event->event_caps |= PERF_EV_CAP_READ_SCOPE;
@@ -14025,7 +14023,7 @@ static void perf_event_setup_cpumask(unsigned int cpu)
continue;

if (!cpumask_empty(cpumask) &&
- cpumask_any_and(pmu_cpumask, cpumask) >= nr_cpu_ids)
+ !cpumask_intersects(pmu_cpumask, cpumask))
cpumask_set_cpu(cpu, pmu_cpumask);
}
end:
--
2.45.0