Commit 282edb36499042a92b71f052f51754ae7ed936e4

Authored by Rusty Russell
1 parent 13816c768d

virtio_ring: virtqueue_add_outbuf / virtqueue_add_inbuf.

These are specialized versions of virtqueue_add_buf(), which cover
over 80% of cases and are far clearer.

In particular, the scatterlists passed to these functions don't have
to be clean (ie. we ignore end markers).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 54 additions and 0 deletions Side-by-side Diff

drivers/virtio/virtio_ring.c
... ... @@ -366,6 +366,50 @@
366 366 EXPORT_SYMBOL_GPL(virtqueue_add_sgs);
367 367  
368 368 /**
  369 + * virtqueue_add_outbuf - expose output buffers to other end
  370 + * @vq: the struct virtqueue we're talking about.
  371 + * @sgs: array of scatterlists (need not be terminated!)
  372 + * @num: the number of scatterlists readable by other side
  373 + * @data: the token identifying the buffer.
  374 + * @gfp: how to do memory allocations (if necessary).
  375 + *
  376 + * Caller must ensure we don't call this with other virtqueue operations
  377 + * at the same time (except where noted).
  378 + *
  379 + * Returns zero or a negative error (ie. ENOSPC, ENOMEM).
  380 + */
  381 +int virtqueue_add_outbuf(struct virtqueue *vq,
  382 + struct scatterlist sg[], unsigned int num,
  383 + void *data,
  384 + gfp_t gfp)
  385 +{
  386 + return virtqueue_add(vq, &sg, sg_next_arr, num, 0, 1, 0, data, gfp);
  387 +}
  388 +EXPORT_SYMBOL_GPL(virtqueue_add_outbuf);
  389 +
  390 +/**
  391 + * virtqueue_add_inbuf - expose input buffers to other end
  392 + * @vq: the struct virtqueue we're talking about.
  393 + * @sgs: array of scatterlists (need not be terminated!)
  394 + * @num: the number of scatterlists writable by other side
  395 + * @data: the token identifying the buffer.
  396 + * @gfp: how to do memory allocations (if necessary).
  397 + *
  398 + * Caller must ensure we don't call this with other virtqueue operations
  399 + * at the same time (except where noted).
  400 + *
  401 + * Returns zero or a negative error (ie. ENOSPC, ENOMEM).
  402 + */
  403 +int virtqueue_add_inbuf(struct virtqueue *vq,
  404 + struct scatterlist sg[], unsigned int num,
  405 + void *data,
  406 + gfp_t gfp)
  407 +{
  408 + return virtqueue_add(vq, &sg, sg_next_arr, 0, num, 0, 1, data, gfp);
  409 +}
  410 +EXPORT_SYMBOL_GPL(virtqueue_add_inbuf);
  411 +
  412 +/**
369 413 * virtqueue_kick_prepare - first half of split virtqueue_kick call.
370 414 * @vq: the struct virtqueue
371 415 *
include/linux/virtio.h
... ... @@ -41,6 +41,16 @@
41 41 void *data,
42 42 gfp_t gfp);
43 43  
  44 +int virtqueue_add_outbuf(struct virtqueue *vq,
  45 + struct scatterlist sg[], unsigned int num,
  46 + void *data,
  47 + gfp_t gfp);
  48 +
  49 +int virtqueue_add_inbuf(struct virtqueue *vq,
  50 + struct scatterlist sg[], unsigned int num,
  51 + void *data,
  52 + gfp_t gfp);
  53 +
44 54 int virtqueue_add_sgs(struct virtqueue *vq,
45 55 struct scatterlist *sgs[],
46 56 unsigned int out_sgs,