lkml.org 
[lkml]   [2018]   [Jul]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next 1/8] vhost: move get_rx_bufs to vhost.c
    Date
    Move get_rx_bufs() to vhost.c and rename it to
    vhost_get_bufs(). This helps to hide vring internal layout from
    specific device implementation. Packed ring implementation will
    benefit from this.

    Signed-off-by: Jason Wang <jasowang@redhat.com>
    ---
    drivers/vhost/net.c | 77 --------------------------------------------------
    drivers/vhost/vhost.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++
    drivers/vhost/vhost.h | 7 +++++
    3 files changed, 85 insertions(+), 77 deletions(-)

    diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
    index 29756d8..712b134 100644
    --- a/drivers/vhost/net.c
    +++ b/drivers/vhost/net.c
    @@ -685,83 +685,6 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
    return len;
    }

    -/* This is a multi-buffer version of vhost_get_desc, that works if
    - * vq has read descriptors only.
    - * @vq - the relevant virtqueue
    - * @datalen - data length we'll be reading
    - * @iovcount - returned count of io vectors we fill
    - * @log - vhost log
    - * @log_num - log offset
    - * @quota - headcount quota, 1 for big buffer
    - * returns number of buffer heads allocated, negative on error
    - */
    -static int get_rx_bufs(struct vhost_virtqueue *vq,
    - struct vring_used_elem *heads,
    - int datalen,
    - unsigned *iovcount,
    - struct vhost_log *log,
    - unsigned *log_num,
    - unsigned int quota)
    -{
    - unsigned int out, in;
    - int seg = 0;
    - int headcount = 0;
    - unsigned d;
    - int r, nlogs = 0;
    - /* len is always initialized before use since we are always called with
    - * datalen > 0.
    - */
    - u32 uninitialized_var(len);
    -
    - while (datalen > 0 && headcount < quota) {
    - if (unlikely(seg >= UIO_MAXIOV)) {
    - r = -ENOBUFS;
    - goto err;
    - }
    - r = vhost_get_vq_desc(vq, vq->iov + seg,
    - ARRAY_SIZE(vq->iov) - seg, &out,
    - &in, log, log_num);
    - if (unlikely(r < 0))
    - goto err;
    -
    - d = r;
    - if (d == vq->num) {
    - r = 0;
    - goto err;
    - }
    - if (unlikely(out || in <= 0)) {
    - vq_err(vq, "unexpected descriptor format for RX: "
    - "out %d, in %d\n", out, in);
    - r = -EINVAL;
    - goto err;
    - }
    - if (unlikely(log)) {
    - nlogs += *log_num;
    - log += *log_num;
    - }
    - heads[headcount].id = cpu_to_vhost32(vq, d);
    - len = iov_length(vq->iov + seg, in);
    - heads[headcount].len = cpu_to_vhost32(vq, len);
    - datalen -= len;
    - ++headcount;
    - seg += in;
    - }
    - heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen);
    - *iovcount = seg;
    - if (unlikely(log))
    - *log_num = nlogs;
    -
    - /* Detect overrun */
    - if (unlikely(datalen > 0)) {
    - r = UIO_MAXIOV + 1;
    - goto err;
    - }
    - return headcount;
    -err:
    - vhost_discard_vq_desc(vq, headcount);
    - return r;
    -}
    -
    /* Expects to be always run from workqueue - which acts as
    * read-size critical section for our kind of RCU. */
    static void handle_rx(struct vhost_net *net)
    diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
    index a502f1a..8814e5b 100644
    --- a/drivers/vhost/vhost.c
    +++ b/drivers/vhost/vhost.c
    @@ -2104,6 +2104,84 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
    }
    EXPORT_SYMBOL_GPL(vhost_get_vq_desc);

    +/* This is a multi-buffer version of vhost_get_desc, that works if
    + * vq has read descriptors only.
    + * @vq - the relevant virtqueue
    + * @datalen - data length we'll be reading
    + * @iovcount - returned count of io vectors we fill
    + * @log - vhost log
    + * @log_num - log offset
    + * @quota - headcount quota, 1 for big buffer
    + * returns number of buffer heads allocated, negative on error
    + */
    +int vhost_get_bufs(struct vhost_virtqueue *vq,
    + struct vring_used_elem *heads,
    + int datalen,
    + unsigned *iovcount,
    + struct vhost_log *log,
    + unsigned *log_num,
    + unsigned int quota)
    +{
    + unsigned int out, in;
    + int seg = 0;
    + int headcount = 0;
    + unsigned d;
    + int r, nlogs = 0;
    + /* len is always initialized before use since we are always called with
    + * datalen > 0.
    + */
    + u32 uninitialized_var(len);
    +
    + while (datalen > 0 && headcount < quota) {
    + if (unlikely(seg >= UIO_MAXIOV)) {
    + r = -ENOBUFS;
    + goto err;
    + }
    + r = vhost_get_vq_desc(vq, vq->iov + seg,
    + ARRAY_SIZE(vq->iov) - seg, &out,
    + &in, log, log_num);
    + if (unlikely(r < 0))
    + goto err;
    +
    + d = r;
    + if (d == vq->num) {
    + r = 0;
    + goto err;
    + }
    + if (unlikely(out || in <= 0)) {
    + vq_err(vq, "unexpected descriptor format for RX: "
    + "out %d, in %d\n", out, in);
    + r = -EINVAL;
    + goto err;
    + }
    + if (unlikely(log)) {
    + nlogs += *log_num;
    + log += *log_num;
    + }
    + heads[headcount].id = cpu_to_vhost32(vq, d);
    + len = iov_length(vq->iov + seg, in);
    + heads[headcount].len = cpu_to_vhost32(vq, len);
    + datalen -= len;
    + ++headcount;
    + seg += in;
    + }
    + heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen);
    + *iovcount = seg;
    + if (unlikely(log))
    + *log_num = nlogs;
    +
    + /* Detect overrun */
    + if (unlikely(datalen > 0)) {
    + r = UIO_MAXIOV + 1;
    + goto err;
    + }
    + return headcount;
    +err:
    + vhost_discard_vq_desc(vq, headcount);
    + return r;
    +}
    +EXPORT_SYMBOL_GPL(vhost_get_bufs);
    +
    /* Reverse the effect of vhost_get_vq_desc. Useful for error handling. */
    void vhost_discard_vq_desc(struct vhost_virtqueue *vq, int n)
    {
    diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
    index 6c844b9..52edd242 100644
    --- a/drivers/vhost/vhost.h
    +++ b/drivers/vhost/vhost.h
    @@ -185,6 +185,13 @@ int vhost_get_vq_desc(struct vhost_virtqueue *,
    struct iovec iov[], unsigned int iov_count,
    unsigned int *out_num, unsigned int *in_num,
    struct vhost_log *log, unsigned int *log_num);
    +int vhost_get_bufs(struct vhost_virtqueue *vq,
    + struct vring_used_elem *heads,
    + int datalen,
    + unsigned *iovcount,
    + struct vhost_log *log,
    + unsigned *log_num,
    + unsigned int quota);
    void vhost_discard_vq_desc(struct vhost_virtqueue *, int n);

    int vhost_vq_init_access(struct vhost_virtqueue *);
    --
    2.7.4
    \
     
     \ /
      Last update: 2018-07-03 07:41    [W:2.277 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site