[net-next 04/13] net/mlx5e: Vxlan, replace spinlock with read-write lock

Saeed Mahameed
2018-07-27T22:40:46Z

From: Gal Pressman <galp@mellanox.com>

The VXLAN database is mainly used by readers in data path, and rarely
used by control path writers.
Multiple readers (threads) should not block each other and cause an
unnecessary contention on the lock.

Replacing the spinlock with rwlock optimizes the common use case where
adding ports to the table (adding VXLAN interfaces) is quite rare, but
the table is accessed for each VXLAN TX skb.

Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 6878925c3abf..870ac617550c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -655,7 +655,7 @@ enum {
};

struct mlx5e_vxlan_db {
- spinlock_t lock; /* protect vxlan table */
+ rwlock_t lock; /* protect vxlan table */
/* max_num_ports is usuallly 4, 16 buckets is more than enough */
DECLARE_HASHTABLE(htable, 4);
int num_ports;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 3c0ea9bc20e3..2733ca63e46b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -42,7 +42,7 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;

- spin_lock_init(&vxlan_db->lock);
+ rwlock_init(&vxlan_db->lock);
hash_init(vxlan_db->htable);

if (mlx5e_vxlan_allowed(priv->mdev))
@@ -98,9 +98,9 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;

- spin_lock_bh(&vxlan_db->lock);
+ read_lock_bh(&vxlan_db->lock);
vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
- spin_unlock_bh(&vxlan_db->lock);
+ read_unlock_bh(&vxlan_db->lock);

return vxlan;
}
@@ -133,9 +133,9 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
vxlan->udp_port = port;
atomic_set(&vxlan->refcount, 1);

- spin_lock_bh(&vxlan_db->lock);
+ write_lock_bh(&vxlan_db->lock);
hash_add(vxlan_db->htable, &vxlan->hlist, port);
- spin_unlock_bh(&vxlan_db->lock);
+ write_unlock_bh(&vxlan_db->lock);

vxlan_db->num_ports++;
return;
@@ -169,7 +169,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
bool remove = false;

mutex_lock(&priv->state_lock);
- spin_lock_bh(&vxlan_db->lock);
+ write_lock_bh(&vxlan_db->lock);
vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
if (!vxlan)
goto out_unlock;
@@ -180,7 +180,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
}

out_unlock:
- spin_unlock_bh(&vxlan_db->lock);
+ write_unlock_bh(&vxlan_db->lock);

if (remove) {
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
--
2.17.0