Commit bbd603efb4238cf78083c00f0a81adfa8994aa33

Authored by Michael S. Tsirkin
Committed by Rusty Russell
1 parent dc3f5e68f8

virtio: add_buf_gfp

Add an add_buf variant that gets gfp parameter. Use that
to allocate indirect buffers.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 28 additions and 14 deletions Side-by-side Diff

drivers/virtio/virtio_ring.c
... ... @@ -110,13 +110,14 @@
110 110 static int vring_add_indirect(struct vring_virtqueue *vq,
111 111 struct scatterlist sg[],
112 112 unsigned int out,
113   - unsigned int in)
  113 + unsigned int in,
  114 + gfp_t gfp)
114 115 {
115 116 struct vring_desc *desc;
116 117 unsigned head;
117 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 121 if (!desc)
121 122 return vq->vring.num;
122 123  
... ... @@ -155,11 +156,12 @@
155 156 return head;
156 157 }
157 158  
158   -int virtqueue_add_buf(struct virtqueue *_vq,
159   - struct scatterlist sg[],
160   - unsigned int out,
161   - unsigned int in,
162   - void *data)
  159 +int virtqueue_add_buf_gfp(struct virtqueue *_vq,
  160 + struct scatterlist sg[],
  161 + unsigned int out,
  162 + unsigned int in,
  163 + void *data,
  164 + gfp_t gfp)
163 165 {
164 166 struct vring_virtqueue *vq = to_vvq(_vq);
165 167 unsigned int i, avail, head, uninitialized_var(prev);
... ... @@ -171,7 +173,7 @@
171 173 /* If the host supports indirect descriptor tables, and we have multiple
172 174 * buffers, then go indirect. FIXME: tune this threshold */
173 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 177 if (head != vq->vring.num)
176 178 goto add_head;
177 179 }
... ... @@ -232,7 +234,7 @@
232 234 return vq->num_free ? vq->vring.num : 0;
233 235 return vq->num_free;
234 236 }
235   -EXPORT_SYMBOL_GPL(virtqueue_add_buf);
  237 +EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
236 238  
237 239 void virtqueue_kick(struct virtqueue *_vq)
238 240 {
include/linux/virtio.h
... ... @@ -7,6 +7,7 @@
7 7 #include <linux/spinlock.h>
8 8 #include <linux/device.h>
9 9 #include <linux/mod_devicetable.h>
  10 +#include <linux/gfp.h>
10 11  
11 12 /**
12 13 * virtqueue - a queue to register buffers for sending or receiving.
... ... @@ -32,6 +33,7 @@
32 33 * out_num: the number of sg readable by other side
33 34 * in_num: the number of sg which are writable (after readable ones)
34 35 * data: the token identifying the buffer.
  36 + * gfp: how to do memory allocations (if necessary).
35 37 * Returns remaining capacity of queue (sg segments) or a negative error.
36 38 * virtqueue_kick: update after add_buf
37 39 * vq: the struct virtqueue
... ... @@ -60,11 +62,21 @@
60 62 * All operations can be called in any context.
61 63 */
62 64  
63   -int virtqueue_add_buf(struct virtqueue *vq,
64   - struct scatterlist sg[],
65   - unsigned int out_num,
66   - unsigned int in_num,
67   - void *data);
  65 +int virtqueue_add_buf_gfp(struct virtqueue *vq,
  66 + struct scatterlist sg[],
  67 + unsigned int out_num,
  68 + unsigned int in_num,
  69 + void *data,
  70 + gfp_t gfp);
  71 +
  72 +static inline int virtqueue_add_buf(struct virtqueue *vq,
  73 + struct scatterlist sg[],
  74 + unsigned int out_num,
  75 + unsigned int in_num,
  76 + void *data)
  77 +{
  78 + return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC);
  79 +}
68 80  
69 81 void virtqueue_kick(struct virtqueue *vq);
70 82