Received: by 10.223.164.202 with SMTP id h10csp4441096wrb; Wed, 29 Nov 2017 06:29:14 -0800 (PST) X-Google-Smtp-Source: AGs4zMZc1RKcYQyAx9uAUg7ixjUzKWL169Ru9K+RlH0ec1MIpt9oQDBoAvub280B64SVSF+2BhFp X-Received: by 10.98.69.209 with SMTP id n78mr3196393pfi.28.1511965754344; Wed, 29 Nov 2017 06:29:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511965754; cv=none; d=google.com; s=arc-20160816; b=zBN5qyRdGHrUEDAow1uYCz2PlIiq9W+h1uWsIL6J/zMxlFFY+N6j222EJqDu4hzEAS YK0JOHslgg+KzLzSmAACSViwDAO73kAUXhwcGUhvD2XsaWv1xIwfPXnGWh0O+uaQQ4tx QjK4zXJ9QZBIgb75IxSfodIPqtuEhfd//zOSau98I9n4gprA1CNJQlwuIMxqMoZtRjnP QPI//zDK/03Rmec0uy30PsT4lZKiZDJVsjctJ52GJVyvgvQuhQnMXZA6aIOrLx5fcDmD You2a8Fi9r11vbZQqgljJBSC1hQZWhCpOwmhjhpzyxcaR+LH0TODtEexp9YhS7d+SWBA VPkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=pcM537EPfHo2ghVcDIzEHbkI9AJreiEX3ENy+Ts8Tqw=; b=bUvYzsSvoJ7oKS/njmdtYZMBOWFFRu1LKS5V0ec1n/O1Xy6ECNQixnmkHW30NAfdbz 3HPo+49aliNWIOOsys7nPpQ+xT6UHrP4i1sn0rnacoZtu9dHvAco03jACu7PJtDb8ukO 6Ivs0h5DPLTtoQcXJonvS3TRr+VA5X2C+5AQEZOqvMD3SpzD2fo0QVN7uxr9LiTj1HrR uTXN+FJAKYSohaS5qcdV45HTtNOUVAwzsGQZ4ngMJqH0w2Sfuisu/u7WrNKtxDsQ+b9Q auObfgvEXpVnV2nVK9UlKHV6tDXAbCIkprjhM9sECd/3KG/lAss1AqiZBenwThnYulqG 8qOA== 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 g9si1317217plo.675.2017.11.29.06.29.03; Wed, 29 Nov 2017 06:29:14 -0800 (PST) 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 S1755095AbdK2OXk (ORCPT + 70 others); Wed, 29 Nov 2017 09:23:40 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43082 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752908AbdK2OXi (ORCPT ); Wed, 29 Nov 2017 09:23:38 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7F1A0356F1; Wed, 29 Nov 2017 14:23:38 +0000 (UTC) Received: from hp-bl660cgen9-01.khw.lab.eng.bos.redhat.com (hp-bl660cgen9-01.khw.lab.eng.bos.redhat.com [10.16.184.190]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8996D5C670; Wed, 29 Nov 2017 14:23:33 +0000 (UTC) From: wexu@redhat.com To: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: jasowang@redhat.com, mst@redhat.com, mjrosato@linux.vnet.ibm.com, wexu@redhat.com Subject: [PATCH net,stable v2] vhost: fix skb leak in handle_rx() Date: Wed, 29 Nov 2017 09:23:24 -0500 Message-Id: <1511965404-23289-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 29 Nov 2017 14:23:38 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wei Xu Matthew found a roughly 40% tcp throughput regression with commit c67df11f(vhost_net: try batch dequing from skb array) as discussed in the following thread: https://www.mail-archive.com/netdev@vger.kernel.org/msg187936.html Eventually we figured out that it was a skb leak in handle_rx() when sending packets to the VM. This usually happens when a guest can not drain out vq as fast as vhost fills in, afterwards it sets off the traffic jam and leaks skb(s) which occurs as no headcount to send on the vq from vhost side. This can be avoided by making sure we have got enough headcount before actually consuming a skb from the batched rx array while transmitting, which is simply done by moving checking the zero headcount a bit ahead. Also strengthen the small possibility of leak in case of recvmsg() fails by freeing the skb. Signed-off-by: Wei Xu Reported-by: Matthew Rosato --- drivers/vhost/net.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) v2: - add Matthew as the reporter, thanks matthew. - moving zero headcount check ahead instead of defer consuming skb due to jason and mst's comment. - add freeing skb in favor of recvmsg() fails. diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 8d626d7..e302e08 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -778,16 +778,6 @@ static void handle_rx(struct vhost_net *net) /* On error, stop handling until the next kick. */ if (unlikely(headcount < 0)) goto out; - if (nvq->rx_array) - msg.msg_control = vhost_net_buf_consume(&nvq->rxq); - /* On overrun, truncate and discard */ - if (unlikely(headcount > UIO_MAXIOV)) { - iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1); - err = sock->ops->recvmsg(sock, &msg, - 1, MSG_DONTWAIT | MSG_TRUNC); - pr_debug("Discarded rx packet: len %zd\n", sock_len); - continue; - } /* OK, now we need to know about added descriptors. */ if (!headcount) { if (unlikely(vhost_enable_notify(&net->dev, vq))) { @@ -800,6 +790,18 @@ static void handle_rx(struct vhost_net *net) * they refilled. */ goto out; } + if (nvq->rx_array) + msg.msg_control = vhost_net_buf_consume(&nvq->rxq); + /* On overrun, truncate and discard */ + if (unlikely(headcount > UIO_MAXIOV)) { + iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1); + err = sock->ops->recvmsg(sock, &msg, + 1, MSG_DONTWAIT | MSG_TRUNC); + if (unlikely(err != 1)) + kfree_skb((struct sk_buff *)msg.msg_control); + pr_debug("Discarded rx packet: len %zd\n", sock_len); + continue; + } /* We don't need to be notified again. */ iov_iter_init(&msg.msg_iter, READ, vq->iov, in, vhost_len); fixup = msg.msg_iter; @@ -818,6 +820,7 @@ static void handle_rx(struct vhost_net *net) pr_debug("Discarded rx packet: " " len %d, expected %zd\n", err, sock_len); vhost_discard_vq_desc(vq, headcount); + kfree_skb((struct sk_buff *)msg.msg_control); continue; } /* Supply virtio_net_hdr if VHOST_NET_F_VIRTIO_NET_HDR */ -- 1.8.3.1 From 1585379696327772297@xxx Wed Nov 29 06:11:38 +0000 2017 X-GM-THRID: 1585331132080725538 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread