aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_ring.c')
-rw-r--r--drivers/virtio/virtio_ring.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index e639584b2dbd..ffd7e7da5d3b 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;
@@ -135,6 +130,13 @@ static int vring_add_indirect(struct vring_virtqueue *vq,
135 unsigned head; 130 unsigned head;
136 int i; 131 int i;
137 132
133 /*
134 * We require lowmem mappings for the descriptors because
135 * otherwise virt_to_phys will give us bogus addresses in the
136 * virtqueue.
137 */
138 gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH);
139
138 desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); 140 desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp);
139 if (!desc) 141 if (!desc)
140 return -ENOMEM; 142 return -ENOMEM;
@@ -160,7 +162,7 @@ static int vring_add_indirect(struct vring_virtqueue *vq,
160 desc[i-1].next = 0; 162 desc[i-1].next = 0;
161 163
162 /* We're about to use a buffer */ 164 /* We're about to use a buffer */
163 vq->num_free--; 165 vq->vq.num_free--;
164 166
165 /* Use a single buffer which doesn't continue */ 167 /* Use a single buffer which doesn't continue */
166 head = vq->free_head; 168 head = vq->free_head;
@@ -174,13 +176,6 @@ static int vring_add_indirect(struct vring_virtqueue *vq,
174 return head; 176 return head;
175} 177}
176 178
177int virtqueue_get_queue_index(struct virtqueue *_vq)
178{
179 struct vring_virtqueue *vq = to_vvq(_vq);
180 return vq->queue_index;
181}
182EXPORT_SYMBOL_GPL(virtqueue_get_queue_index);
183
184/** 179/**
185 * virtqueue_add_buf - expose buffer to other end 180 * virtqueue_add_buf - expose buffer to other end
186 * @vq: the struct virtqueue we're talking about. 181 * @vq: the struct virtqueue we're talking about.
@@ -193,10 +188,7 @@ EXPORT_SYMBOL_GPL(virtqueue_get_queue_index);
193 * Caller must ensure we don't call this with other virtqueue operations 188 * Caller must ensure we don't call this with other virtqueue operations
194 * at the same time (except where noted). 189 * at the same time (except where noted).
195 * 190 *
196 * Returns remaining capacity of queue or a negative error 191 * Returns zero or a negative error (ie. ENOSPC, ENOMEM).
197 * (ie. ENOSPC). Note that it only really makes sense to treat all
198 * positive return values as "available": indirect buffers mean that
199 * we can put an entire sg[] array inside a single queue entry.
200 */ 192 */
201int virtqueue_add_buf(struct virtqueue *_vq, 193int virtqueue_add_buf(struct virtqueue *_vq,
202 struct scatterlist sg[], 194 struct scatterlist sg[],
@@ -228,7 +220,7 @@ int virtqueue_add_buf(struct virtqueue *_vq,
228 220
229 /* If the host supports indirect descriptor tables, and we have multiple 221 /* If the host supports indirect descriptor tables, and we have multiple
230 * buffers, then go indirect. FIXME: tune this threshold */ 222 * buffers, then go indirect. FIXME: tune this threshold */
231 if (vq->indirect && (out + in) > 1 && vq->num_free) { 223 if (vq->indirect && (out + in) > 1 && vq->vq.num_free) {
232 head = vring_add_indirect(vq, sg, out, in, gfp); 224 head = vring_add_indirect(vq, sg, out, in, gfp);
233 if (likely(head >= 0)) 225 if (likely(head >= 0))
234 goto add_head; 226 goto add_head;
@@ -237,9 +229,9 @@ int virtqueue_add_buf(struct virtqueue *_vq,
237 BUG_ON(out + in > vq->vring.num); 229 BUG_ON(out + in > vq->vring.num);
238 BUG_ON(out + in == 0); 230 BUG_ON(out + in == 0);
239 231
240 if (vq->num_free < out + in) { 232 if (vq->vq.num_free < out + in) {
241 pr_debug("Can't add buf len %i - avail = %i\n", 233 pr_debug("Can't add buf len %i - avail = %i\n",
242 out + in, vq->num_free); 234 out + in, vq->vq.num_free);
243 /* FIXME: for historical reasons, we force a notify here if 235 /* FIXME: for historical reasons, we force a notify here if
244 * there are outgoing parts to the buffer. Presumably the 236 * there are outgoing parts to the buffer. Presumably the
245 * host should service the ring ASAP. */ 237 * host should service the ring ASAP. */
@@ -250,7 +242,7 @@ int virtqueue_add_buf(struct virtqueue *_vq,
250 } 242 }
251 243
252 /* We're about to use some buffers from the free list. */ 244 /* We're about to use some buffers from the free list. */
253 vq->num_free -= out + in; 245 vq->vq.num_free -= out + in;
254 246
255 head = vq->free_head; 247 head = vq->free_head;
256 for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { 248 for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
@@ -296,7 +288,7 @@ add_head:
296 pr_debug("Added buffer head %i to %p\n", head, vq); 288 pr_debug("Added buffer head %i to %p\n", head, vq);
297 END_USE(vq); 289 END_USE(vq);
298 290
299 return vq->num_free; 291 return 0;
300} 292}
301EXPORT_SYMBOL_GPL(virtqueue_add_buf); 293EXPORT_SYMBOL_GPL(virtqueue_add_buf);
302 294
@@ -393,13 +385,13 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
393 385
394 while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) { 386 while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
395 i = vq->vring.desc[i].next; 387 i = vq->vring.desc[i].next;
396 vq->num_free++; 388 vq->vq.num_free++;
397 } 389 }
398 390
399 vq->vring.desc[i].next = vq->free_head; 391 vq->vring.desc[i].next = vq->free_head;
400 vq->free_head = head; 392 vq->free_head = head;
401 /* Plus final descriptor */ 393 /* Plus final descriptor */
402 vq->num_free++; 394 vq->vq.num_free++;
403} 395}
404 396
405static inline bool more_used(const struct vring_virtqueue *vq) 397static inline bool more_used(const struct vring_virtqueue *vq)
@@ -599,7 +591,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
599 return buf; 591 return buf;
600 } 592 }
601 /* That should have freed everything. */ 593 /* That should have freed everything. */
602 BUG_ON(vq->num_free != vq->vring.num); 594 BUG_ON(vq->vq.num_free != vq->vring.num);
603 595
604 END_USE(vq); 596 END_USE(vq);
605 return NULL; 597 return NULL;
@@ -653,12 +645,13 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
653 vq->vq.callback = callback; 645 vq->vq.callback = callback;
654 vq->vq.vdev = vdev; 646 vq->vq.vdev = vdev;
655 vq->vq.name = name; 647 vq->vq.name = name;
648 vq->vq.num_free = num;
649 vq->vq.index = index;
656 vq->notify = notify; 650 vq->notify = notify;
657 vq->weak_barriers = weak_barriers; 651 vq->weak_barriers = weak_barriers;
658 vq->broken = false; 652 vq->broken = false;
659 vq->last_used_idx = 0; 653 vq->last_used_idx = 0;
660 vq->num_added = 0; 654 vq->num_added = 0;
661 vq->queue_index = index;
662 list_add_tail(&vq->vq.list, &vdev->vqs); 655 list_add_tail(&vq->vq.list, &vdev->vqs);
663#ifdef DEBUG 656#ifdef DEBUG
664 vq->in_use = false; 657 vq->in_use = false;
@@ -673,7 +666,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
673 vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; 666 vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
674 667
675 /* Put everything in free lists. */ 668 /* Put everything in free lists. */
676 vq->num_free = num;
677 vq->free_head = 0; 669 vq->free_head = 0;
678 for (i = 0; i < num-1; i++) { 670 for (i = 0; i < num-1; i++) {
679 vq->vring.desc[i].next = i+1; 671 vq->vring.desc[i].next = i+1;