virtio_ring.c (818b930bc15077fc00ff16bb22c5df1857f05afa) virtio_ring.c (06ca287dbac9cc19d04ac2901b8c4882c03795ff)
1/* Virtio ring implementation.
2 *
3 * Copyright 2007 Rusty Russell IBM Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.

--- 79 unchanged lines hidden (view full) ---

88 bool broken;
89
90 /* Host supports indirect buffers */
91 bool indirect;
92
93 /* Host publishes avail event idx */
94 bool event;
95
1/* Virtio ring implementation.
2 *
3 * Copyright 2007 Rusty Russell IBM Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.

--- 79 unchanged lines hidden (view full) ---

88 bool broken;
89
90 /* Host supports indirect buffers */
91 bool indirect;
92
93 /* Host publishes avail event idx */
94 bool event;
95
96 /* Number of free buffers */
97 unsigned int num_free;
98 /* Head of free buffer list. */
99 unsigned int free_head;
100 /* Number we've added since last sync. */
101 unsigned int num_added;
102
103 /* Last used index we've seen. */
104 u16 last_used_idx;
105
106 /* How to notify other side. FIXME: commonalize hcalls! */
107 void (*notify)(struct virtqueue *vq);
108
96 /* Head of free buffer list. */
97 unsigned int free_head;
98 /* Number we've added since last sync. */
99 unsigned int num_added;
100
101 /* Last used index we've seen. */
102 u16 last_used_idx;
103
104 /* How to notify other side. FIXME: commonalize hcalls! */
105 void (*notify)(struct virtqueue *vq);
106
109 /* Index of the queue */
110 int queue_index;
111
112#ifdef DEBUG
113 /* They're supposed to lock for us. */
114 unsigned int in_use;
115
116 /* Figure out if their kicks are too delayed. */
117 bool last_add_time_valid;
118 ktime_t last_add_time;
119#endif

--- 10 unchanged lines hidden (view full) ---

130 unsigned int out,
131 unsigned int in,
132 gfp_t gfp)
133{
134 struct vring_desc *desc;
135 unsigned head;
136 int i;
137
107#ifdef DEBUG
108 /* They're supposed to lock for us. */
109 unsigned int in_use;
110
111 /* Figure out if their kicks are too delayed. */
112 bool last_add_time_valid;
113 ktime_t last_add_time;
114#endif

--- 10 unchanged lines hidden (view full) ---

125 unsigned int out,
126 unsigned int in,
127 gfp_t gfp)
128{
129 struct vring_desc *desc;
130 unsigned head;
131 int i;
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);
139 if (!desc)
140 return -ENOMEM;
141
142 /* Transfer entries from the sg list into the indirect page */
143 for (i = 0; i < out; i++) {
144 desc[i].flags = VRING_DESC_F_NEXT;
145 desc[i].addr = sg_phys(sg);

--- 9 unchanged lines hidden (view full) ---

155 sg++;
156 }
157
158 /* Last one doesn't continue. */
159 desc[i-1].flags &= ~VRING_DESC_F_NEXT;
160 desc[i-1].next = 0;
161
162 /* We're about to use a buffer */
140 desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp);
141 if (!desc)
142 return -ENOMEM;
143
144 /* Transfer entries from the sg list into the indirect page */
145 for (i = 0; i < out; i++) {
146 desc[i].flags = VRING_DESC_F_NEXT;
147 desc[i].addr = sg_phys(sg);

--- 9 unchanged lines hidden (view full) ---

157 sg++;
158 }
159
160 /* Last one doesn't continue. */
161 desc[i-1].flags &= ~VRING_DESC_F_NEXT;
162 desc[i-1].next = 0;
163
164 /* We're about to use a buffer */
163 vq->num_free--;
165 vq->vq.num_free--;
164
165 /* Use a single buffer which doesn't continue */
166 head = vq->free_head;
167 vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
168 vq->vring.desc[head].addr = virt_to_phys(desc);
169 vq->vring.desc[head].len = i * sizeof(struct vring_desc);
170
171 /* Update free pointer */
172 vq->free_head = vq->vring.desc[head].next;
173
174 return head;
175}
176
166
167 /* Use a single buffer which doesn't continue */
168 head = vq->free_head;
169 vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
170 vq->vring.desc[head].addr = virt_to_phys(desc);
171 vq->vring.desc[head].len = i * sizeof(struct vring_desc);
172
173 /* Update free pointer */
174 vq->free_head = vq->vring.desc[head].next;
175
176 return head;
177}
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/**
185 * virtqueue_add_buf - expose buffer to other end
186 * @vq: the struct virtqueue we're talking about.
187 * @sg: the description of the buffer(s).
188 * @out_num: the number of sg readable by other side
189 * @in_num: the number of sg which are writable (after readable ones)
190 * @data: the token identifying the buffer.
191 * @gfp: how to do memory allocations (if necessary).

--- 31 unchanged lines hidden (view full) ---

223 > 100);
224 vq->last_add_time = now;
225 vq->last_add_time_valid = true;
226 }
227#endif
228
229 /* If the host supports indirect descriptor tables, and we have multiple
230 * buffers, then go indirect. FIXME: tune this threshold */
179/**
180 * virtqueue_add_buf - expose buffer to other end
181 * @vq: the struct virtqueue we're talking about.
182 * @sg: the description of the buffer(s).
183 * @out_num: the number of sg readable by other side
184 * @in_num: the number of sg which are writable (after readable ones)
185 * @data: the token identifying the buffer.
186 * @gfp: how to do memory allocations (if necessary).

--- 31 unchanged lines hidden (view full) ---

218 > 100);
219 vq->last_add_time = now;
220 vq->last_add_time_valid = true;
221 }
222#endif
223
224 /* If the host supports indirect descriptor tables, and we have multiple
225 * buffers, then go indirect. FIXME: tune this threshold */
231 if (vq->indirect && (out + in) > 1 && vq->num_free) {
226 if (vq->indirect && (out + in) > 1 && vq->vq.num_free) {
232 head = vring_add_indirect(vq, sg, out, in, gfp);
233 if (likely(head >= 0))
234 goto add_head;
235 }
236
237 BUG_ON(out + in > vq->vring.num);
238 BUG_ON(out + in == 0);
239
227 head = vring_add_indirect(vq, sg, out, in, gfp);
228 if (likely(head >= 0))
229 goto add_head;
230 }
231
232 BUG_ON(out + in > vq->vring.num);
233 BUG_ON(out + in == 0);
234
240 if (vq->num_free < out + in) {
235 if (vq->vq.num_free < out + in) {
241 pr_debug("Can't add buf len %i - avail = %i\n",
236 pr_debug("Can't add buf len %i - avail = %i\n",
242 out + in, vq->num_free);
237 out + in, vq->vq.num_free);
243 /* FIXME: for historical reasons, we force a notify here if
244 * there are outgoing parts to the buffer. Presumably the
245 * host should service the ring ASAP. */
246 if (out)
247 vq->notify(&vq->vq);
248 END_USE(vq);
249 return -ENOSPC;
250 }
251
252 /* We're about to use some buffers from the free list. */
238 /* FIXME: for historical reasons, we force a notify here if
239 * there are outgoing parts to the buffer. Presumably the
240 * host should service the ring ASAP. */
241 if (out)
242 vq->notify(&vq->vq);
243 END_USE(vq);
244 return -ENOSPC;
245 }
246
247 /* We're about to use some buffers from the free list. */
253 vq->num_free -= out + in;
248 vq->vq.num_free -= out + in;
254
255 head = vq->free_head;
256 for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
257 vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
258 vq->vring.desc[i].addr = sg_phys(sg);
259 vq->vring.desc[i].len = sg->length;
260 prev = i;
261 sg++;

--- 29 unchanged lines hidden (view full) ---

291 /* This is very unlikely, but theoretically possible. Kick
292 * just in case. */
293 if (unlikely(vq->num_added == (1 << 16) - 1))
294 virtqueue_kick(_vq);
295
296 pr_debug("Added buffer head %i to %p\n", head, vq);
297 END_USE(vq);
298
249
250 head = vq->free_head;
251 for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
252 vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
253 vq->vring.desc[i].addr = sg_phys(sg);
254 vq->vring.desc[i].len = sg->length;
255 prev = i;
256 sg++;

--- 29 unchanged lines hidden (view full) ---

286 /* This is very unlikely, but theoretically possible. Kick
287 * just in case. */
288 if (unlikely(vq->num_added == (1 << 16) - 1))
289 virtqueue_kick(_vq);
290
291 pr_debug("Added buffer head %i to %p\n", head, vq);
292 END_USE(vq);
293
299 return vq->num_free;
294 return vq->vq.num_free;
300}
301EXPORT_SYMBOL_GPL(virtqueue_add_buf);
302
303/**
304 * virtqueue_kick_prepare - first half of split virtqueue_kick call.
305 * @vq: the struct virtqueue
306 *
307 * Instead of virtqueue_kick(), you can do:

--- 80 unchanged lines hidden (view full) ---

388 i = head;
389
390 /* Free the indirect table */
391 if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT)
392 kfree(phys_to_virt(vq->vring.desc[i].addr));
393
394 while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
395 i = vq->vring.desc[i].next;
295}
296EXPORT_SYMBOL_GPL(virtqueue_add_buf);
297
298/**
299 * virtqueue_kick_prepare - first half of split virtqueue_kick call.
300 * @vq: the struct virtqueue
301 *
302 * Instead of virtqueue_kick(), you can do:

--- 80 unchanged lines hidden (view full) ---

383 i = head;
384
385 /* Free the indirect table */
386 if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT)
387 kfree(phys_to_virt(vq->vring.desc[i].addr));
388
389 while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
390 i = vq->vring.desc[i].next;
396 vq->num_free++;
391 vq->vq.num_free++;
397 }
398
399 vq->vring.desc[i].next = vq->free_head;
400 vq->free_head = head;
401 /* Plus final descriptor */
392 }
393
394 vq->vring.desc[i].next = vq->free_head;
395 vq->free_head = head;
396 /* Plus final descriptor */
402 vq->num_free++;
397 vq->vq.num_free++;
403}
404
405static inline bool more_used(const struct vring_virtqueue *vq)
406{
407 return vq->last_used_idx != vq->vring.used->idx;
408}
409
410/**

--- 183 unchanged lines hidden (view full) ---

594 /* detach_buf clears data, so grab it now. */
595 buf = vq->data[i];
596 detach_buf(vq, i);
597 vq->vring.avail->idx--;
598 END_USE(vq);
599 return buf;
600 }
601 /* That should have freed everything. */
398}
399
400static inline bool more_used(const struct vring_virtqueue *vq)
401{
402 return vq->last_used_idx != vq->vring.used->idx;
403}
404
405/**

--- 183 unchanged lines hidden (view full) ---

589 /* detach_buf clears data, so grab it now. */
590 buf = vq->data[i];
591 detach_buf(vq, i);
592 vq->vring.avail->idx--;
593 END_USE(vq);
594 return buf;
595 }
596 /* That should have freed everything. */
602 BUG_ON(vq->num_free != vq->vring.num);
597 BUG_ON(vq->vq.num_free != vq->vring.num);
603
604 END_USE(vq);
605 return NULL;
606}
607EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf);
608
609irqreturn_t vring_interrupt(int irq, void *_vq)
610{

--- 37 unchanged lines hidden (view full) ---

648 vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
649 if (!vq)
650 return NULL;
651
652 vring_init(&vq->vring, num, pages, vring_align);
653 vq->vq.callback = callback;
654 vq->vq.vdev = vdev;
655 vq->vq.name = name;
598
599 END_USE(vq);
600 return NULL;
601}
602EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf);
603
604irqreturn_t vring_interrupt(int irq, void *_vq)
605{

--- 37 unchanged lines hidden (view full) ---

643 vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
644 if (!vq)
645 return NULL;
646
647 vring_init(&vq->vring, num, pages, vring_align);
648 vq->vq.callback = callback;
649 vq->vq.vdev = vdev;
650 vq->vq.name = name;
651 vq->vq.num_free = num;
652 vq->vq.index = index;
656 vq->notify = notify;
657 vq->weak_barriers = weak_barriers;
658 vq->broken = false;
659 vq->last_used_idx = 0;
660 vq->num_added = 0;
653 vq->notify = notify;
654 vq->weak_barriers = weak_barriers;
655 vq->broken = false;
656 vq->last_used_idx = 0;
657 vq->num_added = 0;
661 vq->queue_index = index;
662 list_add_tail(&vq->vq.list, &vdev->vqs);
663#ifdef DEBUG
664 vq->in_use = false;
665 vq->last_add_time_valid = false;
666#endif
667
668 vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC);
669 vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
670
671 /* No callback? Tell other side not to bother us. */
672 if (!callback)
673 vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
674
675 /* Put everything in free lists. */
658 list_add_tail(&vq->vq.list, &vdev->vqs);
659#ifdef DEBUG
660 vq->in_use = false;
661 vq->last_add_time_valid = false;
662#endif
663
664 vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC);
665 vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
666
667 /* No callback? Tell other side not to bother us. */
668 if (!callback)
669 vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
670
671 /* Put everything in free lists. */
676 vq->num_free = num;
677 vq->free_head = 0;
678 for (i = 0; i < num-1; i++) {
679 vq->vring.desc[i].next = i+1;
680 vq->data[i] = NULL;
681 }
682 vq->data[i] = NULL;
683
684 return &vq->vq;

--- 46 unchanged lines hidden ---
672 vq->free_head = 0;
673 for (i = 0; i < num-1; i++) {
674 vq->vring.desc[i].next = i+1;
675 vq->data[i] = NULL;
676 }
677 vq->data[i] = NULL;
678
679 return &vq->vq;

--- 46 unchanged lines hidden ---