Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1940626imm; Wed, 16 May 2018 05:33:20 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrZ8+Tbbk5BUwhlMOr3Q583tTtxWaQcP3Mq62xcsTr4Mk3/Mlo5oXdkJdR6E8rS17iQ+Sid X-Received: by 2002:a17:902:7c94:: with SMTP id y20-v6mr794867pll.202.1526474000936; Wed, 16 May 2018 05:33:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526474000; cv=none; d=google.com; s=arc-20160816; b=ACFYXY1n8LVP4HDWUy0bgVrr85jcmkgOpU1nPSlZTm5pKzNxOLdAGP83/29tceeiCO XGnxjJ6JgNrA6o/aTFU0yMLGiHXVTxM+i+qqTIKrsvLEoAevysXHU8yMctS5zxPKDN/w cDegY3AgNdR6xtUNSlsOWNoLq2JCsUWzXZ7km6DD2wULsPvmPDbunv69STai8Bgyt+lP KtNVMC6Sluf8+N+FrWaGfxe0X3vwxC3q34De6Yq9D3un5GoWF68aBrqdL/ux9pXl7dU1 HtcYkI/Z4aaPgbhkIbXIB5K8wP0sOS6HpCFNrr5ZcN+lqTngsxxtHpqILjls3iOFplqP M+nQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=IbLCmDjH6y2VKALmynNZiE0WmRCkv9Tr0gK8UmPP8Is=; b=SsfM9vrZjVFbUxO5ySvrgmzPiEUQ15WMB1zJVCM/2MMk0PGc2dRl9tyFj92ol3ZHgP nkAqJq8fmaTtiTTTFdriX7OqQDgwOJf1XjtgRZXP/Wle2xg+LHjeLDQVUHfaS4/eovQj EihGHifNJpiysRGhQ+h/U3Ow3LyH8RZkMp7dn406R7tekRyUe9xywLiW+C/jx1LGuVoS 7rGe8E540meUlTbEyRbCi69R5fZGmYp8mQIm1DDQbWJaR+SHiz/Uz86MUwqH1Um5wRH2 o6r5C1TH68Gyopn5qUkVcsVgL6GGL8dSGUDFGMDCus2rBhzku9uDn2P2NUnRD8zWjGYv cg9w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e2-v6si2618961pfm.220.2018.05.16.05.33.07; Wed, 16 May 2018 05:33:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752449AbeEPMci (ORCPT + 99 others); Wed, 16 May 2018 08:32:38 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:47380 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752309AbeEPMcf (ORCPT ); Wed, 16 May 2018 08:32:35 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8078C401EF09; Wed, 16 May 2018 12:32:34 +0000 (UTC) Received: from jason-ThinkPad-T450s.redhat.com (ovpn-12-64.pek2.redhat.com [10.72.12.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 03772215CDA7; Wed, 16 May 2018 12:32:29 +0000 (UTC) From: Jason Wang To: mst@redhat.com, jasowang@redhat.com Cc: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Subject: [RFC V4 PATCH 1/8] vhost: move get_rx_bufs to vhost.c Date: Wed, 16 May 2018 20:32:14 +0800 Message-Id: <1526473941-16199-2-git-send-email-jasowang@redhat.com> In-Reply-To: <1526473941-16199-1-git-send-email-jasowang@redhat.com> References: <1526473941-16199-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 16 May 2018 12:32:34 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 16 May 2018 12:32:34 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jasowang@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/vhost/net.c | 83 ++------------------------------------------------- drivers/vhost/vhost.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 7 +++++ 3 files changed, 88 insertions(+), 80 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 986058a..762aa81 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -664,83 +664,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) @@ -790,9 +713,9 @@ static void handle_rx(struct vhost_net *net) while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk))) { sock_len += sock_hlen; vhost_len = sock_len + vhost_hlen; - headcount = get_rx_bufs(vq, vq->heads + nheads, vhost_len, - &in, vq_log, &log, - likely(mergeable) ? UIO_MAXIOV : 1); + headcount = vhost_get_bufs(vq, vq->heads + nheads, vhost_len, + &in, vq_log, &log, + likely(mergeable) ? UIO_MAXIOV : 1); /* On error, stop handling until the next kick. */ if (unlikely(headcount < 0)) goto out; diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index f3bd8e9..6b455f6 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -2097,6 +2097,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