[v2,05/20] net/ice/base: introduce a non-atomic function

Message ID 20230518151638.1207021-6-qiming.yang@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Qi Zhang
Headers
Series net/ice/base: code update |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Qiming Yang May 18, 2023, 3:16 p.m. UTC
  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.drewek@intel.com>
Signed-off-by: Qiming Yang <qiming.yang@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(-)
  

Patch

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++;
 	}