Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <michael.chan@broadcom.com>
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Stanislav Fomichev <stfomichev@gmail.com>
Link: https://patch.msgid.link/20250616162117.287806-4-stfomichev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Stanislav Fomichev and committed by
Jakub Kicinski
1ead7501 df5425b3

+142 -73
+1 -2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
··· 10219 10219 10220 10220 static const struct udp_tunnel_nic_info bnx2x_udp_tunnels = { 10221 10221 .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, 10224 10223 .tables = { 10225 10224 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 10226 10225 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+2 -4
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 15573 15573 static const struct udp_tunnel_nic_info bnxt_udp_tunnels = { 15574 15574 .set_port = bnxt_udp_tunnel_set_port, 15575 15575 .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, 15578 15577 .tables = { 15579 15578 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 15580 15579 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, }, ··· 15581 15582 }, bnxt_udp_tunnels_p7 = { 15582 15583 .set_port = bnxt_udp_tunnel_set_port, 15583 15584 .unset_port = bnxt_udp_tunnel_unset_port, 15584 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP | 15585 - UDP_TUNNEL_NIC_INFO_OPEN_ONLY, 15585 + .flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY, 15586 15586 .tables = { 15587 15587 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 15588 15588 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+1 -2
drivers/net/ethernet/emulex/benet/be_main.c
··· 4031 4031 static const struct udp_tunnel_nic_info be_udp_tunnels = { 4032 4032 .set_port = be_vxlan_set_port, 4033 4033 .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, 4036 4035 .tables = { 4037 4036 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 4038 4037 },
-1
drivers/net/ethernet/intel/i40e/i40e_main.c
··· 15895 15895 15896 15896 pf->udp_tunnel_nic.set_port = i40e_udp_tunnel_set_port; 15897 15897 pf->udp_tunnel_nic.unset_port = i40e_udp_tunnel_unset_port; 15898 - pf->udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP; 15899 15898 pf->udp_tunnel_nic.shared = &pf->udp_tunnel_shared; 15900 15899 pf->udp_tunnel_nic.tables[0].n_entries = I40E_MAX_PF_UDP_OFFLOAD_PORTS; 15901 15900 pf->udp_tunnel_nic.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN |
-1
drivers/net/ethernet/intel/ice/ice_main.c
··· 4767 4767 4768 4768 pf->hw.udp_tunnel_nic.set_port = ice_udp_tunnel_set_port; 4769 4769 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; 4771 4770 pf->hw.udp_tunnel_nic.shared = &pf->hw.udp_tunnel_shared; 4772 4771 if (pf->hw.tnl.valid_count[TNL_VXLAN]) { 4773 4772 pf->hw.udp_tunnel_nic.tables[0].n_entries =
+1 -2
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
··· 2670 2670 2671 2671 static const struct udp_tunnel_nic_info mlx4_udp_tunnels = { 2672 2672 .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, 2675 2674 .tables = { 2676 2675 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 2677 2676 },
+1 -2
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 5351 5351 5352 5352 priv->nic_info.set_port = mlx5e_vxlan_set_port; 5353 5353 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; 5356 5355 priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN; 5357 5356 /* Don't count the space hard-coded to the IANA port */ 5358 5357 priv->nic_info.tables[0].n_entries =
+1 -2
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
··· 2394 2394 2395 2395 static const struct udp_tunnel_nic_info nfp_udp_tunnels = { 2396 2396 .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, 2399 2398 .tables = { 2400 2399 { 2401 2400 .n_entries = NFP_NET_N_VXLAN_PORTS,
-3
drivers/net/ethernet/qlogic/qede/qede_filter.c
··· 987 987 988 988 static const struct udp_tunnel_nic_info qede_udp_tunnels_both = { 989 989 .sync_table = qede_udp_tunnel_sync, 990 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, 991 990 .tables = { 992 991 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 993 992 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, }, 994 993 }, 995 994 }, qede_udp_tunnels_vxlan = { 996 995 .sync_table = qede_udp_tunnel_sync, 997 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, 998 996 .tables = { 999 997 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 1000 998 }, 1001 999 }, qede_udp_tunnels_geneve = { 1002 1000 .sync_table = qede_udp_tunnel_sync, 1003 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, 1004 1001 .tables = { 1005 1002 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, }, 1006 1003 },
-1
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
··· 486 486 487 487 static const struct udp_tunnel_nic_info qlcnic_udp_tunnels = { 488 488 .sync_table = qlcnic_udp_tunnel_sync, 489 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, 490 489 .tables = { 491 490 { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, 492 491 },
-1
drivers/net/ethernet/sfc/ef10.c
··· 3985 3985 static const struct udp_tunnel_nic_info efx_ef10_udp_tunnels = { 3986 3986 .set_port = efx_ef10_udp_tnl_set_port, 3987 3987 .unset_port = efx_ef10_udp_tnl_unset_port, 3988 - .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, 3989 3988 .tables = { 3990 3989 { 3991 3990 .n_entries = 16,
-4
drivers/net/netdevsim/udp_tunnels.c
··· 112 112 struct net_device *dev = file->private_data; 113 113 struct netdevsim *ns = netdev_priv(dev); 114 114 115 - rtnl_lock(); 116 115 if (dev->reg_state == NETREG_REGISTERED) { 117 116 memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports)); 118 117 udp_tunnel_nic_reset_ntf(dev); 119 118 } 120 - rtnl_unlock(); 121 119 122 120 return count; 123 121 } ··· 179 181 info->sync_table = NULL; 180 182 } 181 183 182 - if (ns->udp_ports.sleep) 183 - info->flags |= UDP_TUNNEL_NIC_INFO_MAY_SLEEP; 184 184 if (nsim_dev->udp_ports.open_only) 185 185 info->flags |= UDP_TUNNEL_NIC_INFO_OPEN_ONLY; 186 186 if (nsim_dev->udp_ports.ipv4_only)
+63 -24
include/net/udp_tunnel.h
··· 130 130 void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type); 131 131 void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type); 132 132 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 - 149 133 /* Transmit the skb using UDP encapsulation. */ 150 134 void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, 151 135 __be32 src, __be32 dst, __u8 tos, __u8 ttl, ··· 206 222 #define UDP_TUNNEL_NIC_MAX_TABLES 4 207 223 208 224 enum udp_tunnel_nic_info_flags { 209 - /* Device callbacks may sleep */ 210 - UDP_TUNNEL_NIC_INFO_MAY_SLEEP = BIT(0), 211 225 /* Device only supports offloads when it's open, all ports 212 226 * will be removed before close and re-added after open. 213 227 */ 214 - UDP_TUNNEL_NIC_INFO_OPEN_ONLY = BIT(1), 228 + UDP_TUNNEL_NIC_INFO_OPEN_ONLY = BIT(0), 215 229 /* Device supports only IPv4 tunnels */ 216 - UDP_TUNNEL_NIC_INFO_IPV4_ONLY = BIT(2), 230 + UDP_TUNNEL_NIC_INFO_IPV4_ONLY = BIT(1), 217 231 /* Device has hard-coded the IANA VXLAN port (4789) as VXLAN. 218 232 * This port must not be counted towards n_entries of any table. 219 233 * Driver will not receive any callback associated with port 4789. 220 234 */ 221 - UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN = BIT(3), 235 + UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN = BIT(2), 222 236 }; 223 237 224 238 struct udp_tunnel_nic; ··· 307 325 size_t (*dump_size)(struct net_device *dev, unsigned int table); 308 326 int (*dump_write)(struct net_device *dev, unsigned int table, 309 327 struct sk_buff *skb); 328 + void (*assert_locked)(struct net_device *dev); 329 + void (*lock)(struct net_device *dev); 330 + void (*unlock)(struct net_device *dev); 310 331 }; 311 332 312 333 #ifdef CONFIG_INET ··· 338 353 udp_tunnel_nic_set_port_priv(struct net_device *dev, unsigned int table, 339 354 unsigned int idx, u8 priv) 340 355 { 341 - if (udp_tunnel_nic_ops) 356 + if (udp_tunnel_nic_ops) { 357 + udp_tunnel_nic_ops->lock(dev); 342 358 udp_tunnel_nic_ops->set_port_priv(dev, table, idx, priv); 359 + udp_tunnel_nic_ops->unlock(dev); 360 + } 361 + } 362 + 363 + static inline void udp_tunnel_nic_assert_locked(struct net_device *dev) 364 + { 365 + if (udp_tunnel_nic_ops) 366 + udp_tunnel_nic_ops->assert_locked(dev); 367 + } 368 + 369 + static inline void udp_tunnel_nic_lock(struct net_device *dev) 370 + { 371 + if (udp_tunnel_nic_ops) 372 + udp_tunnel_nic_ops->lock(dev); 373 + } 374 + 375 + static inline void udp_tunnel_nic_unlock(struct net_device *dev) 376 + { 377 + if (udp_tunnel_nic_ops) 378 + udp_tunnel_nic_ops->unlock(dev); 343 379 } 344 380 345 381 static inline void ··· 402 396 static inline size_t 403 397 udp_tunnel_nic_dump_size(struct net_device *dev, unsigned int table) 404 398 { 399 + size_t ret; 400 + 405 401 if (!udp_tunnel_nic_ops) 406 402 return 0; 407 - return udp_tunnel_nic_ops->dump_size(dev, table); 403 + 404 + udp_tunnel_nic_ops->lock(dev); 405 + ret = udp_tunnel_nic_ops->dump_size(dev, table); 406 + udp_tunnel_nic_ops->unlock(dev); 407 + 408 + return ret; 408 409 } 409 410 410 411 static inline int 411 412 udp_tunnel_nic_dump_write(struct net_device *dev, unsigned int table, 412 413 struct sk_buff *skb) 413 414 { 415 + int ret; 416 + 414 417 if (!udp_tunnel_nic_ops) 415 418 return 0; 416 - return udp_tunnel_nic_ops->dump_write(dev, table, skb); 419 + 420 + udp_tunnel_nic_ops->lock(dev); 421 + ret = udp_tunnel_nic_ops->dump_write(dev, table, skb); 422 + udp_tunnel_nic_ops->unlock(dev); 423 + 424 + return ret; 417 425 } 426 + 427 + static inline void udp_tunnel_get_rx_info(struct net_device *dev) 428 + { 429 + ASSERT_RTNL(); 430 + if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) 431 + return; 432 + udp_tunnel_nic_assert_locked(dev); 433 + call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev); 434 + } 435 + 436 + static inline void udp_tunnel_drop_rx_info(struct net_device *dev) 437 + { 438 + ASSERT_RTNL(); 439 + if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) 440 + return; 441 + udp_tunnel_nic_assert_locked(dev); 442 + call_netdevice_notifiers(NETDEV_UDP_TUNNEL_DROP_INFO, dev); 443 + } 444 + 418 445 #endif
+2
net/core/dev.c
··· 10771 10771 * *before* calling udp_tunnel_get_rx_info, 10772 10772 * but *after* calling udp_tunnel_drop_rx_info. 10773 10773 */ 10774 + udp_tunnel_nic_lock(dev); 10774 10775 if (features & NETIF_F_RX_UDP_TUNNEL_PORT) { 10775 10776 dev->features = features; 10776 10777 udp_tunnel_get_rx_info(dev); 10777 10778 } else { 10778 10779 udp_tunnel_drop_rx_info(dev); 10779 10780 } 10781 + udp_tunnel_nic_unlock(dev); 10780 10782 } 10781 10783 10782 10784 if (diff & NETIF_F_HW_VLAN_CTAG_FILTER) {
+10 -6
net/ipv4/udp_tunnel_core.c
··· 134 134 struct udp_tunnel_info ti; 135 135 struct net_device *dev; 136 136 137 + ASSERT_RTNL(); 138 + 137 139 ti.type = type; 138 140 ti.sa_family = sk->sk_family; 139 141 ti.port = inet_sk(sk)->inet_sport; 140 142 141 - rcu_read_lock(); 142 - for_each_netdev_rcu(net, dev) { 143 + for_each_netdev(net, dev) { 144 + udp_tunnel_nic_lock(dev); 143 145 udp_tunnel_nic_add_port(dev, &ti); 146 + udp_tunnel_nic_unlock(dev); 144 147 } 145 - rcu_read_unlock(); 146 148 } 147 149 EXPORT_SYMBOL_GPL(udp_tunnel_notify_add_rx_port); 148 150 ··· 156 154 struct udp_tunnel_info ti; 157 155 struct net_device *dev; 158 156 157 + ASSERT_RTNL(); 158 + 159 159 ti.type = type; 160 160 ti.sa_family = sk->sk_family; 161 161 ti.port = inet_sk(sk)->inet_sport; 162 162 163 - rcu_read_lock(); 164 - for_each_netdev_rcu(net, dev) { 163 + for_each_netdev(net, dev) { 164 + udp_tunnel_nic_lock(dev); 165 165 udp_tunnel_nic_del_port(dev, &ti); 166 + udp_tunnel_nic_unlock(dev); 166 167 } 167 - rcu_read_unlock(); 168 168 } 169 169 EXPORT_SYMBOL_GPL(udp_tunnel_notify_del_rx_port); 170 170
+60 -18
net/ipv4/udp_tunnel_nic.c
··· 29 29 * struct udp_tunnel_nic - UDP tunnel port offload state 30 30 * @work: async work for talking to hardware from process context 31 31 * @dev: netdev pointer 32 + * @lock: protects all fields 32 33 * @need_sync: at least one port start changed 33 34 * @need_replay: space was freed, we need a replay of all ports 34 35 * @work_pending: @work is currently scheduled ··· 41 40 struct work_struct work; 42 41 43 42 struct net_device *dev; 43 + 44 + struct mutex lock; 44 45 45 46 u8 need_sync:1; 46 47 u8 need_replay:1; ··· 301 298 static void 302 299 udp_tunnel_nic_device_sync(struct net_device *dev, struct udp_tunnel_nic *utn) 303 300 { 304 - const struct udp_tunnel_nic_info *info = dev->udp_tunnel_nic_info; 305 - bool may_sleep; 306 - 307 301 if (!utn->need_sync) 308 302 return; 309 303 310 - /* Drivers which sleep in the callback need to update from 311 - * the workqueue, if we come from the tunnel driver's notification. 312 - */ 313 - may_sleep = info->flags & UDP_TUNNEL_NIC_INFO_MAY_SLEEP; 314 - if (!may_sleep) 315 - __udp_tunnel_nic_device_sync(dev, utn); 316 - if (may_sleep || utn->need_replay) { 317 - queue_work(udp_tunnel_nic_workqueue, &utn->work); 318 - utn->work_pending = 1; 319 - } 304 + queue_work(udp_tunnel_nic_workqueue, &utn->work); 305 + utn->work_pending = 1; 320 306 } 321 307 322 308 static bool ··· 546 554 struct udp_tunnel_nic *utn; 547 555 unsigned int i, j; 548 556 549 - ASSERT_RTNL(); 550 - 551 557 utn = dev->udp_tunnel_nic; 552 558 if (!utn) 553 559 return; 560 + 561 + mutex_lock(&utn->lock); 554 562 555 563 utn->need_sync = false; 556 564 for (i = 0; i < utn->n_tables; i++) ··· 561 569 562 570 entry->flags &= ~(UDP_TUNNEL_NIC_ENTRY_DEL | 563 571 UDP_TUNNEL_NIC_ENTRY_OP_FAIL); 564 - /* We don't release rtnl across ops */ 572 + /* We don't release utn lock across ops */ 565 573 WARN_ON(entry->flags & UDP_TUNNEL_NIC_ENTRY_FROZEN); 566 574 if (!entry->use_cnt) 567 575 continue; ··· 571 579 } 572 580 573 581 __udp_tunnel_nic_device_sync(dev, utn); 582 + 583 + mutex_unlock(&utn->lock); 574 584 } 575 585 576 586 static size_t ··· 637 643 return -EMSGSIZE; 638 644 } 639 645 646 + static void __udp_tunnel_nic_assert_locked(struct net_device *dev) 647 + { 648 + struct udp_tunnel_nic *utn; 649 + 650 + utn = dev->udp_tunnel_nic; 651 + if (utn) 652 + lockdep_assert_held(&utn->lock); 653 + } 654 + 655 + static void __udp_tunnel_nic_lock(struct net_device *dev) 656 + { 657 + struct udp_tunnel_nic *utn; 658 + 659 + utn = dev->udp_tunnel_nic; 660 + if (utn) 661 + mutex_lock(&utn->lock); 662 + } 663 + 664 + static void __udp_tunnel_nic_unlock(struct net_device *dev) 665 + { 666 + struct udp_tunnel_nic *utn; 667 + 668 + utn = dev->udp_tunnel_nic; 669 + if (utn) 670 + mutex_unlock(&utn->lock); 671 + } 672 + 640 673 static const struct udp_tunnel_nic_ops __udp_tunnel_nic_ops = { 641 674 .get_port = __udp_tunnel_nic_get_port, 642 675 .set_port_priv = __udp_tunnel_nic_set_port_priv, ··· 672 651 .reset_ntf = __udp_tunnel_nic_reset_ntf, 673 652 .dump_size = __udp_tunnel_nic_dump_size, 674 653 .dump_write = __udp_tunnel_nic_dump_write, 654 + .assert_locked = __udp_tunnel_nic_assert_locked, 655 + .lock = __udp_tunnel_nic_lock, 656 + .unlock = __udp_tunnel_nic_unlock, 675 657 }; 676 658 677 659 static void ··· 734 710 container_of(work, struct udp_tunnel_nic, work); 735 711 736 712 rtnl_lock(); 713 + mutex_lock(&utn->lock); 714 + 737 715 utn->work_pending = 0; 738 716 __udp_tunnel_nic_device_sync(utn->dev, utn); 739 717 740 718 if (utn->need_replay) 741 719 udp_tunnel_nic_replay(utn->dev, utn); 720 + 721 + mutex_unlock(&utn->lock); 742 722 rtnl_unlock(); 743 723 } 744 724 ··· 758 730 return NULL; 759 731 utn->n_tables = n_tables; 760 732 INIT_WORK(&utn->work, udp_tunnel_nic_device_sync_work); 733 + mutex_init(&utn->lock); 761 734 762 735 for (i = 0; i < n_tables; i++) { 763 736 utn->entries[i] = kcalloc(info->tables[i].n_entries, ··· 850 821 dev_hold(dev); 851 822 dev->udp_tunnel_nic = utn; 852 823 853 - if (!(info->flags & UDP_TUNNEL_NIC_INFO_OPEN_ONLY)) 824 + if (!(info->flags & UDP_TUNNEL_NIC_INFO_OPEN_ONLY)) { 825 + udp_tunnel_nic_lock(dev); 854 826 udp_tunnel_get_rx_info(dev); 827 + udp_tunnel_nic_unlock(dev); 828 + } 855 829 856 830 return 0; 857 831 } ··· 863 831 udp_tunnel_nic_unregister(struct net_device *dev, struct udp_tunnel_nic *utn) 864 832 { 865 833 const struct udp_tunnel_nic_info *info = dev->udp_tunnel_nic_info; 834 + 835 + udp_tunnel_nic_lock(dev); 866 836 867 837 /* For a shared table remove this dev from the list of sharing devices 868 838 * and if there are other devices just detach. ··· 875 841 list_for_each_entry(node, &info->shared->devices, list) 876 842 if (node->dev == dev) 877 843 break; 878 - if (list_entry_is_head(node, &info->shared->devices, list)) 844 + if (list_entry_is_head(node, &info->shared->devices, list)) { 845 + udp_tunnel_nic_unlock(dev); 879 846 return; 847 + } 880 848 881 849 list_del(&node->list); 882 850 kfree(node); ··· 888 852 if (first) { 889 853 udp_tunnel_drop_rx_info(dev); 890 854 utn->dev = first->dev; 855 + udp_tunnel_nic_unlock(dev); 891 856 goto release_dev; 892 857 } 893 858 ··· 899 862 * from the work which we will boot immediately. 900 863 */ 901 864 udp_tunnel_nic_flush(dev, utn); 865 + udp_tunnel_nic_unlock(dev); 902 866 903 867 /* Wait for the work to be done using the state, netdev core will 904 868 * retry unregister until we give up our reference on this device. ··· 948 910 return NOTIFY_DONE; 949 911 950 912 if (event == NETDEV_UP) { 913 + udp_tunnel_nic_lock(dev); 951 914 WARN_ON(!udp_tunnel_nic_is_empty(dev, utn)); 952 915 udp_tunnel_get_rx_info(dev); 916 + udp_tunnel_nic_unlock(dev); 953 917 return NOTIFY_OK; 954 918 } 955 919 if (event == NETDEV_GOING_DOWN) { 920 + udp_tunnel_nic_lock(dev); 956 921 udp_tunnel_nic_flush(dev, utn); 922 + udp_tunnel_nic_unlock(dev); 957 923 return NOTIFY_OK; 958 924 } 959 925