[PATCH] perf: Use cpumask_intersects()

Costa Shulyupin posted 1 patch 1 month, 3 weeks ago
kernel/events/core.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
[PATCH] perf: Use cpumask_intersects()
Posted by Costa Shulyupin 1 month, 3 weeks ago
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@redhat.com>
---
 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