git: 015f22f5d033 - main - mlx5en: Fix TLS worker thread race.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Thu, 17 Feb 2022 12:13:50 UTC
The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=015f22f5d0338882ab4a1e1585622ff3568dface

commit 015f22f5d0338882ab4a1e1585622ff3568dface
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-02-17 11:48:57 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-02-17 12:13:09 +0000

    mlx5en: Fix TLS worker thread race.
    
    Create a dedicated free state, in case the taskqueue worker is still pending,
    to avoid re-activation of a freed send tag.
    
    MFC after:      1 week
    Sponsored by:   NVIDIA Networking
---
 sys/dev/mlx5/mlx5_en/en_hw_tls.h         |  3 ++-
 sys/dev/mlx5/mlx5_en/en_hw_tls_rx.h      |  3 ++-
 sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c    | 11 +++++++----
 sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c | 12 ++++++++----
 4 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_en/en_hw_tls.h b/sys/dev/mlx5/mlx5_en/en_hw_tls.h
index f9d5ae23e82c..70b493a5e82d 100644
--- a/sys/dev/mlx5/mlx5_en/en_hw_tls.h
+++ b/sys/dev/mlx5/mlx5_en/en_hw_tls.h
@@ -55,7 +55,8 @@ struct mlx5e_tls_tag {
 #define	MLX5E_TLS_ST_INIT 0
 #define	MLX5E_TLS_ST_SETUP 1
 #define	MLX5E_TLS_ST_TXRDY 2
-#define	MLX5E_TLS_ST_FREED 3
+#define	MLX5E_TLS_ST_RELEASE 3
+#define	MLX5E_TLS_ST_FREED 4
 	struct work_struct work;
 
 	uint32_t dek_index_ok:1;
diff --git a/sys/dev/mlx5/mlx5_en/en_hw_tls_rx.h b/sys/dev/mlx5/mlx5_en/en_hw_tls_rx.h
index 4bdcbda0076e..4843a0ab8423 100644
--- a/sys/dev/mlx5/mlx5_en/en_hw_tls_rx.h
+++ b/sys/dev/mlx5/mlx5_en/en_hw_tls_rx.h
@@ -70,7 +70,8 @@ struct mlx5e_tls_rx_tag {
 #define	MLX5E_TLS_RX_ST_INIT 0
 #define	MLX5E_TLS_RX_ST_SETUP 1
 #define	MLX5E_TLS_RX_ST_READY 2
-#define	MLX5E_TLS_RX_ST_FREED 3
+#define	MLX5E_TLS_RX_ST_RELEASE 3
+#define	MLX5E_TLS_RX_ST_FREED 4
 
 	/*
 	 * The following fields are used to store the TCP starting
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c
index a1973740571d..e6b4759aeb7a 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c
@@ -127,9 +127,10 @@ mlx5e_tls_tag_release(void *arg, void **store, int cnt)
 static void
 mlx5e_tls_tag_zfree(struct mlx5e_tls_tag *ptag)
 {
+	/* make sure any unhandled taskqueue events are ignored */
+	ptag->state = MLX5E_TLS_ST_FREED;
 
 	/* reset some variables */
-	ptag->state = MLX5E_TLS_ST_INIT;
 	ptag->dek_index = 0;
 	ptag->dek_index_ok = 0;
 
@@ -256,7 +257,7 @@ mlx5e_tls_work(struct work_struct *work)
 		MLX5E_TLS_TAG_UNLOCK(ptag);
 		break;
 
-	case MLX5E_TLS_ST_FREED:
+	case MLX5E_TLS_ST_RELEASE:
 		/* try to destroy DEK context by ID */
 		if (ptag->dek_index_ok)
 			err = mlx5_encryption_key_destroy(priv->mdev, ptag->dek_index);
@@ -330,7 +331,6 @@ mlx5e_tls_snd_tag_alloc(struct ifnet *ifp,
 		return (ENOMEM);
 
 	/* sanity check default values */
-	MPASS(ptag->state == MLX5E_TLS_ST_INIT);
 	MPASS(ptag->dek_index == 0);
 	MPASS(ptag->dek_index_ok == 0);
 
@@ -438,6 +438,9 @@ mlx5e_tls_snd_tag_alloc(struct ifnet *ifp,
 	m_snd_tag_init(&ptag->tag, ifp, snd_tag_sw);
 	*ppmt = &ptag->tag;
 
+	/* reset state */
+	ptag->state = MLX5E_TLS_ST_INIT;
+
 	queue_work(priv->tls.wq, &ptag->work);
 	flush_work(&ptag->work);
 
@@ -483,7 +486,7 @@ mlx5e_tls_snd_tag_free(struct m_snd_tag *pmt)
 	m_snd_tag_rele(ptag->rl_tag);
 
 	MLX5E_TLS_TAG_LOCK(ptag);
-	ptag->state = MLX5E_TLS_ST_FREED;
+	ptag->state = MLX5E_TLS_ST_RELEASE;
 	MLX5E_TLS_TAG_UNLOCK(ptag);
 
 	priv = ptag->tag.ifp->if_softc;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
index 4a6fc8f2d202..39bbd6a37cf3 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
@@ -427,8 +427,10 @@ mlx5e_tls_rx_tag_release(void *arg, void **store, int cnt)
 static void
 mlx5e_tls_rx_tag_zfree(struct mlx5e_tls_rx_tag *ptag)
 {
+	/* make sure any unhandled taskqueue events are ignored */
+	ptag->state = MLX5E_TLS_RX_ST_FREED;
+
 	/* reset some variables */
-	ptag->state = MLX5E_TLS_RX_ST_INIT;
 	ptag->dek_index = 0;
 	ptag->dek_index_ok = 0;
 	ptag->tirn = 0;
@@ -569,7 +571,7 @@ mlx5e_tls_rx_work(struct work_struct *work)
 		MLX5E_TLS_RX_TAG_UNLOCK(ptag);
 		break;
 
-	case MLX5E_TLS_RX_ST_FREED:
+	case MLX5E_TLS_RX_ST_RELEASE:
 		/* remove flow rule for incoming traffic, if any */
 		if (ptag->flow_rule != NULL)
 			mlx5e_accel_fs_del_inpcb(ptag->flow_rule);
@@ -676,7 +678,6 @@ mlx5e_tls_rx_snd_tag_alloc(struct ifnet *ifp,
 		return (ENOMEM);
 
 	/* sanity check default values */
-	MPASS(ptag->state == MLX5E_TLS_RX_ST_INIT);
 	MPASS(ptag->dek_index == 0);
 	MPASS(ptag->dek_index_ok == 0);
 
@@ -760,6 +761,9 @@ mlx5e_tls_rx_snd_tag_alloc(struct ifnet *ifp,
 	m_snd_tag_init(&ptag->tag, ifp, &mlx5e_tls_rx_snd_tag_sw);
 	*ppmt = &ptag->tag;
 
+	/* reset state */
+	ptag->state = MLX5E_TLS_RX_ST_INIT;
+
 	queue_work(priv->tls_rx.wq, &ptag->work);
 	flush_work(&ptag->work);
 
@@ -989,7 +993,7 @@ mlx5e_tls_rx_snd_tag_free(struct m_snd_tag *pmt)
 	struct mlx5e_priv *priv;
 
 	MLX5E_TLS_RX_TAG_LOCK(ptag);
-	ptag->state = MLX5E_TLS_RX_ST_FREED;
+	ptag->state = MLX5E_TLS_RX_ST_RELEASE;
 	MLX5E_TLS_RX_TAG_UNLOCK(ptag);
 
 	priv = ptag->tag.ifp->if_softc;