diff options
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r-- | drivers/block/virtio_blk.c | 40 |
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); |
377 | done: | ||
378 | mutex_unlock(&vblk->config_lock); | ||
379 | } | 367 | } |
380 | 368 | ||
381 | static void virtblk_config_changed(struct virtio_device *vdev) | 369 | static 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 | ||