Skip to content

Commit 8c8b90a

Browse files
TaeheeYoogregkh
authored andcommitted
netdevsim: disable devlink reload when resources are being used
commit 6ab6336 upstream. devlink reload destroys resources and allocates resources again. So, when devices and ports resources are being used, devlink reload function should not be executed. In order to avoid this race, a new lock is added and new_port() and del_port() call devlink_reload_disable() and devlink_reload_enable(). Thread0 Thread1 {new/del}_port() {new/del}_port() devlink_reload_disable() devlink_reload_disable() devlink_reload_enable() //here devlink_reload_enable() Before Thread1's devlink_reload_enable(), the devlink is already allowed to execute reload because Thread0 allows it. devlink reload disable/enable variable type is bool. So the above case would exist. So, disable/enable should be executed atomically. In order to do that, a new lock is used. Test commands: modprobe netdevsim echo 1 > /sys/bus/netdevsim/new_device while : do echo 1 > /sys/devices/netdevsim1/new_port & echo 1 > /sys/devices/netdevsim1/del_port & devlink dev reload netdevsim/netdevsim1 & done Splat looks like: [ 23.342145][ T932] DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock)) [ 23.342159][ T932] WARNING: CPU: 0 PID: 932 at kernel/locking/mutex-debug.c:103 mutex_destroy+0xc7/0xf0 [ 23.344182][ T932] Modules linked in: netdevsim openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nf_dx [ 23.346485][ T932] CPU: 0 PID: 932 Comm: devlink Not tainted 5.5.0+ #322 [ 23.347696][ T932] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 23.348893][ T932] RIP: 0010:mutex_destroy+0xc7/0xf0 [ 23.349505][ T932] Code: e0 07 83 c0 03 38 d0 7c 04 84 d2 75 2e 8b 05 00 ac b0 02 85 c0 75 8b 48 c7 c6 00 5e 07 96 40 [ 23.351887][ T932] RSP: 0018:ffff88806208f810 EFLAGS: 00010286 [ 23.353963][ T932] RAX: dffffc0000000008 RBX: ffff888067f6f2c0 RCX: ffffffff942c4bd4 [ 23.355222][ T932] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff96dac5b4 [ 23.356169][ T932] RBP: ffff888067f6f000 R08: fffffbfff2d235a5 R09: fffffbfff2d235a5 [ 23.357160][ T932] R10: 0000000000000001 R11: fffffbfff2d235a4 R12: ffff888067f6f208 [ 23.358288][ T932] R13: ffff88806208fa70 R14: ffff888067f6f000 R15: ffff888069ce3800 [ 23.359307][ T932] FS: 00007fe2a3876740(0000) GS:ffff88806c000000(0000) knlGS:0000000000000000 [ 23.360473][ T932] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 23.361319][ T932] CR2: 00005561357aa000 CR3: 000000005227a006 CR4: 00000000000606f0 [ 23.362323][ T932] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 23.363417][ T932] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 23.364414][ T932] Call Trace: [ 23.364828][ T932] nsim_dev_reload_destroy+0x77/0xb0 [netdevsim] [ 23.365655][ T932] nsim_dev_reload_down+0x84/0xb0 [netdevsim] [ 23.366433][ T932] devlink_reload+0xb1/0x350 [ 23.367010][ T932] genl_rcv_msg+0x580/0xe90 [ ...] [ 23.531729][ T1305] kernel BUG at lib/list_debug.c:53! [ 23.532523][ T1305] invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 23.533467][ T1305] CPU: 2 PID: 1305 Comm: bash Tainted: G W 5.5.0+ #322 [ 23.534962][ T1305] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 23.536503][ T1305] RIP: 0010:__list_del_entry_valid+0xe6/0x150 [ 23.538346][ T1305] Code: 89 ea 48 c7 c7 00 73 1e 96 e8 df f7 4c ff 0f 0b 48 c7 c7 60 73 1e 96 e8 d1 f7 4c ff 0f 0b 44 [ 23.541068][ T1305] RSP: 0018:ffff888047c27b58 EFLAGS: 00010282 [ 23.542001][ T1305] RAX: 0000000000000054 RBX: ffff888067f6f318 RCX: 0000000000000000 [ 23.543051][ T1305] RDX: 0000000000000054 RSI: 0000000000000008 RDI: ffffed1008f84f61 [ 23.544072][ T1305] RBP: ffff88804aa0fca0 R08: ffffed100d940539 R09: ffffed100d940539 [ 23.545085][ T1305] R10: 0000000000000001 R11: ffffed100d940538 R12: ffff888047c27cb0 [ 23.546422][ T1305] R13: ffff88806208b840 R14: ffffffff981976c0 R15: ffff888067f6f2c0 [ 23.547406][ T1305] FS: 00007f76c0431740(0000) GS:ffff88806c800000(0000) knlGS:0000000000000000 [ 23.548527][ T1305] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 23.549389][ T1305] CR2: 00007f5048f1a2f8 CR3: 000000004b310006 CR4: 00000000000606e0 [ 23.550636][ T1305] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 23.551578][ T1305] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 23.552597][ T1305] Call Trace: [ 23.553004][ T1305] mutex_remove_waiter+0x101/0x520 [ 23.553646][ T1305] __mutex_lock+0xac7/0x14b0 [ 23.554218][ T1305] ? nsim_dev_port_del+0x4e/0x140 [netdevsim] [ 23.554908][ T1305] ? mutex_lock_io_nested+0x1380/0x1380 [ 23.555570][ T1305] ? _parse_integer+0xf0/0xf0 [ 23.556043][ T1305] ? kstrtouint+0x86/0x110 [ 23.556504][ T1305] ? nsim_dev_port_del+0x4e/0x140 [netdevsim] [ 23.557133][ T1305] nsim_dev_port_del+0x4e/0x140 [netdevsim] [ 23.558024][ T1305] del_port_store+0xcc/0xf0 [netdevsim] [ ... ] Fixes: 75ba029 ("netdevsim: implement proper devlink reload") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c83d7f2 commit 8c8b90a

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

drivers/net/netdevsim/bus.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ new_port_store(struct device *dev, struct device_attribute *attr,
9797
const char *buf, size_t count)
9898
{
9999
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
100+
struct nsim_dev *nsim_dev = dev_get_drvdata(dev);
101+
struct devlink *devlink;
100102
unsigned int port_index;
101103
int ret;
102104

@@ -106,7 +108,14 @@ new_port_store(struct device *dev, struct device_attribute *attr,
106108
ret = kstrtouint(buf, 0, &port_index);
107109
if (ret)
108110
return ret;
111+
112+
devlink = priv_to_devlink(nsim_dev);
113+
114+
mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
115+
devlink_reload_disable(devlink);
109116
ret = nsim_dev_port_add(nsim_bus_dev, port_index);
117+
devlink_reload_enable(devlink);
118+
mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
110119
return ret ? ret : count;
111120
}
112121

@@ -117,6 +126,8 @@ del_port_store(struct device *dev, struct device_attribute *attr,
117126
const char *buf, size_t count)
118127
{
119128
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
129+
struct nsim_dev *nsim_dev = dev_get_drvdata(dev);
130+
struct devlink *devlink;
120131
unsigned int port_index;
121132
int ret;
122133

@@ -126,7 +137,14 @@ del_port_store(struct device *dev, struct device_attribute *attr,
126137
ret = kstrtouint(buf, 0, &port_index);
127138
if (ret)
128139
return ret;
140+
141+
devlink = priv_to_devlink(nsim_dev);
142+
143+
mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
144+
devlink_reload_disable(devlink);
129145
ret = nsim_dev_port_del(nsim_bus_dev, port_index);
146+
devlink_reload_enable(devlink);
147+
mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
130148
return ret ? ret : count;
131149
}
132150

@@ -311,6 +329,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count)
311329
nsim_bus_dev->dev.type = &nsim_bus_dev_type;
312330
nsim_bus_dev->port_count = port_count;
313331
nsim_bus_dev->initial_net = current->nsproxy->net_ns;
332+
mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
314333
/* Disallow using nsim_bus_dev */
315334
smp_store_release(&nsim_bus_dev->init, false);
316335

drivers/net/netdevsim/netdevsim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ struct nsim_bus_dev {
240240
*/
241241
unsigned int num_vfs;
242242
struct nsim_vf_config *vfconfigs;
243+
/* Lock for devlink->reload_enabled in netdevsim module */
244+
struct mutex nsim_bus_reload_lock;
243245
bool init;
244246
};
245247

0 commit comments

Comments
 (0)