lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190809220359.11516-4-saeedm@mellanox.com>
Date:   Fri, 9 Aug 2019 22:04:23 +0000
From:   Saeed Mahameed <saeedm@...lanox.com>
To:     "David S. Miller" <davem@...emloft.net>
CC:     "netdev@...r.kernel.org" <netdev@...r.kernel.org>,
        Vlad Buslov <vladbu@...lanox.com>,
        Roi Dayan <roid@...lanox.com>,
        Saeed Mahameed <saeedm@...lanox.com>
Subject: [net-next 03/15] net/mlx5e: Protect hairpin hash table with mutex

From: Vlad Buslov <vladbu@...lanox.com>

To remove dependency on rtnl lock, protect hairpin hash table from
concurrent modifications with new "hairpin_tbl_lock" mutex.

Signed-off-by: Vlad Buslov <vladbu@...lanox.com>
Reviewed-by: Roi Dayan <roid@...lanox.com>
Signed-off-by: Saeed Mahameed <saeedm@...lanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en/fs.h   |  1 +
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   | 21 +++++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index 4518ce19112e..100506a3dd58 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -17,6 +17,7 @@ struct mlx5e_tc_table {
 	struct rhashtable               ht;
 
 	DECLARE_HASHTABLE(mod_hdr_tbl, 8);
+	struct mutex hairpin_tbl_lock; /* protects hairpin_tbl */
 	DECLARE_HASHTABLE(hairpin_tbl, 8);
 
 	struct notifier_block     netdevice_nb;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 0abfa9b3ec54..a7acb7fcbf5a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -652,15 +652,16 @@ static void mlx5e_hairpin_put(struct mlx5e_priv *priv,
 			      struct mlx5e_hairpin_entry *hpe)
 {
 	/* no more hairpin flows for us, release the hairpin pair */
-	if (!refcount_dec_and_test(&hpe->refcnt))
+	if (!refcount_dec_and_mutex_lock(&hpe->refcnt, &priv->fs.tc.hairpin_tbl_lock))
 		return;
+	hash_del(&hpe->hairpin_hlist);
+	mutex_unlock(&priv->fs.tc.hairpin_tbl_lock);
 
 	netdev_dbg(priv->netdev, "del hairpin: peer %s\n",
 		   dev_name(hpe->hp->pair->peer_mdev->device));
 
 	WARN_ON(!list_empty(&hpe->flows));
 	mlx5e_hairpin_destroy(hpe->hp);
-	hash_del(&hpe->hairpin_hlist);
 	kfree(hpe);
 }
 
@@ -729,13 +730,17 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
 				     extack);
 	if (err)
 		return err;
+
+	mutex_lock(&priv->fs.tc.hairpin_tbl_lock);
 	hpe = mlx5e_hairpin_get(priv, peer_id, match_prio);
 	if (hpe)
 		goto attach_flow;
 
 	hpe = kzalloc(sizeof(*hpe), GFP_KERNEL);
-	if (!hpe)
-		return -ENOMEM;
+	if (!hpe) {
+		err = -ENOMEM;
+		goto create_hairpin_err;
+	}
 
 	spin_lock_init(&hpe->flows_lock);
 	INIT_LIST_HEAD(&hpe->flows);
@@ -784,6 +789,8 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
 	} else {
 		flow->nic_attr->hairpin_tirn = hpe->hp->tirn;
 	}
+	mutex_unlock(&priv->fs.tc.hairpin_tbl_lock);
+
 	flow->hpe = hpe;
 	spin_lock(&hpe->flows_lock);
 	list_add(&flow->hairpin, &hpe->flows);
@@ -792,6 +799,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
 	return 0;
 
 create_hairpin_err:
+	mutex_unlock(&priv->fs.tc.hairpin_tbl_lock);
 	kfree(hpe);
 	return err;
 }
@@ -3768,10 +3776,12 @@ static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
 
 	peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id);
 
+	mutex_lock(&priv->fs.tc.hairpin_tbl_lock);
 	hash_for_each(priv->fs.tc.hairpin_tbl, bkt, hpe, hairpin_hlist) {
 		if (hpe->peer_vhca_id == peer_vhca_id)
 			hpe->hp->pair->peer_gone = true;
 	}
+	mutex_unlock(&priv->fs.tc.hairpin_tbl_lock);
 }
 
 static int mlx5e_tc_netdev_event(struct notifier_block *this,
@@ -3808,6 +3818,7 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
 
 	mutex_init(&tc->t_lock);
 	hash_init(tc->mod_hdr_tbl);
+	mutex_init(&tc->hairpin_tbl_lock);
 	hash_init(tc->hairpin_tbl);
 
 	err = rhashtable_init(&tc->ht, &tc_ht_params);
@@ -3839,6 +3850,8 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
 	if (tc->netdevice_nb.notifier_call)
 		unregister_netdevice_notifier(&tc->netdevice_nb);
 
+	mutex_destroy(&tc->hairpin_tbl_lock);
+
 	rhashtable_destroy(&tc->ht);
 
 	if (!IS_ERR_OR_NULL(tc->t)) {
-- 
2.21.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ