Message ID | 20240403155950.2068109-2-dawei.li@shingroup.cn (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | perf: Avoid placing cpumask on the stack | expand |
On Wed, Apr 03, 2024 at 11:59:41PM +0800, Dawei Li wrote: > From: Mark Rutland <mark.rutland@arm.com> > > In some cases, it's useful to be able to select a random cpu from the > intersection of two masks, excluding a particular CPU. > > For example, in some systems an uncore PMU is shared by a subset of > CPUs, and management of this PMU is assigned to some arbitrary CPU in > this set. Whenever the management CPU is hotplugged out, we wish to > migrate responsibility to another arbitrary CPU which is both in this > set and online. > > Today we can use cpumask_any_and() to select an arbitrary CPU in the > intersection of two masks. We can also use cpumask_any_but() to select > any arbitrary cpu in a mask excluding, a particular CPU. > > To do both, we either need to use a temporary cpumask, which is > wasteful, or use some lower-level cpumask helpers, which can be unclear. > > This patch adds a new cpumask_any_and_but() to cater for these cases. > > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Andrew Morton <akpm@linux-foundation.org> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Rusty Russell <rusty@rustcorp.com.au> > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Dawei Li <dawei.li@shingroup.cn> Thank you, Acked-by: Yury Norov <yury.norov@gmail.com>
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 1c29947db848..121f3ac757ff 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -388,6 +388,29 @@ unsigned int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) return i; } +/** + * cpumask_any_and_but - pick a "random" cpu from *mask1 & *mask2, but not this one. + * @mask1: the first input cpumask + * @mask2: the second input cpumask + * @cpu: the cpu to ignore + * + * Returns >= nr_cpu_ids if no cpus set. + */ +static inline +unsigned int cpumask_any_and_but(const struct cpumask *mask1, + const struct cpumask *mask2, + unsigned int cpu) +{ + unsigned int i; + + cpumask_check(cpu); + i = cpumask_first_and(mask1, mask2); + if (i != cpu) + return i; + + return cpumask_next_and(cpu, mask1, mask2); +} + /** * cpumask_nth - get the Nth cpu in a cpumask * @srcp: the cpumask pointer