Skip to content

Commit 6da7a0f

Browse files
committed
Merge branch 'dev-covnert-dev_change_name-to-per-netns-rtnl'
Kuniyuki Iwashima says: ==================== dev: Covnert dev_change_name() to per-netns RTNL. Patch 1 adds a missing netdev_rename_lock in dev_change_name() and Patch 2 removes unnecessary devnet_rename_sem there. Patch 3 replaces RTNL with rtnl_net_lock() in dev_ifsioc(), and now dev_change_name() is always called under per-netns RTNL. Given it's close to -rc8 and Patch 1 touches the trivial unlikely path, can Patch 1 go into net-next ? Otherwise I'll post Patch 2 & 3 separately in the next cycle. ==================== Link: https://patch.msgid.link/20250115095545.52709-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 8d20dcd + be94cfd commit 6da7a0f

File tree

3 files changed

+26
-40
lines changed

3 files changed

+26
-40
lines changed

net/core/dev.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ static DEFINE_SPINLOCK(napi_hash_lock);
181181
static unsigned int napi_gen_id = NR_CPUS;
182182
static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8);
183183

184-
static DECLARE_RWSEM(devnet_rename_sem);
185-
186184
static inline void dev_base_seq_inc(struct net *net)
187185
{
188186
unsigned int val = net->dev_base_seq + 1;
@@ -1350,34 +1348,25 @@ static int dev_get_valid_name(struct net *net, struct net_device *dev,
13501348
*/
13511349
int dev_change_name(struct net_device *dev, const char *newname)
13521350
{
1351+
struct net *net = dev_net(dev);
13531352
unsigned char old_assign_type;
13541353
char oldname[IFNAMSIZ];
13551354
int err = 0;
13561355
int ret;
1357-
struct net *net;
1358-
1359-
ASSERT_RTNL();
1360-
BUG_ON(!dev_net(dev));
1361-
1362-
net = dev_net(dev);
13631356

1364-
down_write(&devnet_rename_sem);
1357+
ASSERT_RTNL_NET(net);
13651358

1366-
if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
1367-
up_write(&devnet_rename_sem);
1359+
if (!strncmp(newname, dev->name, IFNAMSIZ))
13681360
return 0;
1369-
}
13701361

13711362
memcpy(oldname, dev->name, IFNAMSIZ);
13721363

13731364
write_seqlock_bh(&netdev_rename_lock);
13741365
err = dev_get_valid_name(net, dev, newname);
13751366
write_sequnlock_bh(&netdev_rename_lock);
13761367

1377-
if (err < 0) {
1378-
up_write(&devnet_rename_sem);
1368+
if (err < 0)
13791369
return err;
1380-
}
13811370

13821371
if (oldname[0] && !strchr(oldname, '%'))
13831372
netdev_info(dev, "renamed from %s%s\n", oldname,
@@ -1389,14 +1378,13 @@ int dev_change_name(struct net_device *dev, const char *newname)
13891378
rollback:
13901379
ret = device_rename(&dev->dev, dev->name);
13911380
if (ret) {
1381+
write_seqlock_bh(&netdev_rename_lock);
13921382
memcpy(dev->name, oldname, IFNAMSIZ);
1383+
write_sequnlock_bh(&netdev_rename_lock);
13931384
WRITE_ONCE(dev->name_assign_type, old_assign_type);
1394-
up_write(&devnet_rename_sem);
13951385
return ret;
13961386
}
13971387

1398-
up_write(&devnet_rename_sem);
1399-
14001388
netdev_adjacent_rename_links(dev, oldname);
14011389

14021390
netdev_name_node_del(dev->name_node);
@@ -1412,7 +1400,6 @@ int dev_change_name(struct net_device *dev, const char *newname)
14121400
/* err >= 0 after dev_alloc_name() or stores the first errno */
14131401
if (err >= 0) {
14141402
err = ret;
1415-
down_write(&devnet_rename_sem);
14161403
write_seqlock_bh(&netdev_rename_lock);
14171404
memcpy(dev->name, oldname, IFNAMSIZ);
14181405
write_sequnlock_bh(&netdev_rename_lock);

net/core/dev_ioctl.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ static int dev_siocwandev(struct net_device *dev, struct if_settings *ifs)
543543
}
544544

545545
/*
546-
* Perform the SIOCxIFxxx calls, inside rtnl_lock()
546+
* Perform the SIOCxIFxxx calls, inside rtnl_net_lock()
547547
*/
548548
static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
549549
unsigned int cmd)
@@ -620,11 +620,14 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
620620
return -ENODEV;
621621
if (!netif_is_bridge_master(dev))
622622
return -EOPNOTSUPP;
623+
623624
netdev_hold(dev, &dev_tracker, GFP_KERNEL);
624-
rtnl_unlock();
625+
rtnl_net_unlock(net);
626+
625627
err = br_ioctl_call(net, netdev_priv(dev), cmd, ifr, NULL);
628+
626629
netdev_put(dev, &dev_tracker);
627-
rtnl_lock();
630+
rtnl_net_lock(net);
628631
return err;
629632

630633
case SIOCDEVPRIVATE ... SIOCDEVPRIVATE + 15:
@@ -770,9 +773,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
770773
dev_load(net, ifr->ifr_name);
771774
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
772775
return -EPERM;
773-
rtnl_lock();
776+
777+
rtnl_net_lock(net);
774778
ret = dev_ifsioc(net, ifr, data, cmd);
775-
rtnl_unlock();
779+
rtnl_net_unlock(net);
780+
776781
if (colon)
777782
*colon = ':';
778783
return ret;
@@ -816,9 +821,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
816821
case SIOCBONDSLAVEINFOQUERY:
817822
case SIOCBONDINFOQUERY:
818823
dev_load(net, ifr->ifr_name);
819-
rtnl_lock();
824+
825+
rtnl_net_lock(net);
820826
ret = dev_ifsioc(net, ifr, data, cmd);
821-
rtnl_unlock();
827+
rtnl_net_unlock(net);
828+
822829
if (need_copyout)
823830
*need_copyout = false;
824831
return ret;
@@ -841,9 +848,10 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
841848
(cmd >= SIOCDEVPRIVATE &&
842849
cmd <= SIOCDEVPRIVATE + 15)) {
843850
dev_load(net, ifr->ifr_name);
844-
rtnl_lock();
851+
852+
rtnl_net_lock(net);
845853
ret = dev_ifsioc(net, ifr, data, cmd);
846-
rtnl_unlock();
854+
rtnl_net_unlock(net);
847855
return ret;
848856
}
849857
return -ENOTTY;

net/core/rtnl_net_debug.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ static int rtnl_net_debug_event(struct notifier_block *nb,
2727
case NETDEV_CHANGEADDR:
2828
case NETDEV_PRE_CHANGEADDR:
2929
case NETDEV_GOING_DOWN:
30-
case NETDEV_CHANGENAME:
3130
case NETDEV_FEAT_CHANGE:
3231
case NETDEV_BONDING_FAILOVER:
3332
case NETDEV_PRE_UP:
@@ -60,18 +59,10 @@ static int rtnl_net_debug_event(struct notifier_block *nb,
6059
ASSERT_RTNL();
6160
break;
6261

63-
/* Once an event fully supports RTNL_NET, move it here
64-
* and remove "if (0)" below.
65-
*
66-
* case NETDEV_XXX:
67-
* ASSERT_RTNL_NET(net);
68-
* break;
69-
*/
70-
}
71-
72-
/* Just to avoid unused-variable error for dev and net. */
73-
if (0)
62+
case NETDEV_CHANGENAME:
7463
ASSERT_RTNL_NET(net);
64+
break;
65+
}
7566

7667
return NOTIFY_DONE;
7768
}

0 commit comments

Comments
 (0)