diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-07 08:04:56 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-07 08:04:56 -0400 |
| commit | dc92b1f9ab1e1665dbbc56911782358e7f9a49f9 (patch) | |
| tree | 965ccb4a0f2c24a8b24adce415f6506246d07a90 | |
| parent | 5e090ed7af10729a396a25df43d69a236e789736 (diff) | |
| parent | ca16f580a5db7e60bfafe59a50bb133bd3347491 (diff) | |
Merge branch 'virtio-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio changes from Rusty Russell:
"New workflow: same git trees pulled by linux-next get sent straight to
Linus. Git is awkward at shuffling patches compared with quilt or mq,
but that doesn't happen often once things get into my -next branch."
* 'virtio-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (24 commits)
lguest: fix occasional crash in example launcher.
virtio-blk: Disable callback in virtblk_done()
virtio_mmio: Don't attempt to create empty virtqueues
virtio_mmio: fix off by one error allocating queue
drivers/virtio/virtio_pci.c: fix error return code
virtio: don't crash when device is buggy
virtio: remove CONFIG_VIRTIO_RING
virtio: add help to CONFIG_VIRTIO option.
virtio: support reserved vqs
virtio: introduce an API to set affinity for a virtqueue
virtio-ring: move queue_index to vring_virtqueue
virtio_balloon: not EXPERIMENTAL any more.
virtio-balloon: dependency fix
virtio-blk: fix NULL checking in virtblk_alloc_req()
virtio-blk: Add REQ_FLUSH and REQ_FUA support to bio path
virtio-blk: Add bio-based IO path for virtio-blk
virtio: console: fix error handling in init() function
tools: Fix pthread flag for Makefile of trace-agent used by virtio-trace
tools: Add guest trace agent as a user tool
virtio/console: Allocate scatterlist according to the current pipe size
...
25 files changed, 1391 insertions, 106 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index f9acddd9ace3..c8af429991d9 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -656,7 +656,6 @@ config S390_GUEST | |||
| 656 | depends on 64BIT && EXPERIMENTAL | 656 | depends on 64BIT && EXPERIMENTAL |
| 657 | select VIRTUALIZATION | 657 | select VIRTUALIZATION |
| 658 | select VIRTIO | 658 | select VIRTIO |
| 659 | select VIRTIO_RING | ||
| 660 | select VIRTIO_CONSOLE | 659 | select VIRTIO_CONSOLE |
| 661 | help | 660 | help |
| 662 | Enabling this option adds support for virtio based paravirtual device | 661 | Enabling this option adds support for virtio based paravirtual device |
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 6e121a2a49e1..7872a3330fb5 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig | |||
| @@ -4,7 +4,6 @@ config LGUEST_GUEST | |||
| 4 | depends on X86_32 | 4 | depends on X86_32 |
| 5 | select VIRTUALIZATION | 5 | select VIRTUALIZATION |
| 6 | select VIRTIO | 6 | select VIRTIO |
| 7 | select VIRTIO_RING | ||
| 8 | select VIRTIO_CONSOLE | 7 | select VIRTIO_CONSOLE |
| 9 | help | 8 | help |
| 10 | Lguest is a tiny in-kernel hypervisor. Selecting this will | 9 | Lguest is a tiny in-kernel hypervisor. Selecting this will |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c0bbeb470754..0bdde8fba397 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | 14 | ||
| 15 | #define PART_BITS 4 | 15 | #define PART_BITS 4 |
| 16 | 16 | ||
| 17 | static bool use_bio; | ||
| 18 | module_param(use_bio, bool, S_IRUGO); | ||
| 19 | |||
| 17 | static int major; | 20 | static int major; |
| 18 | static DEFINE_IDA(vd_index_ida); | 21 | static DEFINE_IDA(vd_index_ida); |
| 19 | 22 | ||
| @@ -23,6 +26,7 @@ struct virtio_blk | |||
| 23 | { | 26 | { |
| 24 | struct virtio_device *vdev; | 27 | struct virtio_device *vdev; |
| 25 | struct virtqueue *vq; | 28 | struct virtqueue *vq; |
| 29 | wait_queue_head_t queue_wait; | ||
| 26 | 30 | ||
| 27 | /* The disk structure for the kernel. */ | 31 | /* The disk structure for the kernel. */ |
| 28 | struct gendisk *disk; | 32 | struct gendisk *disk; |
| @@ -51,53 +55,244 @@ struct virtio_blk | |||
| 51 | struct virtblk_req | 55 | struct virtblk_req |
| 52 | { | 56 | { |
| 53 | struct request *req; | 57 | struct request *req; |
| 58 | struct bio *bio; | ||
| 54 | struct virtio_blk_outhdr out_hdr; | 59 | struct virtio_blk_outhdr out_hdr; |
| 55 | struct virtio_scsi_inhdr in_hdr; | 60 | struct virtio_scsi_inhdr in_hdr; |
| 61 | struct work_struct work; | ||
| 62 | struct virtio_blk *vblk; | ||
| 63 | int flags; | ||
| 56 | u8 status; | 64 | u8 status; |
| 65 | struct scatterlist sg[]; | ||
| 66 | }; | ||
| 67 | |||
| 68 | enum { | ||
| 69 | VBLK_IS_FLUSH = 1, | ||
| 70 | VBLK_REQ_FLUSH = 2, | ||
| 71 | VBLK_REQ_DATA = 4, | ||
| 72 | VBLK_REQ_FUA = 8, | ||
| 57 | }; | 73 | }; |
| 58 | 74 | ||
| 59 | static void blk_done(struct virtqueue *vq) | 75 | static inline int virtblk_result(struct virtblk_req *vbr) |
| 76 | { | ||
| 77 | switch (vbr->status) { | ||
| 78 | case VIRTIO_BLK_S_OK: | ||
| 79 | return 0; | ||
| 80 | case VIRTIO_BLK_S_UNSUPP: | ||
| 81 | return -ENOTTY; | ||
| 82 | default: | ||
| 83 | return -EIO; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk, | ||
| 88 | gfp_t gfp_mask) | ||
| 60 | { | 89 | { |
| 61 | struct virtio_blk *vblk = vq->vdev->priv; | ||
| 62 | struct virtblk_req *vbr; | 90 | struct virtblk_req *vbr; |
| 63 | unsigned int len; | ||
| 64 | unsigned long flags; | ||
| 65 | 91 | ||
| 66 | spin_lock_irqsave(vblk->disk->queue->queue_lock, flags); | 92 | vbr = mempool_alloc(vblk->pool, gfp_mask); |
| 67 | while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { | 93 | if (!vbr) |
| 68 | int error; | 94 | return NULL; |
| 69 | 95 | ||
| 70 | switch (vbr->status) { | 96 | vbr->vblk = vblk; |
| 71 | case VIRTIO_BLK_S_OK: | 97 | if (use_bio) |
| 72 | error = 0; | 98 | sg_init_table(vbr->sg, vblk->sg_elems); |
| 73 | break; | 99 | |
| 74 | case VIRTIO_BLK_S_UNSUPP: | 100 | return vbr; |
| 75 | error = -ENOTTY; | 101 | } |
| 76 | break; | 102 | |
| 77 | default: | 103 | static void virtblk_add_buf_wait(struct virtio_blk *vblk, |
| 78 | error = -EIO; | 104 | struct virtblk_req *vbr, |
| 105 | unsigned long out, | ||
| 106 | unsigned long in) | ||
| 107 | { | ||
| 108 | DEFINE_WAIT(wait); | ||
| 109 | |||
| 110 | for (;;) { | ||
| 111 | prepare_to_wait_exclusive(&vblk->queue_wait, &wait, | ||
| 112 | TASK_UNINTERRUPTIBLE); | ||
| 113 | |||
| 114 | spin_lock_irq(vblk->disk->queue->queue_lock); | ||
| 115 | if (virtqueue_add_buf(vblk->vq, vbr->sg, out, in, vbr, | ||
| 116 | GFP_ATOMIC) < 0) { | ||
| 117 | spin_unlock_irq(vblk->disk->queue->queue_lock); | ||
| 118 | io_schedule(); | ||
| 119 | } else { | ||
| 120 | virtqueue_kick(vblk->vq); | ||
| 121 | spin_unlock_irq(vblk->disk->queue->queue_lock); | ||
| 79 | break; | 122 | break; |
| 80 | } | 123 | } |
| 81 | 124 | ||
| 82 | switch (vbr->req->cmd_type) { | 125 | } |
| 83 | case REQ_TYPE_BLOCK_PC: | 126 | |
| 84 | vbr->req->resid_len = vbr->in_hdr.residual; | 127 | finish_wait(&vblk->queue_wait, &wait); |
| 85 | vbr->req->sense_len = vbr->in_hdr.sense_len; | 128 | } |
| 86 | vbr->req->errors = vbr->in_hdr.errors; | 129 | |
| 87 | break; | 130 | static inline void virtblk_add_req(struct virtblk_req *vbr, |
| 88 | case REQ_TYPE_SPECIAL: | 131 | unsigned int out, unsigned int in) |
| 89 | vbr->req->errors = (error != 0); | 132 | { |
| 90 | break; | ||
