Skip to content

Commit

Permalink
vringh: implement vringh_kiov_advance()
Browse files Browse the repository at this point in the history
In some cases, it may be useful to provide a way to skip a number
of bytes in a vringh_kiov.

Let's implement vringh_kiov_advance() for this purpose, reusing the
code from vringh_iov_xfer().
We replace that code calling the new vringh_kiov_advance().

Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20210315163450.254396-6-sgarzare@redhat.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Stefano Garzarella authored and Michael S. Tsirkin committed May 3, 2021
1 parent 69c13c5 commit b8c06ad
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
41 changes: 29 additions & 12 deletions drivers/vhost/vringh.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,34 @@ static inline int __vringh_get_head(const struct vringh *vrh,
return head;
}

/**
* vringh_kiov_advance - skip bytes from vring_kiov
* @iov: an iov passed to vringh_getdesc_*() (updated as we consume)
* @len: the maximum length to advance
*/
void vringh_kiov_advance(struct vringh_kiov *iov, size_t len)
{
while (len && iov->i < iov->used) {
size_t partlen = min(iov->iov[iov->i].iov_len, len);

iov->consumed += partlen;
iov->iov[iov->i].iov_len -= partlen;
iov->iov[iov->i].iov_base += partlen;

if (!iov->iov[iov->i].iov_len) {
/* Fix up old iov element then increment. */
iov->iov[iov->i].iov_len = iov->consumed;
iov->iov[iov->i].iov_base -= iov->consumed;

iov->consumed = 0;
iov->i++;
}

len -= partlen;
}
}
EXPORT_SYMBOL(vringh_kiov_advance);

/* Copy some bytes to/from the iovec. Returns num copied. */
static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
struct vringh_kiov *iov,
Expand All @@ -95,19 +123,8 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
done += partlen;
len -= partlen;
ptr += partlen;
iov->consumed += partlen;
iov->iov[iov->i].iov_len -= partlen;
iov->iov[iov->i].iov_base += partlen;

if (!iov->iov[iov->i].iov_len) {
/* Fix up old iov element then increment. */
iov->iov[iov->i].iov_len = iov->consumed;
iov->iov[iov->i].iov_base -= iov->consumed;


iov->consumed = 0;
iov->i++;
}
vringh_kiov_advance(iov, partlen);
}
return done;
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/vringh.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
kiov->iov = NULL;
}

void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);

int vringh_getdesc_kern(struct vringh *vrh,
struct vringh_kiov *riov,
struct vringh_kiov *wiov,
Expand Down

0 comments on commit b8c06ad

Please sign in to comment.