diff options
-rw-r--r-- | drivers/virtio/virtio_mmio.c | 4 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci.c | 6 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 34 | ||||
-rw-r--r-- | include/linux/virtio.h | 14 |
4 files changed, 28 insertions, 30 deletions
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 6b1b7e184939..5a0e1d32ce13 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -225,7 +225,7 @@ static void vm_notify(struct virtqueue *vq) | |||
225 | 225 | ||
226 | /* We write the queue's selector into the notification register to | 226 | /* We write the queue's selector into the notification register to |
227 | * signal the other end */ | 227 | * signal the other end */ |
228 | writel(virtqueue_get_queue_index(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); | 228 | writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); |
229 | } | 229 | } |
230 | 230 | ||
231 | /* Notify all virtqueues on an interrupt. */ | 231 | /* Notify all virtqueues on an interrupt. */ |
@@ -266,7 +266,7 @@ static void vm_del_vq(struct virtqueue *vq) | |||
266 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); | 266 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); |
267 | struct virtio_mmio_vq_info *info = vq->priv; | 267 | struct virtio_mmio_vq_info *info = vq->priv; |
268 | unsigned long flags, size; | 268 | unsigned long flags, size; |
269 | unsigned int index = virtqueue_get_queue_index(vq); | 269 | unsigned int index = vq->index; |
270 | 270 | ||
271 | spin_lock_irqsave(&vm_dev->lock, flags); | 271 | spin_lock_irqsave(&vm_dev->lock, flags); |
272 | list_del(&info->node); | 272 | list_del(&info->node); |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index b59237c1d540..e3ecc94591ad 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -203,8 +203,7 @@ static void vp_notify(struct virtqueue *vq) | |||
203 | 203 | ||
204 | /* we write the queue's selector into the notification register to | 204 | /* we write the queue's selector into the notification register to |
205 | * signal the other end */ | 205 | * signal the other end */ |
206 | iowrite16(virtqueue_get_queue_index(vq), | 206 | iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); |
207 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); | ||
208 | } | 207 | } |
209 | 208 | ||
210 | /* Handle a configuration change: Tell driver if it wants to know. */ | 209 | /* Handle a configuration change: Tell driver if it wants to know. */ |
@@ -479,8 +478,7 @@ static void vp_del_vq(struct virtqueue *vq) | |||
479 | list_del(&info->node); | 478 | list_del(&info->node); |
480 | spin_unlock_irqrestore(&vp_dev->lock, flags); | 479 | spin_unlock_irqrestore(&vp_dev->lock, flags); |
481 | 480 | ||
482 | iowrite16(virtqueue_get_queue_index(vq), | 481 | iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); |
483 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | ||
484 | 482 | ||
485 | if (vp_dev->msix_enabled) { | 483 | if (vp_dev->msix_enabled) { |
486 | iowrite16(VIRTIO_MSI_NO_VECTOR, | 484 | iowrite16(VIRTIO_MSI_NO_VECTOR, |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 286c30cb393d..33a4ce009bcc 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -93,8 +93,6 @@ struct vring_virtqueue | |||
93 | /* Host publishes avail event idx */ | 93 | /* Host publishes avail event idx */ |
94 | bool event; | 94 | bool event; |
95 | 95 | ||
96 | /* Number of free buffers */ | ||
97 | unsigned int num_free; | ||
98 | /* Head of free buffer list. */ | 96 | /* Head of free buffer list. */ |
99 | unsigned int free_head; | 97 | unsigned int free_head; |
100 | /* Number we've added since last sync. */ | 98 | /* Number we've added since last sync. */ |
@@ -106,9 +104,6 @@ struct vring_virtqueue | |||
106 | /* How to notify other side. FIXME: commonalize hcalls! */ | 104 | /* How to notify other side. FIXME: commonalize hcalls! */ |
107 | void (*notify)(struct virtqueue *vq); | 105 | void (*notify)(struct virtqueue *vq); |
108 | 106 | ||
109 | /* Index of the queue */ | ||
110 | int queue_index; | ||
111 | |||
112 | #ifdef DEBUG | 107 | #ifdef DEBUG |
113 | /* They're supposed to lock for us. */ | 108 | /* They're supposed to lock for us. */ |
114 | unsigned int in_use; | 109 | unsigned int in_use; |
@@ -167,7 +162,7 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
167 | desc[i-1].next = 0; | 162 | desc[i-1].next = 0; |
168 | 163 | ||
169 | /* We're about to use a buffer */ | 164 | /* We're about to use a buffer */ |
170 | vq->num_free--; | 165 | vq->vq.num_free--; |
171 | 166 | ||
172 | /* Use a single buffer which doesn't continue */ | 167 | /* Use a single buffer which doesn't continue */ |
173 | head = vq->free_head; | 168 | head = vq->free_head; |
@@ -181,13 +176,6 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
181 | return head; | 176 | return head; |
182 | } | 177 | } |
183 | 178 | ||
184 | int virtqueue_get_queue_index(struct virtqueue *_vq) | ||
185 | { | ||
186 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
187 | return vq->queue_index; | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(virtqueue_get_queue_index); | ||
190 | |||
191 | /** | 179 | /** |
192 | * virtqueue_add_buf - expose buffer to other end | 180 | * virtqueue_add_buf - expose buffer to other end |
193 | * @vq: the struct virtqueue we're talking about. | 181 | * @vq: the struct virtqueue we're talking about. |
@@ -235,7 +223,7 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
235 | 223 | ||
236 | /* If the host supports indirect descriptor tables, and we have multiple | 224 | /* If the host supports indirect descriptor tables, and we have multiple |
237 | * buffers, then go indirect. FIXME: tune this threshold */ | 225 | * buffers, then go indirect. FIXME: tune this threshold */ |
238 | if (vq->indirect && (out + in) > 1 && vq->num_free) { | 226 | if (vq->indirect && (out + in) > 1 && vq->vq.num_free) { |
239 | head = vring_add_indirect(vq, sg, out, in, gfp); | 227 | head = vring_add_indirect(vq, sg, out, in, gfp); |
240 | if (likely(head >= 0)) | 228 | if (likely(head >= 0)) |
241 | goto add_head; | 229 | goto add_head; |
@@ -244,9 +232,9 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
244 | BUG_ON(out + in > vq->vring.num); | 232 | BUG_ON(out + in > vq->vring.num); |
245 | BUG_ON(out + in == 0); | 233 | BUG_ON(out + in == 0); |
246 | 234 | ||
247 | if (vq->num_free < out + in) { | 235 | if (vq->vq.num_free < out + in) { |
248 | pr_debug("Can't add buf len %i - avail = %i\n", | 236 | pr_debug("Can't add buf len %i - avail = %i\n", |
249 | out + in, vq->num_free); | 237 | out + in, vq->vq.num_free); |
250 | /* FIXME: for historical reasons, we force a notify here if | 238 | /* FIXME: for historical reasons, we force a notify here if |
251 | * there are outgoing parts to the buffer. Presumably the | 239 | * there are outgoing parts to the buffer. Presumably the |
252 | * host should service the ring ASAP. */ | 240 | * host should service the ring ASAP. */ |
@@ -257,7 +245,7 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
257 | } | 245 | } |
258 | 246 | ||
259 | /* We're about to use some buffers from the free list. */ | 247 | /* We're about to use some buffers from the free list. */ |
260 | vq->num_free -= out + in; | 248 | vq->vq.num_free -= out + in; |
261 | 249 | ||
262 | head = vq->free_head; | 250 | head = vq->free_head; |
263 | for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { | 251 | for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { |
@@ -303,7 +291,7 @@ add_head: | |||
303 | pr_debug("Added buffer head %i to %p\n", head, vq); | 291 | pr_debug("Added buffer head %i to %p\n", head, vq); |
304 | END_USE(vq); | 292 | END_USE(vq); |
305 | 293 | ||
306 | return vq->num_free; | 294 | return vq->vq.num_free; |
307 | } | 295 | } |
308 | EXPORT_SYMBOL_GPL(virtqueue_add_buf); | 296 | EXPORT_SYMBOL_GPL(virtqueue_add_buf); |
309 | 297 | ||
@@ -400,13 +388,13 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head) | |||
400 | 388 | ||
401 | while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) { | 389 | while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) { |
402 | i = vq->vring.desc[i].next; | 390 | i = vq->vring.desc[i].next; |
403 | vq->num_free++; | 391 | vq->vq.num_free++; |
404 | } | 392 | } |
405 | 393 | ||
406 | vq->vring.desc[i].next = vq->free_head; | 394 | vq->vring.desc[i].next = vq->free_head; |
407 | vq->free_head = head; | 395 | vq->free_head = head; |
408 | /* Plus final descriptor */ | 396 | /* Plus final descriptor */ |
409 | vq->num_free++; | 397 | vq->vq.num_free++; |
410 | } | 398 | } |
411 | 399 | ||
412 | static inline bool more_used(const struct vring_virtqueue *vq) | 400 | static inline bool more_used(const struct vring_virtqueue *vq) |
@@ -606,7 +594,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | |||
606 | return buf; | 594 | return buf; |
607 | } | 595 | } |
608 | /* That should have freed everything. */ | 596 | /* That should have freed everything. */ |
609 | BUG_ON(vq->num_free != vq->vring.num); | 597 | BUG_ON(vq->vq.num_free != vq->vring.num); |
610 | 598 | ||
611 | END_USE(vq); | 599 | END_USE(vq); |
612 | return NULL; | 600 | return NULL; |
@@ -660,12 +648,13 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
660 | vq->vq.callback = callback; | 648 | vq->vq.callback = callback; |
661 | vq->vq.vdev = vdev; | 649 | vq->vq.vdev = vdev; |
662 | vq->vq.name = name; | 650 | vq->vq.name = name; |
651 | vq->vq.num_free = num; | ||
652 | vq->vq.index = index; | ||
663 | vq->notify = notify; | 653 | vq->notify = notify; |
664 | vq->weak_barriers = weak_barriers; | 654 | vq->weak_barriers = weak_barriers; |
665 | vq->broken = false; | 655 | vq->broken = false; |
666 | vq->last_used_idx = 0; | 656 | vq->last_used_idx = 0; |
667 | vq->num_added = 0; | 657 | vq->num_added = 0; |
668 | vq->queue_index = index; | ||
669 | list_add_tail(&vq->vq.list, &vdev->vqs); | 658 | list_add_tail(&vq->vq.list, &vdev->vqs); |
670 | #ifdef DEBUG | 659 | #ifdef DEBUG |
671 | vq->in_use = false; | 660 | vq->in_use = false; |
@@ -680,7 +669,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
680 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; | 669 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; |
681 | 670 | ||
682 | /* Put everything in free lists. */ | 671 | /* Put everything in free lists. */ |
683 | vq->num_free = num; | ||
684 | vq->free_head = 0; | 672 | vq->free_head = 0; |
685 | for (i = 0; i < num-1; i++) { | 673 | for (i = 0; i < num-1; i++) { |
686 | vq->vring.desc[i].next = i+1; | 674 | vq->vring.desc[i].next = i+1; |
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 533b1157f22e..4b8f17d90458 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
@@ -16,12 +16,20 @@ | |||
16 | * @name: the name of this virtqueue (mainly for debugging) | 16 | * @name: the name of this virtqueue (mainly for debugging) |
17 | * @vdev: the virtio device this queue was created for. | 17 | * @vdev: the virtio device this queue was created for. |
18 | * @priv: a pointer for the virtqueue implementation to use. | 18 | * @priv: a pointer for the virtqueue implementation to use. |
19 | * @index: the zero-based ordinal number for this queue. | ||
20 | * @num_free: number of elements we expect to be able to fit. | ||
21 | * | ||
22 | * A note on @num_free: with indirect buffers, each buffer needs one | ||
23 | * element in the queue, otherwise a buffer will need one element per | ||
24 | * sg element. | ||
19 | */ | 25 | */ |
20 | struct virtqueue { | 26 | struct virtqueue { |
21 | struct list_head list; | 27 | struct list_head list; |
22 | void (*callback)(struct virtqueue *vq); | 28 | void (*callback)(struct virtqueue *vq); |
23 | const char *name; | 29 | const char *name; |
24 | struct virtio_device *vdev; | 30 | struct virtio_device *vdev; |
31 | unsigned int index; | ||
32 | unsigned int num_free; | ||
25 | void *priv; | 33 | void *priv; |
26 | }; | 34 | }; |
27 | 35 | ||
@@ -50,7 +58,11 @@ void *virtqueue_detach_unused_buf(struct virtqueue *vq); | |||
50 | 58 | ||
51 | unsigned int virtqueue_get_vring_size(struct virtqueue *vq); | 59 | unsigned int virtqueue_get_vring_size(struct virtqueue *vq); |
52 | 60 | ||
53 | int virtqueue_get_queue_index(struct virtqueue *vq); | 61 | /* FIXME: Obsolete accessor, but required for virtio_net merge. */ |
62 | static inline unsigned int virtqueue_get_queue_index(struct virtqueue *vq) | ||
63 | { | ||
64 | return vq->index; | ||
65 | } | ||
54 | 66 | ||
55 | /** | 67 | /** |
56 | * virtio_device - representation of a device using virtio | 68 | * virtio_device - representation of a device using virtio |