On Monday, November 28, 2022 3:10:02 AM CET Li Zetao wrote: > When doing the following test steps, an error was found: > step 1: modprobe 9pnet_virtio succeeded > # modprobe 9pnet_virtio <-- OK > > step 2: fault injection in sysfs_create_file() > # modprobe -r 9pnet_virtio <-- OK > # ... > FAULT_INJECTION: forcing a failure. > name failslab, interval 1, probability 0, space 0, times 0 > CPU: 0 PID: 3790 Comm: modprobe Tainted: G W > 6.1.0-rc6-00285-g6a1e40c4b995-dirty #108 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) > Call Trace: > <TASK> > ... > should_failslab+0xa/0x20 > ... > sysfs_create_file_ns+0x130/0x1d0 > p9_virtio_probe+0x662/0xb30 [9pnet_virtio] > virtio_dev_probe+0x608/0xae0 > ... > </TASK> > 9pnet_virtio: probe of virtio3 failed with error -12 > > step 3: modprobe virtio_net failed > # modprobe 9pnet_virtio <-- failed > 9pnet_virtio: probe of virtio3 failed with error -2 > > The root cause of the problem is that the virtqueues are not > stopped on the error handling path when sysfs_create_file() > fails in p9_virtio_probe(), resulting in an error "-ENOENT" > returned in the next modprobe call in setup_vq(). > > virtio_pci_modern_device uses virtqueues to send or > receive message, and "queue_enable" records whether the > queues are available. In vp_modern_find_vqs(), all queues > will be selected and activated, but once queues are enabled > there is no way to go back except reset. > > Fix it by reset virtio device on error handling path. After > virtio_find_single_vq() succeeded, all virtqueues should be > stopped on error handling path. > > Fixes: 1fcf0512c9c8 ("virtio_pci: modern driver") > Signed-off-by: Li Zetao <lizetao1@xxxxxxxxxx> > --- As others said, comment should probably be adjusted, apart from that: Reviewed-by: Christian Schoenebeck <linux_oss@xxxxxxxxxxxxx> > net/9p/trans_virtio.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c > index e757f0601304..39933187284b 100644 > --- a/net/9p/trans_virtio.c > +++ b/net/9p/trans_virtio.c > @@ -668,6 +668,7 @@ static int p9_virtio_probe(struct virtio_device *vdev) > out_free_tag: > kfree(tag); > out_free_vq: > + virtio_reset_device(vdev); > vdev->config->del_vqs(vdev); > out_free_chan: > kfree(chan); >