diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2010-04-29 17:26:37 +0300 | 
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-05-19 22:15:46 +0930 | 
| commit | bbd603efb4238cf78083c00f0a81adfa8994aa33 (patch) | |
| tree | 3980961f9dbf08e748b3c2de56caf43dec21aa76 | |
| parent | dc3f5e68f846eec38fb31d78f0b6e83633ad375e (diff) | |
| download | olio-linux-3.10-bbd603efb4238cf78083c00f0a81adfa8994aa33.tar.xz olio-linux-3.10-bbd603efb4238cf78083c00f0a81adfa8994aa33.zip  | |
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>
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 20 | ||||
| -rw-r--r-- | include/linux/virtio.h | 22 | 
2 files changed, 28 insertions, 14 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0717b5b000b..1ca88908723 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -110,13 +110,14 @@ struct vring_virtqueue  static int vring_add_indirect(struct vring_virtqueue *vq,  			      struct scatterlist sg[],  			      unsigned int out, -			      unsigned int in) +			      unsigned int in, +			      gfp_t gfp)  {  	struct vring_desc *desc;  	unsigned head;  	int i; -	desc = kmalloc((out + in) * sizeof(struct vring_desc), GFP_ATOMIC); +	desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp);  	if (!desc)  		return vq->vring.num; @@ -155,11 +156,12 @@ static int vring_add_indirect(struct vring_virtqueue *vq,  	return head;  } -int virtqueue_add_buf(struct virtqueue *_vq, -		  struct scatterlist sg[], -		  unsigned int out, -		  unsigned int in, -		  void *data) +int virtqueue_add_buf_gfp(struct virtqueue *_vq, +			  struct scatterlist sg[], +			  unsigned int out, +			  unsigned int in, +			  void *data, +			  gfp_t gfp)  {  	struct vring_virtqueue *vq = to_vvq(_vq);  	unsigned int i, avail, head, uninitialized_var(prev); @@ -171,7 +173,7 @@ int virtqueue_add_buf(struct virtqueue *_vq,  	/* If the host supports indirect descriptor tables, and we have multiple  	 * buffers, then go indirect. FIXME: tune this threshold */  	if (vq->indirect && (out + in) > 1 && vq->num_free) { -		head = vring_add_indirect(vq, sg, out, in); +		head = vring_add_indirect(vq, sg, out, in, gfp);  		if (head != vq->vring.num)  			goto add_head;  	} @@ -232,7 +234,7 @@ add_head:  		return vq->num_free ? vq->vring.num : 0;  	return vq->num_free;  } -EXPORT_SYMBOL_GPL(virtqueue_add_buf); +EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);  void virtqueue_kick(struct virtqueue *_vq)  { diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 5b0fce0d2aa..aff5b4f7404 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -7,6 +7,7 @@  #include <linux/spinlock.h>  #include <linux/device.h>  #include <linux/mod_devicetable.h> +#include <linux/gfp.h>  /**   * virtqueue - a queue to register buffers for sending or receiving. @@ -32,6 +33,7 @@ struct virtqueue {   *	out_num: the number of sg readable by other side   *	in_num: the number of sg which are writable (after readable ones)   *	data: the token identifying the buffer. + *	gfp: how to do memory allocations (if necessary).   *      Returns remaining capacity of queue (sg segments) or a negative error.   * virtqueue_kick: update after add_buf   *	vq: the struct virtqueue @@ -60,11 +62,21 @@ struct virtqueue {   * All operations can be called in any context.   */ -int virtqueue_add_buf(struct virtqueue *vq, -		      struct scatterlist sg[], -		      unsigned int out_num, -		      unsigned int in_num, -		      void *data); +int virtqueue_add_buf_gfp(struct virtqueue *vq, +			  struct scatterlist sg[], +			  unsigned int out_num, +			  unsigned int in_num, +			  void *data, +			  gfp_t gfp); + +static inline int virtqueue_add_buf(struct virtqueue *vq, +				    struct scatterlist sg[], +				    unsigned int out_num, +				    unsigned int in_num, +				    void *data) +{ +	return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC); +}  void virtqueue_kick(struct virtqueue *vq);  |