Skip to content

Commit eeeec1d

Browse files
committed
net: make netdev netlink ops hold netdev_lock()
In prep for dropping rtnl_lock, start locking netdev->lock in netlink genl ops. We need to be using netdev->up instead of flags & IFF_UP. We can remove the RCU lock protection for the NAPI since NAPI list is protected by netdev->lock already. Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250115035319.559603-8-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 413f027 commit eeeec1d

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

net/core/dev.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,8 @@ static struct napi_struct *napi_by_id(unsigned int napi_id)
768768
}
769769

770770
/* must be called under rcu_read_lock(), as we dont take a reference */
771-
struct napi_struct *netdev_napi_by_id(struct net *net, unsigned int napi_id)
771+
static struct napi_struct *
772+
netdev_napi_by_id(struct net *net, unsigned int napi_id)
772773
{
773774
struct napi_struct *napi;
774775

net/core/dev.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ struct sd_flow_limit {
2323

2424
extern int netdev_flow_limit_table_len;
2525

26-
struct napi_struct *netdev_napi_by_id(struct net *net, unsigned int napi_id);
2726
struct napi_struct *
2827
netdev_napi_by_id_lock(struct net *net, unsigned int napi_id);
2928
struct net_device *dev_get_by_napi_id(unsigned int napi_id);

net/core/netdev-genl.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
167167
void *hdr;
168168
pid_t pid;
169169

170-
if (!(napi->dev->flags & IFF_UP))
170+
if (!napi->dev->up)
171171
return 0;
172172

173173
hdr = genlmsg_iput(rsp, info);
@@ -230,17 +230,16 @@ int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
230230
return -ENOMEM;
231231

232232
rtnl_lock();
233-
rcu_read_lock();
234233

235-
napi = netdev_napi_by_id(genl_info_net(info), napi_id);
234+
napi = netdev_napi_by_id_lock(genl_info_net(info), napi_id);
236235
if (napi) {
237236
err = netdev_nl_napi_fill_one(rsp, napi, info);
237+
netdev_unlock(napi->dev);
238238
} else {
239239
NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
240240
err = -ENOENT;
241241
}
242242

243-
rcu_read_unlock();
244243
rtnl_unlock();
245244

246245
if (err) {
@@ -266,7 +265,7 @@ netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
266265
unsigned int prev_id;
267266
int err = 0;
268267

269-
if (!(netdev->flags & IFF_UP))
268+
if (!netdev->up)
270269
return err;
271270

272271
prev_id = UINT_MAX;
@@ -303,13 +302,15 @@ int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
303302

304303
rtnl_lock();
305304
if (ifindex) {
306-
netdev = __dev_get_by_index(net, ifindex);
307-
if (netdev)
305+
netdev = netdev_get_by_index_lock(net, ifindex);
306+
if (netdev) {
308307
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
309-
else
308+
netdev_unlock(netdev);
309+
} else {
310310
err = -ENODEV;
311+
}
311312
} else {
312-
for_each_netdev_dump(net, netdev, ctx->ifindex) {
313+
for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
313314
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
314315
if (err < 0)
315316
break;
@@ -358,17 +359,16 @@ int netdev_nl_napi_set_doit(struct sk_buff *skb, struct genl_info *info)
358359
napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
359360

360361
rtnl_lock();
361-
rcu_read_lock();
362362

363-
napi = netdev_napi_by_id(genl_info_net(info), napi_id);
363+
napi = netdev_napi_by_id_lock(genl_info_net(info), napi_id);
364364
if (napi) {
365365
err = netdev_nl_napi_set_config(napi, info);
366+
netdev_unlock(napi->dev);
366367
} else {
367368
NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
368369
err = -ENOENT;
369370
}
370371

371-
rcu_read_unlock();
372372
rtnl_unlock();
373373

374374
return err;
@@ -442,7 +442,7 @@ netdev_nl_queue_fill(struct sk_buff *rsp, struct net_device *netdev, u32 q_idx,
442442
{
443443
int err;
444444

445-
if (!(netdev->flags & IFF_UP))
445+
if (!netdev->up)
446446
return -ENOENT;
447447

448448
err = netdev_nl_queue_validate(netdev, q_idx, q_type);
@@ -474,11 +474,13 @@ int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
474474

475475
rtnl_lock();
476476

477-
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
478-
if (netdev)
477+
netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
478+
if (netdev) {
479479
err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
480-
else
480+
netdev_unlock(netdev);
481+
} else {
481482
err = -ENODEV;
483+
}
482484

483485
rtnl_unlock();
484486

@@ -499,7 +501,7 @@ netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
499501
{
500502
int err = 0;
501503

502-
if (!(netdev->flags & IFF_UP))
504+
if (!netdev->up)
503505
return err;
504506

505507
for (; ctx->rxq_idx < netdev->real_num_rx_queues; ctx->rxq_idx++) {
@@ -532,13 +534,15 @@ int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
532534

533535
rtnl_lock();
534536
if (ifindex) {
535-
netdev = __dev_get_by_index(net, ifindex);
536-
if (netdev)
537+
netdev = netdev_get_by_index_lock(net, ifindex);
538+
if (netdev) {
537539
err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
538-
else
540+
netdev_unlock(netdev);
541+
} else {
539542
err = -ENODEV;
543+
}
540544
} else {
541-
for_each_netdev_dump(net, netdev, ctx->ifindex) {
545+
for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
542546
err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
543547
if (err < 0)
544548
break;

0 commit comments

Comments
 (0)