diff options
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 17 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 44 |
2 files changed, 29 insertions, 32 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index bfec7c29486d..0f1da45ba47d 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -75,7 +75,7 @@ static void balloon_ack(struct virtqueue *vq) | |||
75 | struct virtio_balloon *vb; | 75 | struct virtio_balloon *vb; |
76 | unsigned int len; | 76 | unsigned int len; |
77 | 77 | ||
78 | vb = vq->vq_ops->get_buf(vq, &len); | 78 | vb = virtqueue_get_buf(vq, &len); |
79 | if (vb) | 79 | if (vb) |
80 | complete(&vb->acked); | 80 | complete(&vb->acked); |
81 | } | 81 | } |
@@ -89,9 +89,9 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) | |||
89 | init_completion(&vb->acked); | 89 | init_completion(&vb->acked); |
90 | 90 | ||
91 | /* We should always be able to add one buffer to an empty queue. */ | 91 | /* We should always be able to add one buffer to an empty queue. */ |
92 | if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0) | 92 | if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) |
93 | BUG(); | 93 | BUG(); |
94 | vq->vq_ops->kick(vq); | 94 | virtqueue_kick(vq); |
95 | 95 | ||
96 | /* When host has read buffer, this completes via balloon_ack */ | 96 | /* When host has read buffer, this completes via balloon_ack */ |
97 | wait_for_completion(&vb->acked); | 97 | wait_for_completion(&vb->acked); |
@@ -204,7 +204,7 @@ static void stats_request(struct virtqueue *vq) | |||
204 | struct virtio_balloon *vb; | 204 | struct virtio_balloon *vb; |
205 | unsigned int len; | 205 | unsigned int len; |
206 | 206 | ||
207 | vb = vq->vq_ops->get_buf(vq, &len); | 207 | vb = virtqueue_get_buf(vq, &len); |
208 | if (!vb) | 208 | if (!vb) |
209 | return; | 209 | return; |
210 | vb->need_stats_update = 1; | 210 | vb->need_stats_update = 1; |
@@ -221,9 +221,9 @@ static void stats_handle_request(struct virtio_balloon *vb) | |||
221 | 221 | ||
222 | vq = vb->stats_vq; | 222 | vq = vb->stats_vq; |
223 | sg_init_one(&sg, vb->stats, sizeof(vb->stats)); | 223 | sg_init_one(&sg, vb->stats, sizeof(vb->stats)); |
224 | if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0) | 224 | if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) |
225 | BUG(); | 225 | BUG(); |
226 | vq->vq_ops->kick(vq); | 226 | virtqueue_kick(vq); |
227 | } | 227 | } |
228 | 228 | ||
229 | static void virtballoon_changed(struct virtio_device *vdev) | 229 | static void virtballoon_changed(struct virtio_device *vdev) |
@@ -314,10 +314,9 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
314 | * use it to signal us later. | 314 | * use it to signal us later. |
315 | */ | 315 | */ |
316 | sg_init_one(&sg, vb->stats, sizeof vb->stats); | 316 | sg_init_one(&sg, vb->stats, sizeof vb->stats); |
317 | if (vb->stats_vq->vq_ops->add_buf(vb->stats_vq, | 317 | if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb) < 0) |
318 | &sg, 1, 0, vb) < 0) | ||
319 | BUG(); | 318 | BUG(); |
320 | vb->stats_vq->vq_ops->kick(vb->stats_vq); | 319 | virtqueue_kick(vb->stats_vq); |
321 | } | 320 | } |
322 | 321 | ||
323 | vb->thread = kthread_run(balloon, vb, "vballoon"); | 322 | vb->thread = kthread_run(balloon, vb, "vballoon"); |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0f90634bcb85..1ca88908723b 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -110,13 +110,14 @@ struct vring_virtqueue | |||
110 | static int vring_add_indirect(struct vring_virtqueue *vq, | 110 | static int vring_add_indirect(struct vring_virtqueue *vq, |
111 | struct scatterlist sg[], | 111 | struct scatterlist sg[], |
112 | unsigned int out, | 112 | unsigned int out, |
113 | unsigned int in) | 113 | unsigned int in, |
114 | gfp_t gfp) | ||
114 | { | 115 | { |
115 | struct vring_desc *desc; | 116 | struct vring_desc *desc; |
116 | unsigned head; | 117 | unsigned head; |
117 | int i; | 118 | int i; |
118 | 119 | ||
119 | desc = kmalloc((out + in) * sizeof(struct vring_desc), GFP_ATOMIC); | 120 | desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); |
120 | if (!desc) | 121 | if (!desc) |
121 | return vq->vring.num; | 122 | return vq->vring.num; |
122 | 123 | ||
@@ -155,11 +156,12 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
155 | return head; | 156 | return head; |
156 | } | 157 | } |
157 | 158 | ||
158 | static int vring_add_buf(struct virtqueue *_vq, | 159 | int virtqueue_add_buf_gfp(struct virtqueue *_vq, |
159 | struct scatterlist sg[], | 160 | struct scatterlist sg[], |
160 | unsigned int out, | 161 | unsigned int out, |
161 | unsigned int in, | 162 | unsigned int in, |
162 | void *data) | 163 | void *data, |
164 | gfp_t gfp) | ||
163 | { | 165 | { |
164 | struct vring_virtqueue *vq = to_vvq(_vq); | 166 | struct vring_virtqueue *vq = to_vvq(_vq); |
165 | unsigned int i, avail, head, uninitialized_var(prev); | 167 | unsigned int i, avail, head, uninitialized_var(prev); |
@@ -171,7 +173,7 @@ static int vring_add_buf(struct virtqueue *_vq, | |||
171 | /* If the host supports indirect descriptor tables, and we have multiple | 173 | /* If the host supports indirect descriptor tables, and we have multiple |
172 | * buffers, then go indirect. FIXME: tune this threshold */ | 174 | * buffers, then go indirect. FIXME: tune this threshold */ |
173 | if (vq->indirect && (out + in) > 1 && vq->num_free) { | 175 | if (vq->indirect && (out + in) > 1 && vq->num_free) { |
174 | head = vring_add_indirect(vq, sg, out, in); | 176 | head = vring_add_indirect(vq, sg, out, in, gfp); |
175 | if (head != vq->vring.num) | 177 | if (head != vq->vring.num) |
176 | goto add_head; | 178 | goto add_head; |
177 | } | 179 | } |
@@ -232,8 +234,9 @@ add_head: | |||
232 | return vq->num_free ? vq->vring.num : 0; | 234 | return vq->num_free ? vq->vring.num : 0; |
233 | return vq->num_free; | 235 | return vq->num_free; |
234 | } | 236 | } |
237 | EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); | ||
235 | 238 | ||
236 | static void vring_kick(struct virtqueue *_vq) | 239 | void virtqueue_kick(struct virtqueue *_vq) |
237 | { | 240 | { |
238 | struct vring_virtqueue *vq = to_vvq(_vq); | 241 | struct vring_virtqueue *vq = to_vvq(_vq); |
239 | START_USE(vq); | 242 | START_USE(vq); |
@@ -253,6 +256,7 @@ static void vring_kick(struct virtqueue *_vq) | |||
253 | 256 | ||
254 | END_USE(vq); | 257 | END_USE(vq); |
255 | } | 258 | } |
259 | EXPORT_SYMBOL_GPL(virtqueue_kick); | ||
256 | 260 | ||
257 | static void detach_buf(struct vring_virtqueue *vq, unsigned int head) | 261 | static void detach_buf(struct vring_virtqueue *vq, unsigned int head) |
258 | { | 262 | { |
@@ -284,7 +288,7 @@ static inline bool more_used(const struct vring_virtqueue *vq) | |||
284 | return vq->last_used_idx != vq->vring.used->idx; | 288 | return vq->last_used_idx != vq->vring.used->idx; |
285 | } | 289 | } |
286 | 290 | ||
287 | static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) | 291 | void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) |
288 | { | 292 | { |
289 | struct vring_virtqueue *vq = to_vvq(_vq); | 293 | struct vring_virtqueue *vq = to_vvq(_vq); |
290 | void *ret; | 294 | void *ret; |
@@ -325,15 +329,17 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) | |||
325 | END_USE(vq); | 329 | END_USE(vq); |
326 | return ret; | 330 | return ret; |
327 | } | 331 | } |
332 | EXPORT_SYMBOL_GPL(virtqueue_get_buf); | ||
328 | 333 | ||
329 | static void vring_disable_cb(struct virtqueue *_vq) | 334 | void virtqueue_disable_cb(struct virtqueue *_vq) |
330 | { | 335 | { |
331 | struct vring_virtqueue *vq = to_vvq(_vq); | 336 | struct vring_virtqueue *vq = to_vvq(_vq); |
332 | 337 | ||
333 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; | 338 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; |
334 | } | 339 | } |
340 | EXPORT_SYMBOL_GPL(virtqueue_disable_cb); | ||
335 | 341 | ||
336 | static bool vring_enable_cb(struct virtqueue *_vq) | 342 | bool virtqueue_enable_cb(struct virtqueue *_vq) |
337 | { | 343 | { |
338 | struct vring_virtqueue *vq = to_vvq(_vq); | 344 | struct vring_virtqueue *vq = to_vvq(_vq); |
339 | 345 | ||
@@ -351,8 +357,9 @@ static bool vring_enable_cb(struct virtqueue *_vq) | |||
351 | END_USE(vq); | 357 | END_USE(vq); |
352 | return true; | 358 | return true; |
353 | } | 359 | } |
360 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); | ||
354 | 361 | ||
355 | static void *vring_detach_unused_buf(struct virtqueue *_vq) | 362 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) |
356 | { | 363 | { |
357 | struct vring_virtqueue *vq = to_vvq(_vq); | 364 | struct vring_virtqueue *vq = to_vvq(_vq); |
358 | unsigned int i; | 365 | unsigned int i; |
@@ -375,6 +382,7 @@ static void *vring_detach_unused_buf(struct virtqueue *_vq) | |||
375 | END_USE(vq); | 382 | END_USE(vq); |
376 | return NULL; | 383 | return NULL; |
377 | } | 384 | } |
385 | EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf); | ||
378 | 386 | ||
379 | irqreturn_t vring_interrupt(int irq, void *_vq) | 387 | irqreturn_t vring_interrupt(int irq, void *_vq) |
380 | { | 388 | { |
@@ -396,15 +404,6 @@ irqreturn_t vring_interrupt(int irq, void *_vq) | |||
396 | } | 404 | } |
397 | EXPORT_SYMBOL_GPL(vring_interrupt); | 405 | EXPORT_SYMBOL_GPL(vring_interrupt); |
398 | 406 | ||
399 | static struct virtqueue_ops vring_vq_ops = { | ||
400 | .add_buf = vring_add_buf, | ||
401 | .get_buf = vring_get_buf, | ||
402 | .kick = vring_kick, | ||
403 | .disable_cb = vring_disable_cb, | ||
404 | .enable_cb = vring_enable_cb, | ||
405 | .detach_unused_buf = vring_detach_unused_buf, | ||
406 | }; | ||
407 | |||
408 | struct virtqueue *vring_new_virtqueue(unsigned int num, | 407 | struct virtqueue *vring_new_virtqueue(unsigned int num, |
409 | unsigned int vring_align, | 408 | unsigned int vring_align, |
410 | struct virtio_device *vdev, | 409 | struct virtio_device *vdev, |
@@ -429,7 +428,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
429 | vring_init(&vq->vring, num, pages, vring_align); | 428 | vring_init(&vq->vring, num, pages, vring_align); |
430 | vq->vq.callback = callback; | 429 | vq->vq.callback = callback; |
431 | vq->vq.vdev = vdev; | 430 | vq->vq.vdev = vdev; |
432 | vq->vq.vq_ops = &vring_vq_ops; | ||
433 | vq->vq.name = name; | 431 | vq->vq.name = name; |
434 | vq->notify = notify; | 432 | vq->notify = notify; |
435 | vq->broken = false; | 433 | vq->broken = false; |