On Tue, 01/06 11:35, Michael S. Tsirkin wrote: > On Tue, Jan 06, 2015 at 03:33:36PM +0800, Fam Zheng wrote: > > There is a race condition in virtscsi_handle_event, when many device > > hotplug/unplug events flush in quickly. > > > > The scsi_remove_device in virtscsi_handle_transport_reset may trigger > > the BUG_ON in scsi_target_reap, because the state is altered behind it, > > probably by scsi_scan_host of another event. I'm able to reproduce it by > > repeatedly plugging and unplugging a scsi disk with the same lun number. > > > > To make is safe, a single thread workqueue local to the module is added > > which runs the scan work. With this change, the panic goes away. > > > > Signed-off-by: Fam Zheng <famz@xxxxxxxxxx> > > --- > > > > v2: Use a single threaded workqueue instead of mutex to serialize work > > (Venkatesh) > > --- > > drivers/scsi/virtio_scsi.c | 14 +++++++++++++- > > 1 file changed, 13 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c > > index c52bb5d..71b0091 100644 > > --- a/drivers/scsi/virtio_scsi.c > > +++ b/drivers/scsi/virtio_scsi.c > > @@ -120,6 +120,8 @@ struct virtio_scsi { > > > > static struct kmem_cache *virtscsi_cmd_cache; > > static mempool_t *virtscsi_cmd_pool; > > +static struct workqueue_struct *virtscsi_scan_wq; > > + > > > > Don't add two empty lines please. > > > static inline struct Scsi_Host *virtio_scsi_host(struct virtio_device *vdev) > > { > > @@ -404,7 +406,7 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf) > > struct virtio_scsi_event_node *event_node = buf; > > > > if (!vscsi->stop_events) > > - queue_work(system_freezable_wq, &event_node->work); > > + queue_work(virtscsi_scan_wq, &event_node->work); > > } > > > > static void virtscsi_event_done(struct virtqueue *vq) > > @@ -1119,6 +1121,12 @@ static int __init init(void) > > pr_err("mempool_create() for virtscsi_cmd_pool failed\n"); > > goto error; > > } > > + virtscsi_scan_wq = create_singlethread_workqueue("virtscsi-scan"); > > + if (!virtscsi_scan_wq) { > > + pr_err("create_singlethread_workqueue() for virtscsi_scan_wq failed\n"); > > + goto error; > > + } > > + > > ret = register_virtio_driver(&virtio_scsi_driver); > > if (ret < 0) > > goto error; > > @@ -1126,6 +1134,9 @@ static int __init init(void) > > return 0; > > > > error: > > + if (virtscsi_scan_wq) { > > + destroy_workqueue(virtscsi_scan_wq); > > + } > > if (virtscsi_cmd_pool) { > > mempool_destroy(virtscsi_cmd_pool); > > virtscsi_cmd_pool = NULL; > > @@ -1142,6 +1153,7 @@ static void __exit fini(void) > > unregister_virtio_driver(&virtio_scsi_driver); > > mempool_destroy(virtscsi_cmd_pool); > > kmem_cache_destroy(virtscsi_cmd_cache); > > + destroy_workqueue(virtscsi_scan_wq); > > > Please destroy in reverse order of initialization: > between unregister_virtio_driver and mempool_destroy. OK, will fix this. Thanks. Fam > > > } > > module_init(init); > > module_exit(fini); > > -- > > 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html