Skip to content

Commit 18a2b7f

Browse files
kuba-mooSaeed Mahameed
authored andcommitted
net/mlx5: convert to new udp_tunnel infrastructure
Allocate nic_info dynamically - n_entries is not constant. Attach the tunnel offload info only to the uplink representor. We expect the "main" netdev to be unregistered in switchdev mode, and there to be only one uplink representor. Drop the udp_tunnel_drop_rx_info() call, it was not there until commit b3c2ed2 ("net/mlx5e: Fix VXLAN configuration restore after function reload") so the device doesn't need it, and core should handle reloads and reset just fine. v2: - don't drop the ndos on reprs, and register info on uplink repr. v4: - Move netdev tunnel structure handling to en_main.c Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 966e505 commit 18a2b7f

File tree

5 files changed

+64
-136
lines changed

5 files changed

+64
-136
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <linux/mlx5/transobj.h>
4646
#include <linux/mlx5/fs.h>
4747
#include <linux/rhashtable.h>
48+
#include <net/udp_tunnel.h>
4849
#include <net/switchdev.h>
4950
#include <net/xdp.h>
5051
#include <linux/dim.h>
@@ -792,6 +793,7 @@ struct mlx5e_priv {
792793
u16 drop_rq_q_counter;
793794
struct notifier_block events_nb;
794795

796+
struct udp_tunnel_nic_info nic_info;
795797
#ifdef CONFIG_MLX5_CORE_EN_DCB
796798
struct mlx5e_dcbx dcbx;
797799
#endif
@@ -1012,6 +1014,7 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv);
10121014
int mlx5e_set_dev_port_mtu_ctx(struct mlx5e_priv *priv, void *context);
10131015
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
10141016
mlx5e_fp_preactivate preactivate);
1017+
void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv);
10151018

10161019
/* ethtool helpers */
10171020
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
@@ -1080,8 +1083,6 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
10801083
void mlx5e_rx_dim_work(struct work_struct *work);
10811084
void mlx5e_tx_dim_work(struct work_struct *work);
10821085

1083-
void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
1084-
void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
10851086
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
10861087
struct net_device *netdev,
10871088
netdev_features_t features);

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 38 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4191,83 +4191,6 @@ int mlx5e_get_vf_stats(struct net_device *dev,
41914191
}
41924192
#endif
41934193

4194-
struct mlx5e_vxlan_work {
4195-
struct work_struct work;
4196-
struct mlx5e_priv *priv;
4197-
u16 port;
4198-
};
4199-
4200-
static void mlx5e_vxlan_add_work(struct work_struct *work)
4201-
{
4202-
struct mlx5e_vxlan_work *vxlan_work =
4203-
container_of(work, struct mlx5e_vxlan_work, work);
4204-
struct mlx5e_priv *priv = vxlan_work->priv;
4205-
u16 port = vxlan_work->port;
4206-
4207-
mutex_lock(&priv->state_lock);
4208-
mlx5_vxlan_add_port(priv->mdev->vxlan, port);
4209-
mutex_unlock(&priv->state_lock);
4210-
4211-
kfree(vxlan_work);
4212-
}
4213-
4214-
static void mlx5e_vxlan_del_work(struct work_struct *work)
4215-
{
4216-
struct mlx5e_vxlan_work *vxlan_work =
4217-
container_of(work, struct mlx5e_vxlan_work, work);
4218-
struct mlx5e_priv *priv = vxlan_work->priv;
4219-
u16 port = vxlan_work->port;
4220-
4221-
mutex_lock(&priv->state_lock);
4222-
mlx5_vxlan_del_port(priv->mdev->vxlan, port);
4223-
mutex_unlock(&priv->state_lock);
4224-
kfree(vxlan_work);
4225-
}
4226-
4227-
static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
4228-
{
4229-
struct mlx5e_vxlan_work *vxlan_work;
4230-
4231-
vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
4232-
if (!vxlan_work)
4233-
return;
4234-
4235-
if (add)
4236-
INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
4237-
else
4238-
INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
4239-
4240-
vxlan_work->priv = priv;
4241-
vxlan_work->port = port;
4242-
queue_work(priv->wq, &vxlan_work->work);
4243-
}
4244-
4245-
void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4246-
{
4247-
struct mlx5e_priv *priv = netdev_priv(netdev);
4248-
4249-
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
4250-
return;
4251-
4252-
if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4253-
return;
4254-
4255-
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
4256-
}
4257-
4258-
void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4259-
{
4260-
struct mlx5e_priv *priv = netdev_priv(netdev);
4261-
4262-
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
4263-
return;
4264-
4265-
if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4266-
return;
4267-
4268-
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
4269-
}
4270-
42714194
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
42724195
struct sk_buff *skb,
42734196
netdev_features_t features)
@@ -4597,8 +4520,8 @@ const struct net_device_ops mlx5e_netdev_ops = {
45974520
.ndo_change_mtu = mlx5e_change_nic_mtu,
45984521
.ndo_do_ioctl = mlx5e_ioctl,
45994522
.ndo_set_tx_maxrate = mlx5e_set_tx_maxrate,
4600-
.ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
4601-
.ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
4523+
.ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
4524+
.ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
46024525
.ndo_features_check = mlx5e_features_check,
46034526
.ndo_tx_timeout = mlx5e_tx_timeout,
46044527
.ndo_bpf = mlx5e_xdp,
@@ -4869,6 +4792,39 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
48694792
}
48704793
}
48714794

4795+
static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
4796+
unsigned int entry, struct udp_tunnel_info *ti)
4797+
{
4798+
struct mlx5e_priv *priv = netdev_priv(netdev);
4799+
4800+
return mlx5_vxlan_add_port(priv->mdev->vxlan, ntohs(ti->port));
4801+
}
4802+
4803+
static int mlx5e_vxlan_unset_port(struct net_device *netdev, unsigned int table,
4804+
unsigned int entry, struct udp_tunnel_info *ti)
4805+
{
4806+
struct mlx5e_priv *priv = netdev_priv(netdev);
4807+
4808+
return mlx5_vxlan_del_port(priv->mdev->vxlan, ntohs(ti->port));
4809+
}
4810+
4811+
void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv)
4812+
{
4813+
if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4814+
return;
4815+
4816+
priv->nic_info.set_port = mlx5e_vxlan_set_port;
4817+
priv->nic_info.unset_port = mlx5e_vxlan_unset_port;
4818+
priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
4819+
UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
4820+
priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN;
4821+
/* Don't count the space hard-coded to the IANA port */
4822+
priv->nic_info.tables[0].n_entries =
4823+
mlx5_vxlan_max_udp_ports(priv->mdev) - 1;
4824+
4825+
priv->netdev->udp_tunnel_nic_info = &priv->nic_info;
4826+
}
4827+
48724828
static void mlx5e_build_nic_netdev(struct net_device *netdev)
48734829
{
48744830
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4912,6 +4868,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
49124868
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
49134869
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
49144870

4871+
mlx5e_vxlan_set_netdev_info(priv);
4872+
49154873
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
49164874
mlx5e_any_tunnel_proto_supported(mdev)) {
49174875
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
@@ -5217,8 +5175,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
52175175
rtnl_lock();
52185176
if (netif_running(netdev))
52195177
mlx5e_open(netdev);
5220-
if (mlx5_vxlan_allowed(priv->mdev->vxlan))
5221-
udp_tunnel_get_rx_info(netdev);
5178+
udp_tunnel_nic_reset_ntf(priv->netdev);
52225179
netif_device_attach(netdev);
52235180
rtnl_unlock();
52245181
}
@@ -5233,8 +5190,6 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
52335190
rtnl_lock();
52345191
if (netif_running(priv->netdev))
52355192
mlx5e_close(priv->netdev);
5236-
if (mlx5_vxlan_allowed(priv->mdev->vxlan))
5237-
udp_tunnel_drop_rx_info(priv->netdev);
52385193
netif_device_detach(priv->netdev);
52395194
rtnl_unlock();
52405195

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,8 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
658658
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
659659
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
660660
.ndo_change_mtu = mlx5e_uplink_rep_change_mtu,
661-
.ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
662-
.ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
661+
.ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
662+
.ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
663663
.ndo_features_check = mlx5e_features_check,
664664
.ndo_set_vf_mac = mlx5e_set_vf_mac,
665665
.ndo_set_vf_rate = mlx5e_set_vf_rate,
@@ -730,6 +730,7 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
730730
/* we want a persistent mac for the uplink rep */
731731
mlx5_query_mac_address(mdev, netdev->dev_addr);
732732
netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
733+
mlx5e_vxlan_set_netdev_info(priv);
733734
mlx5e_dcbnl_build_rep_netdev(netdev);
734735
} else {
735736
netdev->netdev_ops = &mlx5e_netdev_ops_rep;

drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c

Lines changed: 15 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,14 @@ struct mlx5_vxlan {
4242
struct mlx5_core_dev *mdev;
4343
/* max_num_ports is usuallly 4, 16 buckets is more than enough */
4444
DECLARE_HASHTABLE(htable, 4);
45-
int num_ports;
4645
struct mutex sync_lock; /* sync add/del port HW operations */
4746
};
4847

4948
struct mlx5_vxlan_port {
5049
struct hlist_node hlist;
51-
refcount_t refcount;
5250
u16 udp_port;
5351
};
5452

55-
static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
56-
{
57-
return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
58-
}
59-
6053
static int mlx5_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
6154
{
6255
u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {};
@@ -109,48 +102,24 @@ static struct mlx5_vxlan_port *vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 p
109102
int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
110103
{
111104
struct mlx5_vxlan_port *vxlanp;
112-
int ret = 0;
113-
114-
mutex_lock(&vxlan->sync_lock);
115-
vxlanp = vxlan_lookup_port(vxlan, port);
116-
if (vxlanp) {
117-
refcount_inc(&vxlanp->refcount);
118-
goto unlock;
119-
}
105+
int ret;
120106

121-
if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
122-
mlx5_core_info(vxlan->mdev,
123-
"UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
124-
port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
125-
ret = -ENOSPC;
126-
goto unlock;
127-
}
107+
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
108+
if (!vxlanp)
109+
return -ENOMEM;
110+
vxlanp->udp_port = port;
128111

129112
ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
130-
if (ret)
131-
goto unlock;
132-
133-
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
134-
if (!vxlanp) {
135-
ret = -ENOMEM;
136-
goto err_delete_port;
113+
if (ret) {
114+
kfree(vxlanp);
115+
return ret;
137116
}
138117

139-
vxlanp->udp_port = port;
140-
refcount_set(&vxlanp->refcount, 1);
141-
118+
mutex_lock(&vxlan->sync_lock);
142119
hash_add_rcu(vxlan->htable, &vxlanp->hlist, port);
143-
144-
vxlan->num_ports++;
145120
mutex_unlock(&vxlan->sync_lock);
146-
return 0;
147-
148-
err_delete_port:
149-
mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
150121

151-
unlock:
152-
mutex_unlock(&vxlan->sync_lock);
153-
return ret;
122+
return 0;
154123
}
155124

156125
int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
@@ -161,18 +130,15 @@ int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
161130
mutex_lock(&vxlan->sync_lock);
162131

163132
vxlanp = vxlan_lookup_port(vxlan, port);
164-
if (!vxlanp) {
133+
if (WARN_ON(!vxlanp)) {
165134
ret = -ENOENT;
166135
goto out_unlock;
167136
}
168137

169-
if (refcount_dec_and_test(&vxlanp->refcount)) {
170-
hash_del_rcu(&vxlanp->hlist);
171-
synchronize_rcu();
172-
mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
173-
kfree(vxlanp);
174-
vxlan->num_ports--;
175-
}
138+
hash_del_rcu(&vxlanp->hlist);
139+
synchronize_rcu();
140+
mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
141+
kfree(vxlanp);
176142

177143
out_unlock:
178144
mutex_unlock(&vxlan->sync_lock);

drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
struct mlx5_vxlan;
3838
struct mlx5_vxlan_port;
3939

40+
static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
41+
{
42+
return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
43+
}
44+
4045
static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
4146
{
4247
/* not allowed reason is encoded in vxlan pointer as error,

0 commit comments

Comments
 (0)