Skip to content

Commit 1ead750

Browse files
Stanislav Fomichevkuba-moo
authored andcommitted
udp_tunnel: remove rtnl_lock dependency
Drivers that are using ops lock and don't depend on RTNL lock still need to manage it because udp_tunnel's RTNL dependency. Introduce new udp_tunnel_nic_lock and use it instead of rtnl_lock. Drop non-UDP_TUNNEL_NIC_INFO_MAY_SLEEP mode from udp_tunnel infra (udp_tunnel_nic_device_sync_work needs to grab udp_tunnel_nic_lock mutex and might sleep). Cover more places in v4: - netlink - udp_tunnel_notify_add_rx_port (ndo_open) - triggers udp_tunnel_nic_device_sync_work - udp_tunnel_notify_del_rx_port (ndo_stop) - triggers udp_tunnel_nic_device_sync_work - udp_tunnel_get_rx_info (__netdev_update_features) - triggers NETDEV_UDP_TUNNEL_PUSH_INFO - udp_tunnel_drop_rx_info (__netdev_update_features) - triggers NETDEV_UDP_TUNNEL_DROP_INFO - udp_tunnel_nic_reset_ntf (ndo_open) - notifiers - udp_tunnel_nic_netdevice_event, depending on the event: - triggers NETDEV_UDP_TUNNEL_PUSH_INFO - triggers NETDEV_UDP_TUNNEL_DROP_INFO - ethnl_tunnel_info_reply_size - udp_tunnel_nic_set_port_priv (two intel drivers) Cc: Michael Chan <[email protected]> Suggested-by: Jakub Kicinski <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent df5425b commit 1ead750

File tree

16 files changed

+142
-73
lines changed

16 files changed

+142
-73
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10219,8 +10219,7 @@ static int bnx2x_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
1021910219

1022010220
static const struct udp_tunnel_nic_info bnx2x_udp_tunnels = {
1022110221
.sync_table = bnx2x_udp_tunnel_sync,
10222-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
10223-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
10222+
.flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
1022410223
.tables = {
1022510224
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
1022610225
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15573,17 +15573,15 @@ static int bnxt_udp_tunnel_unset_port(struct net_device *netdev, unsigned int ta
1557315573
static const struct udp_tunnel_nic_info bnxt_udp_tunnels = {
1557415574
.set_port = bnxt_udp_tunnel_set_port,
1557515575
.unset_port = bnxt_udp_tunnel_unset_port,
15576-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
15577-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
15576+
.flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
1557815577
.tables = {
1557915578
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
1558015579
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
1558115580
},
1558215581
}, bnxt_udp_tunnels_p7 = {
1558315582
.set_port = bnxt_udp_tunnel_set_port,
1558415583
.unset_port = bnxt_udp_tunnel_unset_port,
15585-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
15586-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
15584+
.flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
1558715585
.tables = {
1558815586
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
1558915587
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },

drivers/net/ethernet/emulex/benet/be_main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4031,8 +4031,7 @@ static int be_vxlan_unset_port(struct net_device *netdev, unsigned int table,
40314031
static const struct udp_tunnel_nic_info be_udp_tunnels = {
40324032
.set_port = be_vxlan_set_port,
40334033
.unset_port = be_vxlan_unset_port,
4034-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
4035-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
4034+
.flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
40364035
.tables = {
40374036
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
40384037
},

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15895,7 +15895,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1589515895

1589615896
pf->udp_tunnel_nic.set_port = i40e_udp_tunnel_set_port;
1589715897
pf->udp_tunnel_nic.unset_port = i40e_udp_tunnel_unset_port;
15898-
pf->udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP;
1589915898
pf->udp_tunnel_nic.shared = &pf->udp_tunnel_shared;
1590015899
pf->udp_tunnel_nic.tables[0].n_entries = I40E_MAX_PF_UDP_OFFLOAD_PORTS;
1590115900
pf->udp_tunnel_nic.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN |

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4767,7 +4767,6 @@ int ice_init_dev(struct ice_pf *pf)
47674767

47684768
pf->hw.udp_tunnel_nic.set_port = ice_udp_tunnel_set_port;
47694769
pf->hw.udp_tunnel_nic.unset_port = ice_udp_tunnel_unset_port;
4770-
pf->hw.udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP;
47714770
pf->hw.udp_tunnel_nic.shared = &pf->hw.udp_tunnel_shared;
47724771
if (pf->hw.tnl.valid_count[TNL_VXLAN]) {
47734772
pf->hw.udp_tunnel_nic.tables[0].n_entries =

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,8 +2670,7 @@ static int mlx4_udp_tunnel_sync(struct net_device *dev, unsigned int table)
26702670

26712671
static const struct udp_tunnel_nic_info mlx4_udp_tunnels = {
26722672
.sync_table = mlx4_udp_tunnel_sync,
2673-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
2674-
UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
2673+
.flags = UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
26752674
.tables = {
26762675
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
26772676
},

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5351,8 +5351,7 @@ void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv)
53515351

53525352
priv->nic_info.set_port = mlx5e_vxlan_set_port;
53535353
priv->nic_info.unset_port = mlx5e_vxlan_unset_port;
5354-
priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
5355-
UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
5354+
priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
53565355
priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN;
53575356
/* Don't count the space hard-coded to the IANA port */
53585357
priv->nic_info.tables[0].n_entries =

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,8 +2394,7 @@ static int nfp_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
23942394

23952395
static const struct udp_tunnel_nic_info nfp_udp_tunnels = {
23962396
.sync_table = nfp_udp_tunnel_sync,
2397-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
2398-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
2397+
.flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
23992398
.tables = {
24002399
{
24012400
.n_entries = NFP_NET_N_VXLAN_PORTS,

drivers/net/ethernet/qlogic/qede/qede_filter.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -987,20 +987,17 @@ static int qede_udp_tunnel_sync(struct net_device *dev, unsigned int table)
987987

988988
static const struct udp_tunnel_nic_info qede_udp_tunnels_both = {
989989
.sync_table = qede_udp_tunnel_sync,
990-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
991990
.tables = {
992991
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
993992
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
994993
},
995994
}, qede_udp_tunnels_vxlan = {
996995
.sync_table = qede_udp_tunnel_sync,
997-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
998996
.tables = {
999997
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
1000998
},
1001999
}, qede_udp_tunnels_geneve = {
10021000
.sync_table = qede_udp_tunnel_sync,
1003-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
10041001
.tables = {
10051002
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
10061003
},

drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,6 @@ static int qlcnic_udp_tunnel_sync(struct net_device *dev, unsigned int table)
486486

487487
static const struct udp_tunnel_nic_info qlcnic_udp_tunnels = {
488488
.sync_table = qlcnic_udp_tunnel_sync,
489-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
490489
.tables = {
491490
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
492491
},

drivers/net/ethernet/sfc/ef10.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3985,7 +3985,6 @@ static int efx_ef10_udp_tnl_unset_port(struct net_device *dev,
39853985
static const struct udp_tunnel_nic_info efx_ef10_udp_tunnels = {
39863986
.set_port = efx_ef10_udp_tnl_set_port,
39873987
.unset_port = efx_ef10_udp_tnl_unset_port,
3988-
.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
39893988
.tables = {
39903989
{
39913990
.n_entries = 16,

drivers/net/netdevsim/udp_tunnels.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,10 @@ nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data,
112112
struct net_device *dev = file->private_data;
113113
struct netdevsim *ns = netdev_priv(dev);
114114

115-
rtnl_lock();
116115
if (dev->reg_state == NETREG_REGISTERED) {
117116
memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
118117
udp_tunnel_nic_reset_ntf(dev);
119118
}
120-
rtnl_unlock();
121119

122120
return count;
123121
}
@@ -181,8 +179,6 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
181179
info->sync_table = NULL;
182180
}
183181

184-
if (ns->udp_ports.sleep)
185-
info->flags |= UDP_TUNNEL_NIC_INFO_MAY_SLEEP;
186182
if (nsim_dev->udp_ports.open_only)
187183
info->flags |= UDP_TUNNEL_NIC_INFO_OPEN_ONLY;
188184
if (nsim_dev->udp_ports.ipv4_only)

include/net/udp_tunnel.h

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,6 @@ void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
130130
void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type);
131131
void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type);
132132

133-
static inline void udp_tunnel_get_rx_info(struct net_device *dev)
134-
{
135-
ASSERT_RTNL();
136-
if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
137-
return;
138-
call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev);
139-
}
140-
141-
static inline void udp_tunnel_drop_rx_info(struct net_device *dev)
142-
{
143-
ASSERT_RTNL();
144-
if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
145-
return;
146-
call_netdevice_notifiers(NETDEV_UDP_TUNNEL_DROP_INFO, dev);
147-
}
148-
149133
/* Transmit the skb using UDP encapsulation. */
150134
void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
151135
__be32 src, __be32 dst, __u8 tos, __u8 ttl,
@@ -222,19 +206,17 @@ static inline void udp_tunnel_encap_enable(struct sock *sk)
222206
#define UDP_TUNNEL_NIC_MAX_TABLES 4
223207

224208
enum udp_tunnel_nic_info_flags {
225-
/* Device callbacks may sleep */
226-
UDP_TUNNEL_NIC_INFO_MAY_SLEEP = BIT(0),
227209
/* Device only supports offloads when it's open, all ports
228210
* will be removed before close and re-added after open.
229211
*/
230-
UDP_TUNNEL_NIC_INFO_OPEN_ONLY = BIT(1),
212+
UDP_TUNNEL_NIC_INFO_OPEN_ONLY = BIT(0),
231213
/* Device supports only IPv4 tunnels */
232-
UDP_TUNNEL_NIC_INFO_IPV4_ONLY = BIT(2),
214+
UDP_TUNNEL_NIC_INFO_IPV4_ONLY = BIT(1),
233215
/* Device has hard-coded the IANA VXLAN port (4789) as VXLAN.
234216
* This port must not be counted towards n_entries of any table.
235217
* Driver will not receive any callback associated with port 4789.
236218
*/
237-
UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN = BIT(3),
219+
UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN = BIT(2),
238220
};
239221

240222
struct udp_tunnel_nic;
@@ -325,6 +307,9 @@ struct udp_tunnel_nic_ops {
325307
size_t (*dump_size)(struct net_device *dev, unsigned int table);
326308
int (*dump_write)(struct net_device *dev, unsigned int table,
327309
struct sk_buff *skb);
310+
void (*assert_locked)(struct net_device *dev);
311+
void (*lock)(struct net_device *dev);
312+
void (*unlock)(struct net_device *dev);
328313
};
329314

330315
#ifdef CONFIG_INET
@@ -353,8 +338,29 @@ static inline void
353338
udp_tunnel_nic_set_port_priv(struct net_device *dev, unsigned int table,
354339
unsigned int idx, u8 priv)
355340
{
356-
if (udp_tunnel_nic_ops)
341+
if (udp_tunnel_nic_ops) {
342+
udp_tunnel_nic_ops->lock(dev);
357343
udp_tunnel_nic_ops->set_port_priv(dev, table, idx, priv);
344+
udp_tunnel_nic_ops->unlock(dev);
345+
}
346+
}
347+
348+
static inline void udp_tunnel_nic_assert_locked(struct net_device *dev)
349+
{
350+
if (udp_tunnel_nic_ops)
351+
udp_tunnel_nic_ops->assert_locked(dev);
352+
}
353+
354+
static inline void udp_tunnel_nic_lock(struct net_device *dev)
355+
{
356+
if (udp_tunnel_nic_ops)
357+
udp_tunnel_nic_ops->lock(dev);
358+
}
359+
360+
static inline void udp_tunnel_nic_unlock(struct net_device *dev)
361+
{
362+
if (udp_tunnel_nic_ops)
363+
udp_tunnel_nic_ops->unlock(dev);
358364
}
359365

360366
static inline void
@@ -396,17 +402,50 @@ static inline void udp_tunnel_nic_reset_ntf(struct net_device *dev)
396402
static inline size_t
397403
udp_tunnel_nic_dump_size(struct net_device *dev, unsigned int table)
398404
{
405+
size_t ret;
406+
399407
if (!udp_tunnel_nic_ops)
400408
return 0;
401-
return udp_tunnel_nic_ops->dump_size(dev, table);
409+
410+
udp_tunnel_nic_ops->lock(dev);
411+
ret = udp_tunnel_nic_ops->dump_size(dev, table);
412+
udp_tunnel_nic_ops->unlock(dev);
413+
414+
return ret;
402415
}
403416

404417
static inline int
405418
udp_tunnel_nic_dump_write(struct net_device *dev, unsigned int table,
406419
struct sk_buff *skb)
407420
{
421+
int ret;
422+
408423
if (!udp_tunnel_nic_ops)
409424
return 0;
410-
return udp_tunnel_nic_ops->dump_write(dev, table, skb);
425+
426+
udp_tunnel_nic_ops->lock(dev);
427+
ret = udp_tunnel_nic_ops->dump_write(dev, table, skb);
428+
udp_tunnel_nic_ops->unlock(dev);
429+
430+
return ret;
431+
}
432+
433+
static inline void udp_tunnel_get_rx_info(struct net_device *dev)
434+
{
435+
ASSERT_RTNL();
436+
if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
437+
return;
438+
udp_tunnel_nic_assert_locked(dev);
439+
call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev);
411440
}
441+
442+
static inline void udp_tunnel_drop_rx_info(struct net_device *dev)
443+
{
444+
ASSERT_RTNL();
445+
if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
446+
return;
447+
udp_tunnel_nic_assert_locked(dev);
448+
call_netdevice_notifiers(NETDEV_UDP_TUNNEL_DROP_INFO, dev);
449+
}
450+
412451
#endif

net/core/dev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10771,12 +10771,14 @@ int __netdev_update_features(struct net_device *dev)
1077110771
* *before* calling udp_tunnel_get_rx_info,
1077210772
* but *after* calling udp_tunnel_drop_rx_info.
1077310773
*/
10774+
udp_tunnel_nic_lock(dev);
1077410775
if (features & NETIF_F_RX_UDP_TUNNEL_PORT) {
1077510776
dev->features = features;
1077610777
udp_tunnel_get_rx_info(dev);
1077710778
} else {
1077810779
udp_tunnel_drop_rx_info(dev);
1077910780
}
10781+
udp_tunnel_nic_unlock(dev);
1078010782
}
1078110783

1078210784
if (diff & NETIF_F_HW_VLAN_CTAG_FILTER) {

net/ipv4/udp_tunnel_core.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,17 @@ void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type)
134134
struct udp_tunnel_info ti;
135135
struct net_device *dev;
136136

137+
ASSERT_RTNL();
138+
137139
ti.type = type;
138140
ti.sa_family = sk->sk_family;
139141
ti.port = inet_sk(sk)->inet_sport;
140142

141-
rcu_read_lock();
142-
for_each_netdev_rcu(net, dev) {
143+
for_each_netdev(net, dev) {
144+
udp_tunnel_nic_lock(dev);
143145
udp_tunnel_nic_add_port(dev, &ti);
146+
udp_tunnel_nic_unlock(dev);
144147
}
145-
rcu_read_unlock();
146148
}
147149
EXPORT_SYMBOL_GPL(udp_tunnel_notify_add_rx_port);
148150

@@ -154,15 +156,17 @@ void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type)
154156
struct udp_tunnel_info ti;
155157
struct net_device *dev;
156158

159+
ASSERT_RTNL();
160+
157161
ti.type = type;
158162
ti.sa_family = sk->sk_family;
159163
ti.port = inet_sk(sk)->inet_sport;
160164

161-
rcu_read_lock();
162-
for_each_netdev_rcu(net, dev) {
165+
for_each_netdev(net, dev) {
166+
udp_tunnel_nic_lock(dev);
163167
udp_tunnel_nic_del_port(dev, &ti);
168+
udp_tunnel_nic_unlock(dev);
164169
}
165-
rcu_read_unlock();
166170
}
167171
EXPORT_SYMBOL_GPL(udp_tunnel_notify_del_rx_port);
168172

0 commit comments

Comments
 (0)