Skip to content

Commit 03df156

Browse files
committed
xdp: double protect netdev->xdp_flags with netdev->lock
Protect xdp_features with netdev->lock. This way pure readers no longer have to take rtnl_lock to access the field. This includes calling NETDEV_XDP_FEAT_CHANGE under the lock. Looks like that's fine for bonding, the only "real" listener, it's the same as ethtool feature change. In terms of normal drivers - only GVE need special consideration (other drivers don't use instance lock or don't support XDP). It calls xdp_set_features_flag() helper from gve_init_priv() which in turn is called from gve_reset_recovery() (locked), or prior to netdev registration. So switch to _locked. Reviewed-by: Joe Damato <[email protected]> Acked-by: Stanislav Fomichev <[email protected]> Acked-by: Harshitha Ramamurthy <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent d02e3b3 commit 03df156

File tree

6 files changed

+16
-4
lines changed

6 files changed

+16
-4
lines changed

Documentation/networking/netdevices.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ For devices with locked ops, currently only the following notifiers are
354354
running under the lock:
355355
* ``NETDEV_REGISTER``
356356
* ``NETDEV_UP``
357+
* ``NETDEV_XDP_FEAT_CHANGE``
357358

358359
The following notifiers are running without the lock:
359360
* ``NETDEV_UNREGISTER``

drivers/net/ethernet/google/gve/gve_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2185,7 +2185,7 @@ static void gve_set_netdev_xdp_features(struct gve_priv *priv)
21852185
xdp_features = 0;
21862186
}
21872187

2188-
xdp_set_features_flag(priv->dev, xdp_features);
2188+
xdp_set_features_flag_locked(priv->dev, xdp_features);
21892189
}
21902190

21912191
static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device)

include/linux/netdevice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2526,7 +2526,7 @@ struct net_device {
25262526
* @net_shaper_hierarchy, @reg_state, @threaded
25272527
*
25282528
* Double protects:
2529-
* @up, @moving_ns, @nd_net
2529+
* @up, @moving_ns, @nd_net, @xdp_flags
25302530
*
25312531
* Double ops protects:
25322532
* @real_num_rx_queues, @real_num_tx_queues

include/net/xdp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ struct xdp_metadata_ops {
616616
u32 bpf_xdp_metadata_kfunc_id(int id);
617617
bool bpf_dev_bound_kfunc_id(u32 btf_id);
618618
void xdp_set_features_flag(struct net_device *dev, xdp_features_t val);
619+
void xdp_set_features_flag_locked(struct net_device *dev, xdp_features_t val);
619620
void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg);
620621
void xdp_features_clear_redirect_target(struct net_device *dev);
621622
#else

net/core/lock_debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ int netdev_debug_event(struct notifier_block *nb, unsigned long event,
2020
switch (cmd) {
2121
case NETDEV_REGISTER:
2222
case NETDEV_UP:
23+
case NETDEV_XDP_FEAT_CHANGE:
2324
netdev_ops_assert_locked(dev);
2425
fallthrough;
2526
case NETDEV_DOWN:
@@ -58,7 +59,6 @@ int netdev_debug_event(struct notifier_block *nb, unsigned long event,
5859
case NETDEV_OFFLOAD_XSTATS_DISABLE:
5960
case NETDEV_OFFLOAD_XSTATS_REPORT_USED:
6061
case NETDEV_OFFLOAD_XSTATS_REPORT_DELTA:
61-
case NETDEV_XDP_FEAT_CHANGE:
6262
ASSERT_RTNL();
6363
break;
6464

net/core/xdp.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <net/page_pool/helpers.h>
1818

1919
#include <net/hotdata.h>
20+
#include <net/netdev_lock.h>
2021
#include <net/xdp.h>
2122
#include <net/xdp_priv.h> /* struct xdp_mem_allocator */
2223
#include <trace/events/xdp.h>
@@ -991,17 +992,26 @@ static int __init xdp_metadata_init(void)
991992
}
992993
late_initcall(xdp_metadata_init);
993994

994-
void xdp_set_features_flag(struct net_device *dev, xdp_features_t val)
995+
void xdp_set_features_flag_locked(struct net_device *dev, xdp_features_t val)
995996
{
996997
val &= NETDEV_XDP_ACT_MASK;
997998
if (dev->xdp_features == val)
998999
return;
9991000

1001+
netdev_assert_locked_or_invisible(dev);
10001002
dev->xdp_features = val;
10011003

10021004
if (dev->reg_state == NETREG_REGISTERED)
10031005
call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
10041006
}
1007+
EXPORT_SYMBOL_GPL(xdp_set_features_flag_locked);
1008+
1009+
void xdp_set_features_flag(struct net_device *dev, xdp_features_t val)
1010+
{
1011+
netdev_lock(dev);
1012+
xdp_set_features_flag_locked(dev, val);
1013+
netdev_unlock(dev);
1014+
}
10051015
EXPORT_SYMBOL_GPL(xdp_set_features_flag);
10061016

10071017
void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)

0 commit comments

Comments
 (0)