The function helps to XOR bitmaps and calculate Hamming weight of the result in one pass. Signed-off-by: Yury Norov (NVIDIA) --- 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 Use the right helper and save one bitmaps traverse. Signed-off-by: Yury Norov (NVIDIA) --- drivers/net/ethernet/intel/ice/ice_switch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 84848f0123e7..903417477929 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -4984,10 +4984,8 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, hw->switch_info->recp_list[bit].res_idxs, ICE_MAX_FV_WORDS); - bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); - /* return number of free indexes */ - return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS); + return (u16)bitmap_weighted_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); } /** -- 2.43.0 bitmap_empty() is more verbose and efficient, as it stops traversing {r,t}xq_ena as soon as the 1st set bit found. Signed-off-by: Yury Norov (NVIDIA) --- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index de9e81ccee66..2b359752a158 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -1210,8 +1210,8 @@ bool ice_is_vf_trusted(struct ice_vf *vf) */ bool ice_vf_has_no_qs_ena(struct ice_vf *vf) { - return (!bitmap_weight(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF) && - !bitmap_weight(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF)); + return bitmap_empty(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF) && + bitmap_empty(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF); } /** -- 2.43.0