diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 41 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | 1 |
3 files changed, 28 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index c4d4db8722f5..6878925c3abf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -656,7 +656,8 @@ enum { struct mlx5e_vxlan_db { spinlock_t lock; /* protect vxlan table */ - struct radix_tree_root tree; + /* 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 e3af2efe18ce..3c0ea9bc20e3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c @@ -43,7 +43,7 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv) struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; spin_lock_init(&vxlan_db->lock); - INIT_RADIX_TREE(&vxlan_db->tree, GFP_ATOMIC); + hash_init(vxlan_db->htable); if (mlx5e_vxlan_allowed(priv->mdev)) /* Hardware adds 4789 by default. @@ -79,13 +79,27 @@ static int mlx5e_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port) return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); } +static struct mlx5e_vxlan *mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv, + u16 port) +{ + struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; + struct mlx5e_vxlan *vxlan; + + hash_for_each_possible(vxlan_db->htable, vxlan, hlist, port) { + if (vxlan->udp_port == port) + return vxlan; + } + + return NULL; +} + 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); - vxlan = radix_tree_lookup(&vxlan_db->tree, port); + vxlan = mlx5e_vxlan_lookup_port_locked(priv, port); spin_unlock_bh(&vxlan_db->lock); return vxlan; @@ -95,7 +109,6 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) { struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; struct mlx5e_vxlan *vxlan; - int err; vxlan = mlx5e_vxlan_lookup_port(priv, port); if (vxlan) { @@ -121,16 +134,12 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) atomic_set(&vxlan->refcount, 1); spin_lock_bh(&vxlan_db->lock); - err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); + hash_add(vxlan_db->htable, &vxlan->hlist, port); spin_unlock_bh(&vxlan_db->lock); - if (err) - goto err_free; vxlan_db->num_ports++; return; -err_free: - kfree(vxlan); err_delete_port: mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); } @@ -161,12 +170,12 @@ static void mlx5e_vxlan_del_work(struct work_struct *work) mutex_lock(&priv->state_lock); spin_lock_bh(&vxlan_db->lock); - vxlan = radix_tree_lookup(&vxlan_db->tree, port); + vxlan = mlx5e_vxlan_lookup_port_locked(priv, port); if (!vxlan) goto out_unlock; if (atomic_dec_and_test(&vxlan->refcount)) { - radix_tree_delete(&vxlan_db->tree, port); + hash_del(&vxlan->hlist); remove = true; } @@ -206,13 +215,13 @@ void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) { struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; struct mlx5e_vxlan *vxlan; - unsigned int port = 0; + struct hlist_node *tmp; + int bkt; - /* Lockless since we are the only radix-tree consumers, wq is disabled */ - while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) { - port = vxlan->udp_port; - radix_tree_delete(&vxlan_db->tree, port); - mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); + /* Lockless since we are the only hash table consumers, wq and TX are disabled */ + hash_for_each_safe(vxlan_db->htable, bkt, tmp, vxlan, hlist) { + hash_del(&vxlan->hlist); + mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port); kfree(vxlan); } } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h index 5ef6ae7d568a..52c41c22235d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h @@ -36,6 +36,7 @@ #include "en.h" struct mlx5e_vxlan { + struct hlist_node hlist; atomic_t refcount; u16 udp_port; }; |