[v2,25/26] net/ntnic: avoid possible deadlock

Message ID 20250505071309.586015-26-okl-plv@napatech.com (mailing list archive)
State Awaiting Upstream
Delegated to: Stephen Hemminger
Headers
Series net/ntnic: fixes and improvements |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Oleksandr Kolomeiets May 5, 2025, 7:13 a.m. UTC
From: Danylo Vodopianov <dvo-plv@napatech.com>

Sometimes during  high flow learn performance two threads
could cause deadlock using queue and mutex.

learn_ignored variable sets when flow learn and gets
when flow removes. Hence, learn_ignore should not be protected
as far as two thread could not access to the same flow
at the same time.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api_engine.h                | 2 +-
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)
  

Patch

diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h
index 859c76656a..6401c79e3c 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -297,7 +297,7 @@  struct flow_handle {
 	enum flow_handle_type type;
 	uint32_t flm_id;
 	uint16_t caller_id;
-	uint16_t learn_ignored;
+	RTE_ATOMIC(uint16_t) learn_ignored;
 
 	struct flow_eth_dev *dev;
 	struct flow_handle *next;
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 3133464675..cb6a66a061 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -518,9 +518,8 @@  static void flm_mtr_read_sta_records(struct flow_eth_dev *dev, uint32_t *data, u
 			uint8_t port;
 			bool remote_caller = is_remote_caller(caller_id, &port);
 
-			rte_spinlock_lock(&dev->ndev->mtx);
-			((struct flow_handle *)flm_h.p)->learn_ignored = 1;
-			rte_spinlock_unlock(&dev->ndev->mtx);
+			rte_atomic_store_explicit(&((struct flow_handle *)flm_h.p)->learn_ignored,
+				1, rte_memory_order_seq_cst);
 			struct flm_status_event_s data = {
 				.flow = flm_h.p,
 				.learn_ignore = sta_data->lis,
@@ -972,7 +971,7 @@  static int flm_flow_programming(struct flow_handle *fh, uint32_t flm_op)
 	if (flm_op == NT_FLM_OP_UNLEARN) {
 		ntnic_id_table_free_id(fh->dev->ndev->id_table_handle, flm_id);
 
-		if (fh->learn_ignored == 1)
+		if (rte_atomic_load_explicit(&fh->learn_ignored, rte_memory_order_seq_cst) == 1)
 			return 0;
 	}