[PATCH 1/3] bitmap: introduce bitmap_weighted_xor()
From: "Yury Norov (NVIDIA)" <yury.norov@gmail.com>
Date: 2025-12-23 16:23:07
Also in:
intel-wired-lan, lkml
Subsystem:
bitmap api, library code, the rest · Maintainers:
Yury Norov, Andrew Morton, Linus Torvalds
The function helps to XOR bitmaps and calculate Hamming weight of the result in one pass. Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com> --- include/linux/bitmap.h | 14 ++++++++++++++ lib/bitmap.c | 7 +++++++ 2 files changed, 21 insertions(+)
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 0f4789e1f7cb..7ecf56e0d3b5 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h@@ -169,6 +169,8 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, unsigned int nbits); unsigned int __bitmap_weighted_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, unsigned int nbits); +unsigned int __bitmap_weighted_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int nbits); void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, unsigned int nbits); bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
@@ -355,6 +357,18 @@ unsigned int bitmap_weighted_or(unsigned long *dst, const unsigned long *src1, } } +static __always_inline +unsigned int bitmap_weighted_xor(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (small_const_nbits(nbits)) { + *dst = *src1 ^ *src2; + return hweight_long(*dst & BITMAP_LAST_WORD_MASK(nbits)); + } else { + return __bitmap_weighted_xor(dst, src1, src2, nbits); + } +} + static __always_inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 698d15933c84..bed32b8cd23a 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c@@ -382,6 +382,13 @@ unsigned int __bitmap_weighted_or(unsigned long *dst, const unsigned long *bitma return BITMAP_WEIGHT(({dst[idx] = bitmap1[idx] | bitmap2[idx]; dst[idx]; }), bits); } +unsigned int __bitmap_weighted_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits) +{ + return BITMAP_WEIGHT(({dst[idx] = bitmap1[idx] ^ bitmap2[idx]; dst[idx]; }), bits); +} +EXPORT_SYMBOL(__bitmap_weighted_xor); + unsigned long __bitmap_weight_from(const unsigned long *bitmap, unsigned int start, unsigned int nbits) {
--
2.43.0