lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20241007121525.1905562-1-costa.shul@redhat.com>
Date: Mon,  7 Oct 2024 15:15:24 +0300
From: Costa Shulyupin <costa.shul@...hat.com>
To: Peter Zijlstra <peterz@...radead.org>,
	Ingo Molnar <mingo@...hat.com>,
	Arnaldo Carvalho de Melo <acme@...nel.org>,
	Namhyung Kim <namhyung@...nel.org>,
	Mark Rutland <mark.rutland@....com>,
	Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
	Jiri Olsa <jolsa@...nel.org>,
	Ian Rogers <irogers@...gle.com>,
	Adrian Hunter <adrian.hunter@...el.com>,
	"Liang, Kan" <kan.liang@...ux.intel.com>,
	linux-perf-users@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: ming.lei@...hat.com,
	Costa Shulyupin <costa.shul@...hat.com>
Subject: [PATCH] perf: Use cpumask_intersects()

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@...hat.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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ