Skip to content

Commit b9fa644

Browse files
committed
cpumask: Implement cpumask_or_equal()
The IPI code of x86 needs to evaluate whether the target cpumask is equal to the cpu_online_mask or equal except for the calling CPU. To replace the current implementation which requires the usage of a temporary cpumask, which might involve allocations, add a new function which compares a cpumask to the result of two other cpumasks which are or'ed together before comparison. This allows to make the required decision in one go and the calling code then can check for the calling CPU being set in the target mask with cpumask_test_cpu(). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20190722105220.585449120@linutronix.de
1 parent e797bda commit b9fa644

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

include/linux/bitmap.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ extern int __bitmap_empty(const unsigned long *bitmap, unsigned int nbits);
120120
extern int __bitmap_full(const unsigned long *bitmap, unsigned int nbits);
121121
extern int __bitmap_equal(const unsigned long *bitmap1,
122122
const unsigned long *bitmap2, unsigned int nbits);
123+
extern bool __pure __bitmap_or_equal(const unsigned long *src1,
124+
const unsigned long *src2,
125+
const unsigned long *src3,
126+
unsigned int nbits);
123127
extern void __bitmap_complement(unsigned long *dst, const unsigned long *src,
124128
unsigned int nbits);
125129
extern void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
@@ -321,6 +325,25 @@ static inline int bitmap_equal(const unsigned long *src1,
321325
return __bitmap_equal(src1, src2, nbits);
322326
}
323327

328+
/**
329+
* bitmap_or_equal - Check whether the or of two bitnaps is equal to a third
330+
* @src1: Pointer to bitmap 1
331+
* @src2: Pointer to bitmap 2 will be or'ed with bitmap 1
332+
* @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2
333+
*
334+
* Returns: True if (*@src1 | *@src2) == *@src3, false otherwise
335+
*/
336+
static inline bool bitmap_or_equal(const unsigned long *src1,
337+
const unsigned long *src2,
338+
const unsigned long *src3,
339+
unsigned int nbits)
340+
{
341+
if (!small_const_nbits(nbits))
342+
return __bitmap_or_equal(src1, src2, src3, nbits);
343+
344+
return !(((*src1 | *src2) ^ *src3) & BITMAP_LAST_WORD_MASK(nbits));
345+
}
346+
324347
static inline int bitmap_intersects(const unsigned long *src1,
325348
const unsigned long *src2, unsigned int nbits)
326349
{

include/linux/cpumask.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,20 @@ static inline bool cpumask_equal(const struct cpumask *src1p,
475475
nr_cpumask_bits);
476476
}
477477

478+
/**
479+
* cpumask_or_equal - *src1p | *src2p == *src3p
480+
* @src1p: the first input
481+
* @src2p: the second input
482+
* @src3p: the third input
483+
*/
484+
static inline bool cpumask_or_equal(const struct cpumask *src1p,
485+
const struct cpumask *src2p,
486+
const struct cpumask *src3p)
487+
{
488+
return bitmap_or_equal(cpumask_bits(src1p), cpumask_bits(src2p),
489+
cpumask_bits(src3p), nr_cpumask_bits);
490+
}
491+
478492
/**
479493
* cpumask_intersects - (*src1p & *src2p) != 0
480494
* @src1p: the first input

lib/bitmap.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ int __bitmap_equal(const unsigned long *bitmap1,
5959
}
6060
EXPORT_SYMBOL(__bitmap_equal);
6161

62+
bool __bitmap_or_equal(const unsigned long *bitmap1,
63+
const unsigned long *bitmap2,
64+
const unsigned long *bitmap3,
65+
unsigned int bits)
66+
{
67+
unsigned int k, lim = bits / BITS_PER_LONG;
68+
unsigned long tmp;
69+
70+
for (k = 0; k < lim; ++k) {
71+
if ((bitmap1[k] | bitmap2[k]) != bitmap3[k])
72+
return false;
73+
}
74+
75+
if (!(bits % BITS_PER_LONG))
76+
return true;
77+
78+
tmp = (bitmap1[k] | bitmap2[k]) ^ bitmap3[k];
79+
return (tmp & BITMAP_LAST_WORD_MASK(bits)) == 0;
80+
}
81+
6282
void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits)
6383
{
6484
unsigned int k, lim = BITS_TO_LONGS(bits);

0 commit comments

Comments
 (0)