aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/virtio_blk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r--drivers/block/virtio_blk.c40
1 files changed, 11 insertions, 29 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 0a581400de0f..930fee886917 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -41,12 +41,6 @@ struct virtio_blk
41 /* Process context for config space updates */ 41 /* Process context for config space updates */
42 struct work_struct config_work; 42 struct work_struct config_work;
43 43
44 /* Lock for config space updates */
45 struct mutex config_lock;
46
47 /* enable config space updates */
48 bool config_enable;
49
50 /* What host tells us, plus 2 for header & tailer. */ 44 /* What host tells us, plus 2 for header & tailer. */
51 unsigned int sg_elems; 45 unsigned int sg_elems;
52 46
@@ -347,10 +341,6 @@ static void virtblk_config_changed_work(struct work_struct *work)
347 char *envp[] = { "RESIZE=1", NULL }; 341 char *envp[] = { "RESIZE=1", NULL };
348 u64 capacity, size; 342 u64 capacity, size;
349 343
350 mutex_lock(&vblk->config_lock);
351 if (!vblk->config_enable)
352 goto done;
353
354 /* Host must always specify the capacity. */ 344 /* Host must always specify the capacity. */
355 virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity); 345 virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity);
356 346
@@ -374,8 +364,6 @@ static void virtblk_config_changed_work(struct work_struct *work)
374 set_capacity(vblk->disk, capacity); 364 set_capacity(vblk->disk, capacity);
375 revalidate_disk(vblk->disk); 365 revalidate_disk(vblk->disk);
376 kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp); 366 kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
377done:
378 mutex_unlock(&vblk->config_lock);
379} 367}
380 368
381static void virtblk_config_changed(struct virtio_device *vdev) 369static void virtblk_config_changed(struct virtio_device *vdev)
@@ -606,10 +594,8 @@ static int virtblk_probe(struct virtio_device *vdev)
606 594
607 vblk->vdev = vdev; 595 vblk->vdev = vdev;
608 vblk->sg_elems = sg_elems; 596 vblk->sg_elems = sg_elems;
609 mutex_init(&vblk->config_lock);
610 597
611 INIT_WORK(&vblk->config_work, virtblk_config_changed_work); 598 INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
612 vblk->config_enable = true;
613 599
614 err = init_vq(vblk); 600 err = init_vq(vblk);
615 if (err) 601 if (err)
@@ -733,6 +719,8 @@ static int virtblk_probe(struct virtio_device *vdev)
733 if (!err && opt_io_size) 719 if (!err && opt_io_size)
734 blk_queue_io_opt(q, blk_size * opt_io_size); 720 blk_queue_io_opt(q, blk_size * opt_io_size);
735 721
722 virtio_device_ready(vdev);
723
736 add_disk(vblk->disk); 724 add_disk(vblk->disk);
737 err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); 725 err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
738 if (err) 726 if (err)
@@ -771,10 +759,8 @@ static void virtblk_remove(struct virtio_device *vdev)
771 int index = vblk->index; 759 int index = vblk->index;
772 int refc; 760 int refc;
773 761
774 /* Prevent config work handler from accessing the device. */ 762 /* Make sure no work handler is accessing the device. */
775 mutex_lock(&vblk->config_lock); 763 flush_work(&vblk->config_work);
776 vblk->config_enable = false;
777 mutex_unlock(&vblk->config_lock);
778 764
779 del_gendisk(vblk->disk); 765 del_gendisk(vblk->disk);
780 blk_cleanup_queue(vblk->disk->queue); 766 blk_cleanup_queue(vblk->disk->queue);
@@ -784,8 +770,6 @@ static void virtblk_remove(struct virtio_device *vdev)
784 /* Stop all the virtqueues. */ 770 /* Stop all the virtqueues. */
785 vdev->config->reset(vdev); 771 vdev->config->reset(vdev);
786 772
787 flush_work(&vblk->config_work);
788
789 refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount); 773 refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount);
790 put_disk(vblk->disk); 774 put_disk(vblk->disk);
791 vdev->config->del_vqs(vdev); 775 vdev->config->del_vqs(vdev);
@@ -805,11 +789,7 @@ static int virtblk_freeze(struct virtio_device *vdev)
805 /* Ensure we don't receive any more interrupts */ 789 /* Ensure we don't receive any more interrupts */
806 vdev->config->reset(vdev); 790 vdev->config->reset(vdev);
807 791
808 /* Prevent config work handler from accessing the device. */ 792 /* Make sure no work handler is accessing the device. */
809 mutex_lock(&vblk->config_lock);
810 vblk->config_enable = false;
811 mutex_unlock(&vblk->config_lock);
812
813 flush_work(&vblk->config_work); 793 flush_work(&vblk->config_work);
814 794
815 blk_mq_stop_hw_queues(vblk->disk->queue); 795 blk_mq_stop_hw_queues(vblk->disk->queue);
@@ -823,12 +803,14 @@ static int virtblk_restore(struct virtio_device *vdev)
823 struct virtio_blk *vblk = vdev->priv; 803 struct virtio_blk *vblk = vdev->priv;
824 int ret; 804 int ret;
825 805
826 vblk->config_enable = true;
827 ret = init_vq(vdev->priv); 806 ret = init_vq(vdev->priv);
828 if (!ret) 807 if (ret)
829 blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); 808 return ret;
830 809
831 return ret; 810 virtio_device_ready(vdev);
811
812 blk_mq_start_stopped_hw_queues(vblk->disk->queue, true);
813 return 0;
832} 814}
833#endif 815#endif
834 816