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

Reply via email to