recipe_bitmap is not aligned to 8 bytes in ice_aqc_recipe_data_elem structure and set_bit is a atomic operation we end up with a split lock. The reason for this is that recipe_bitmap might end up being in two cache lines because it's not aligned. Fix this by introducing non-atomic function ice_set_recipe_index to replace ice_set_bit in this specific case.
Signed-off-by: Wojciech Drewek <wojciech.dre...@intel.com> Signed-off-by: Qiming Yang <qiming.y...@intel.com> --- drivers/net/ice/base/ice_bitops.h | 7 +++++++ drivers/net/ice/base/ice_switch.c | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/ice/base/ice_bitops.h b/drivers/net/ice/base/ice_bitops.h index 5384e99415..df00c859ac 100644 --- a/drivers/net/ice/base/ice_bitops.h +++ b/drivers/net/ice/base/ice_bitops.h @@ -11,6 +11,13 @@ /* Define the size of the bitmap chunk */ typedef u32 ice_bitmap_t; +/* NOTE! + * Do not use any of the functions declared in this file + * on memory that was not declared with ice_declare_bitmap. + * Not following this rule might cause issues like split + * locks. + */ + /* Number of bits per bitmap chunk */ #define BITS_PER_CHUNK (BITS_PER_BYTE * sizeof(ice_bitmap_t)) /* Determine which chunk a bit belongs in */ diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index cd6237136e..c71861a36d 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -7163,6 +7163,17 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles, return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS); } +static void ice_set_recipe_index(unsigned long idx, u8 *bitmap) +{ + u32 byte = idx / BITS_PER_BYTE; + u32 bit = idx % BITS_PER_BYTE; + + if (byte >= 8) + return; + + bitmap[byte] |= 1 << bit; +} + /** * ice_add_sw_recipe - function to call AQ calls to create switch recipe * @hw: pointer to hardware structure @@ -7290,10 +7301,10 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, } /* fill recipe dependencies */ - ice_zero_bitmap((ice_bitmap_t *)buf[recps].recipe_bitmap, - ICE_MAX_NUM_RECIPES); - ice_set_bit(buf[recps].recipe_indx, - (ice_bitmap_t *)buf[recps].recipe_bitmap); + ice_memset(buf[recps].recipe_bitmap, 0, + sizeof(buf[recps].recipe_bitmap), ICE_NONDMA_MEM); + ice_set_recipe_index(buf[recps].recipe_indx, + buf[recps].recipe_bitmap); buf[recps].content.act_ctrl_fwd_priority = rm->priority; recps++; } -- 2.25.1