From patchwork Mon Dec 2 13:44:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Flavio Leitner X-Patchwork-Id: 1203162 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=sysclose.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sysclose.org header.i=@sysclose.org header.b="oowVnxC7"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=sysclose.org header.i=@sysclose.org header.b="leaf2Tz8"; dkim-atps=neutral Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47RRF90bF4z9sPc for ; Tue, 3 Dec 2019 00:45:01 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 967A48821D; Mon, 2 Dec 2019 13:44:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SmqGEZPR7+tr; Mon, 2 Dec 2019 13:44:59 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 2BE99881CC; Mon, 2 Dec 2019 13:44:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0E18BC1DD9; Mon, 2 Dec 2019 13:44:59 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id C10D5C087F for ; Mon, 2 Dec 2019 13:44:57 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id AFC3E2078D for ; Mon, 2 Dec 2019 13:44:57 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PebsqWgbS4-Q for ; Mon, 2 Dec 2019 13:44:55 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sysclose.org (smtp.sysclose.org [69.164.214.230]) by silver.osuosl.org (Postfix) with ESMTPS id 7D8522094C for ; Mon, 2 Dec 2019 13:44:55 +0000 (UTC) Received: by sysclose.org (Postfix, from userid 5001) id 8B7E93052; Mon, 2 Dec 2019 13:45:11 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 8B7E93052 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294311; bh=Z4ND0ntFzCUJI1/b02TnlYiueXlTLzNsQeJCOihtM5Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oowVnxC7Zwo5dYztWe7plNJCcOo+ez1ij+1/nunGZcHcwN3JNiIDall7tfJOY70TG yZtD1X+pGjdSCKpNGFsWZE+s6raRSPZnhR27XHFu9uuYgYsfBmTRxgBsuAGHT+G6Rz jIBZm8EMxUF3yoIMrFyVzBLD7f5tb/hWfSjEBLL0qd2JuNa3pzRcqi81fsGUpYPjkw oJudJ6mvDd+xpb3msK++0Y7FbuOXa9MzmWjDcYWmD22lnt6biqQ9RlC+Ocsw/qQVrv rFDNPx18j50DSvNvwdzzg+adFMeY/iCxYB2mzvKmnWIn1t4xZw7Y5HOCVqryF/cb80 Y37BefAedV7Rw== Received: from localhost (unknown [45.71.104.69]) by sysclose.org (Postfix) with ESMTPSA id 79F8B181; Mon, 2 Dec 2019 13:45:10 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 79F8B181 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294310; bh=Z4ND0ntFzCUJI1/b02TnlYiueXlTLzNsQeJCOihtM5Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=leaf2Tz8HEfqQ120NfcMMwMu7qW6HtE/y0llhYoIp18miAuiE0c1/zzXB781hprEa 2JUjBTmOWGaYOJeqwoVztrTgg6kcPPkT0Lxlz+aAEvehBvWsRgLFDkR6AsroZlw9jL 0fPYC6fS35yK5XUwWCrqT/425JxFIIf70xuxLzIbQehDKdrEIuVJik8xKdVkIR99Jo V6ja1L41upzThs5GuLfalFqkkO2msxlV7NqB69t4bybNAsndbq7PDTBgZjpLj9/gpY u//fN8oWXjqCB1cvBH/mQVkAswz+/iKAyqsfy0XAr6RWeGOsSLgu8U3nKhh+dv9vST Dv/9cgYOpw4rA== From: Flavio Leitner To: dev@openvswitch.org Date: Mon, 2 Dec 2019 10:44:23 -0300 Message-Id: <20191202134426.2220333-2-fbl@sysclose.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191202134426.2220333-1-fbl@sysclose.org> References: <20191202134426.2220333-1-fbl@sysclose.org> MIME-Version: 1.0 Cc: Flavio Leitner Subject: [ovs-dev] [PATCH 1/4] dp-packet: preserve headroom when cloning a pkt batch X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" The headroom is useful if the packet needs to insert additional header, so preserve the original headroom when cloning the batch. Signed-off-by: Flavio Leitner --- lib/dp-packet.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 14f0897fa..1e5362304 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -874,7 +874,11 @@ dp_packet_batch_clone(struct dp_packet_batch *dst, dp_packet_batch_init(dst); DP_PACKET_BATCH_FOR_EACH (i, packet, src) { - dp_packet_batch_add(dst, dp_packet_clone(packet)); + uint32_t headroom = dp_packet_headroom(packet); + struct dp_packet *pkt_clone; + + pkt_clone = dp_packet_clone_with_headroom(packet, headroom); + dp_packet_batch_add(dst, pkt_clone); } dst->trunc = src->trunc; } From patchwork Mon Dec 2 13:44:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Flavio Leitner X-Patchwork-Id: 1203163 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=sysclose.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sysclose.org header.i=@sysclose.org header.b="YEBrXDkt"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=sysclose.org header.i=@sysclose.org header.b="StGONLN6"; dkim-atps=neutral Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47RRFH0HP1z9sPc for ; Tue, 3 Dec 2019 00:45:06 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1B6EF83604; Mon, 2 Dec 2019 13:45:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OBdkQKEI2CCK; Mon, 2 Dec 2019 13:45:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id E54D7834A3; Mon, 2 Dec 2019 13:45:03 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id DC858C1798; Mon, 2 Dec 2019 13:45:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 71D9CC087F for ; Mon, 2 Dec 2019 13:45:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 680CA88246 for ; Mon, 2 Dec 2019 13:45:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7VwRM2n9QSd9 for ; Mon, 2 Dec 2019 13:45:01 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sysclose.org (smtp.sysclose.org [69.164.214.230]) by hemlock.osuosl.org (Postfix) with ESMTPS id BFE2988216 for ; Mon, 2 Dec 2019 13:45:01 +0000 (UTC) Received: by sysclose.org (Postfix, from userid 5001) id B00043052; Mon, 2 Dec 2019 13:45:17 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org B00043052 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294317; bh=oozOH/PZa16K9OU5GaaKGpcj35kzejgU9X6KcrRiQTY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YEBrXDktK/ntQG/BYnNZcSHVXbLp8c8W4PAyG2pDOvVLa0rCsqSN97t1T7FgH01xV axpfXSdOX5ff/MpI4joF16aJj1kkNlYtQeX44Xhskjw+RLIXT80Es8ezJuNhKEqs+N DvZz3uBJKRmIJvdJHhZWboLtcyjuaaAP0reEevlQSj5l/1UnPRgpWdkJ2NHhZnz3u4 hkiPH/Lds3zyn4L14rcvoxAYZ/in5Mb3ZcPl7NUkySFVuAnjtuX6ZtIfjwyPan/P7l 3DZsGC0DhBGuyLLaJoQK6+n+OuIcfRSm4xZo59wZFxCuiSJRzhlVfLS7IInpyb4bdH xkS0NBUjB9eYw== Received: from localhost (unknown [45.71.104.69]) by sysclose.org (Postfix) with ESMTPSA id 566CE181; Mon, 2 Dec 2019 13:45:16 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 566CE181 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294316; bh=oozOH/PZa16K9OU5GaaKGpcj35kzejgU9X6KcrRiQTY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=StGONLN6ugEfAaCWynuRIuxAZEiCZpOANpRZlJ4tyFpZ3HfGb3/DA8sZc+mWZpa7j ruwkH3GeeUKCkg/iaI+c/LwNA4i+JadulJfkmoLt0Il37HlFkwqEf6v4Ig/Hml/b2p Qm+RP7SCEWq7QD7YClBfub2k3qd/eMgZj49RfeAF6FRJwFhgJCTyCX6YRIG42To8TS W0I/S20rhJFP1UL8PrqzxtHP2eZogPxpY3QboWnebt3uoKTRxD4tkmppH93NREI70+ A7ai8qWYAOXiDsCG5NF+216Ap0Ei4FtRS7hSavjqSniT/hkQxOS+wfWfk6zCiwLlBN gka1ZYEEhNv7w== From: Flavio Leitner To: dev@openvswitch.org Date: Mon, 2 Dec 2019 10:44:24 -0300 Message-Id: <20191202134426.2220333-3-fbl@sysclose.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191202134426.2220333-1-fbl@sysclose.org> References: <20191202134426.2220333-1-fbl@sysclose.org> MIME-Version: 1.0 Cc: Flavio Leitner Subject: [ovs-dev] [PATCH 2/4] vhost: Disable multi-segmented buffers X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" There is no support for multi-segmented buffers, so flag that to vhost library. Signed-off-by: Flavio Leitner --- lib/netdev-dpdk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 2423d26ee..cd035f76e 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -4355,6 +4355,9 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) /* Register client-mode device. */ vhost_flags |= RTE_VHOST_USER_CLIENT; + /* There is no support for multi-segments buffers */ + vhost_flags |= RTE_VHOST_USER_LINEARBUF_SUPPORT; + /* Enable IOMMU support, if explicitly requested. */ if (dpdk_vhost_iommu_enabled()) { vhost_flags |= RTE_VHOST_USER_IOMMU_SUPPORT; From patchwork Mon Dec 2 13:44:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Flavio Leitner X-Patchwork-Id: 1203164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=sysclose.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sysclose.org header.i=@sysclose.org header.b="VZyCJl6B"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=sysclose.org header.i=@sysclose.org header.b="Cfm6Etd0"; dkim-atps=neutral Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47RRFN4ySyz9sPc for ; Tue, 3 Dec 2019 00:45:12 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 35FEE88253; Mon, 2 Dec 2019 13:45:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id scrXeOVvWY+w; Mon, 2 Dec 2019 13:45:10 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id BBD47881D9; Mon, 2 Dec 2019 13:45:10 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A5B5CC1798; Mon, 2 Dec 2019 13:45:10 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6C74FC087F for ; Mon, 2 Dec 2019 13:45:08 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 5B44D214EB for ; Mon, 2 Dec 2019 13:45:08 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SRTZOCTPg1pA for ; Mon, 2 Dec 2019 13:45:07 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sysclose.org (smtp.sysclose.org [69.164.214.230]) by silver.osuosl.org (Postfix) with ESMTPS id 79557214D2 for ; Mon, 2 Dec 2019 13:45:07 +0000 (UTC) Received: by sysclose.org (Postfix, from userid 5001) id 7D3DE181; Mon, 2 Dec 2019 13:45:23 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 7D3DE181 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294323; bh=zgubtbMgN5AMKTde7xQymfGQMGACw/8OoQ9mfmcMrdk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VZyCJl6Bq7fiWkJQdWtuiRdWKdGG+7mvYv/sHTK06q3dNjjGGF2hXia4hmAinzx6v +c0qKUh7IeRjA7E0YPNP4yE7OhIStsJNnn1mECgoVsyMOM73qFN0l22mbhKyVbdyXX O0i0a380bI++wMlmUUhhdE4g25c4Kj08hB1jekg7ie5P2LWLwpwUMCYQYWraQE4w5L 31G0mUaXTfxsq6o2UQ3Mnh6fbAP1It3TetHotmXesgWTk1AGilxRu1dJfPUmCEx0UN JY9QLr8Imf33GgTcMfiI5/OStbK3TVSf2Ce/5GPq9QG3IHierNZQLgQjflbxZCoICt kwVpmHCiE/kBg== Received: from localhost (unknown [45.71.104.69]) by sysclose.org (Postfix) with ESMTPSA id 16E22303C; Mon, 2 Dec 2019 13:45:20 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 16E22303C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294321; bh=zgubtbMgN5AMKTde7xQymfGQMGACw/8OoQ9mfmcMrdk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cfm6Etd0lueiJo1hwfn0sMzHR2MiO9np4jcgXdNv4KgnST6Fk3GyEoYuVMeaulm8y QBST6lPDDG55C1xeH03rvPWn4P+LJlbp+aOi3i2TotoaKiHKbILiKGrtPafPXnCn4C 60dK6/gdcFpl8Y7XEqM2Un8ZzmANvO9h8fCHU7qycPL7eZmADCmB5BZApR1xiElHh3 QyVIYIcWvBzrt1zVetPouc9PAXT3YNi2jeZLHm7DoI0PKuIjBR7qhOMORAU4g5I/t9 PVCNsKTPCD+/nOrLXqQqTpGr7cdrq8zGWX3GgmojTRq4iD9mxF7/3oBTXK+rXSjoJs Gw+YsFiu9F0Ag== From: Flavio Leitner To: dev@openvswitch.org Date: Mon, 2 Dec 2019 10:44:25 -0300 Message-Id: <20191202134426.2220333-4-fbl@sysclose.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191202134426.2220333-1-fbl@sysclose.org> References: <20191202134426.2220333-1-fbl@sysclose.org> MIME-Version: 1.0 Cc: Flavio Leitner Subject: [ovs-dev] [PATCH 3/4] dp-packet: handle new dpdk buffer flags X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" DPDK included a couple flags EXT_ATTACHED_MBUF and IND_ATTACHED_MBUF which are not really offloading flags, so this patch fixes to reset only offloading flags or to reset only those flags when needed. Signed-off-by: Flavio Leitner --- lib/dp-packet.c | 4 +++- lib/dp-packet.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/dp-packet.c b/lib/dp-packet.c index 62d7faa4c..e02891449 100644 --- a/lib/dp-packet.c +++ b/lib/dp-packet.c @@ -193,7 +193,9 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom) offsetof(struct dp_packet, l2_pad_size)); #ifdef DPDK_NETDEV - new_buffer->mbuf.ol_flags = buffer->mbuf.ol_flags; + /* The new packet is linear, so copy only the offloading flags */ + new_buffer->mbuf.ol_flags = buffer->mbuf.ol_flags + & ~(EXT_ATTACHED_MBUF | IND_ATTACHED_MBUF); #endif if (dp_packet_rss_valid(buffer)) { diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 1e5362304..325924eaa 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -538,7 +538,7 @@ dp_packet_rss_valid(const struct dp_packet *p) static inline void dp_packet_reset_offload(struct dp_packet *p) { - p->mbuf.ol_flags = 0; + p->mbuf.ol_flags &= (EXT_ATTACHED_MBUF | IND_ATTACHED_MBUF); } static inline bool From patchwork Mon Dec 2 13:44:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Flavio Leitner X-Patchwork-Id: 1203165 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=sysclose.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sysclose.org header.i=@sysclose.org header.b="aJrfmJl5"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=sysclose.org header.i=@sysclose.org header.b="VyelcVwL"; dkim-atps=neutral Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47RRFc1CG8z9sPJ for ; Tue, 3 Dec 2019 00:45:24 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 9C93C83511; Mon, 2 Dec 2019 13:45:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AzMLgIwM2rCc; Mon, 2 Dec 2019 13:45:19 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id D038F832F8; Mon, 2 Dec 2019 13:45:19 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B384AC1DD6; Mon, 2 Dec 2019 13:45:19 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 11F18C1798 for ; Mon, 2 Dec 2019 13:45:18 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 01044834A0 for ; Mon, 2 Dec 2019 13:45:18 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id L9pc66xLTiWi for ; Mon, 2 Dec 2019 13:45:16 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sysclose.org (smtp.sysclose.org [69.164.214.230]) by fraxinus.osuosl.org (Postfix) with ESMTPS id E5B50834E3 for ; Mon, 2 Dec 2019 13:45:15 +0000 (UTC) Received: by sysclose.org (Postfix, from userid 5001) id D8A723E52; Mon, 2 Dec 2019 13:45:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org D8A723E52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294331; bh=GA4O9R1HjgRJvoECIVFirVl7mEnD/vqKt/7ND0cng50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aJrfmJl56gJ2gYlgL8zl1BXE9KfsuNuV1JqYTu9Al6MiW0171NoxAdudZVqihtagV RvAdOZBYAGD0w9SM/cjZ7cFijLqyOoNdiwN+943qb1xRl1h3IIoi8HFm76vE1GKL5c UWWSgg2vfZdosgPSnF2/OtsXlXvCpFgpmeKzEAu3iRbxjoi4HIi14gSMKIsYpoUppf KGiMHUO13KE/TeAzTIYhVvXgI8qYbbizH1CxspYAWX1ZUaaSvyc9VDjRE9wiGrk7H3 E6QOnNX1OR+T1z83kNWhoY5JVWHHpIudAuFBPqkZCmwawUMo54ZavjE08t6DmctqO1 wer98HzpjDD6w== Received: from localhost (unknown [45.71.104.69]) by sysclose.org (Postfix) with ESMTPSA id 1C2CE181; Mon, 2 Dec 2019 13:45:26 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 sysclose.org 1C2CE181 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysclose.org; s=201903; t=1575294327; bh=GA4O9R1HjgRJvoECIVFirVl7mEnD/vqKt/7ND0cng50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VyelcVwLdbPGuGc1fbcC2lIQz1QhUR05Mg9QY5lpT+OmaOPVkSebTheMqGaFmYKbh xvF9rk7I9+7IQKZnnNs4QBQ44DPC+jB1U9yP3DZJwxD6L3LAu02HvrlRdESIjrjwse 1VHD24tnLHUQLZn5Ukoh5K8AL3q+LUcDex8xnZQcxXWj/+VD1EwChnShhR8n2VG3Ad Qs7FDhp53yQt7lMzy9kttHH+e+1P803srwLNaUR+t6aadKRRbLacrKiVX0Vyc8U7hs xd9FWECIEbnsG7Eyh6sbnnfAXH3zCUhjKEzH1BGAFc6sk3dEujfiKc/itQn+EjQY8n xP1PjzL6MmBvQ== From: Flavio Leitner To: dev@openvswitch.org Date: Mon, 2 Dec 2019 10:44:26 -0300 Message-Id: <20191202134426.2220333-5-fbl@sysclose.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191202134426.2220333-1-fbl@sysclose.org> References: <20191202134426.2220333-1-fbl@sysclose.org> MIME-Version: 1.0 Cc: Flavio Leitner Subject: [ovs-dev] [PATCH 4/4] netdev-dpdk: Add TCP Segmentation Offload support X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Abbreviated as TSO, TCP Segmentation Offload is a feature which enables the network stack to delegate the TCP segmentation to the NIC reducing the per packet CPU overhead. A guest using vhostuser interface with TSO enabled can send TCP packets much bigger than the MTU, which saves CPU cycles normally used to break the packets down to MTU size and to calculate checksums. It also saves CPU cycles used to parse multiple packets/headers during the packet processing inside virtual switch. If the destination of the packet is another guest in the same host, then the same big packet can be sent through a vhostuser interface skipping the segmentation completely. However, if the destination is not local, the NIC hardware is instructed to do the TCP segmentation and checksum calculation. It is recommended to check if NIC hardware supports TSO before enabling the feature, which is off by default. Signed-off-by: Flavio Leitner --- Documentation/automake.mk | 1 + Documentation/topics/dpdk/index.rst | 1 + Documentation/topics/dpdk/tso.rst | 83 +++++++++++++++++++++ NEWS | 1 + lib/automake.mk | 2 + lib/dp-packet.c | 46 ++++++++++++ lib/dp-packet.h | 30 ++++++-- lib/netdev-bsd.c | 7 ++ lib/netdev-dpdk.c | 109 +++++++++++++++++++++++----- lib/netdev-dummy.c | 7 ++ lib/netdev-linux.c | 71 ++++++++++++++++-- lib/tso.c | 54 ++++++++++++++ lib/tso.h | 23 ++++++ vswitchd/bridge.c | 2 + vswitchd/vswitch.xml | 14 ++++ 15 files changed, 418 insertions(+), 33 deletions(-) create mode 100644 Documentation/topics/dpdk/tso.rst create mode 100644 lib/tso.c create mode 100644 lib/tso.h diff --git a/Documentation/automake.mk b/Documentation/automake.mk index 5f7c3e07b..abe5aaed1 100644 --- a/Documentation/automake.mk +++ b/Documentation/automake.mk @@ -35,6 +35,7 @@ DOC_SOURCE = \ Documentation/topics/dpdk/index.rst \ Documentation/topics/dpdk/bridge.rst \ Documentation/topics/dpdk/jumbo-frames.rst \ + Documentation/topics/dpdk/tso.rst \ Documentation/topics/dpdk/memory.rst \ Documentation/topics/dpdk/pdump.rst \ Documentation/topics/dpdk/phy.rst \ diff --git a/Documentation/topics/dpdk/index.rst b/Documentation/topics/dpdk/index.rst index f2862ea70..400d56051 100644 --- a/Documentation/topics/dpdk/index.rst +++ b/Documentation/topics/dpdk/index.rst @@ -40,4 +40,5 @@ DPDK Support /topics/dpdk/qos /topics/dpdk/pdump /topics/dpdk/jumbo-frames + /topics/dpdk/tso /topics/dpdk/memory diff --git a/Documentation/topics/dpdk/tso.rst b/Documentation/topics/dpdk/tso.rst new file mode 100644 index 000000000..92393a399 --- /dev/null +++ b/Documentation/topics/dpdk/tso.rst @@ -0,0 +1,83 @@ +.. + Copyright 2019, Red Hat, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + + Convention for heading levels in Open vSwitch documentation: + + ======= Heading 0 (reserved for the title in a document) + ------- Heading 1 + ~~~~~~~ Heading 2 + +++++++ Heading 3 + ''''''' Heading 4 + + Avoid deeper levels because they do not render well. + +=== +TSO +=== + +**Note:** This feature is considered experimental. + +TCP Segmentation Offload (TSO) enables a network stack to delegate segmentation +of an oversized TCP segment to the underlying physical NIC. Offload of frame +segmentation achieves computational savings in the core, freeing up CPU cycles +for more useful work. + +A common use case for TSO is when using virtualization, where traffic that's +coming in from a VM can offload the TCP segmentation, thus avoiding the +fragmentation in software. Additionally, if the traffic is headed to a VM +within the same host further optimization can be expected. As the traffic never +leaves the machine, no MTU needs to be accounted for, and thus no segmentation +and checksum calculations are required, which saves yet more cycles. Only when +the traffic actually leaves the host the segmentation needs to happen, in which +case it will be performed by the egress NIC. Consult your controller's datasheet +for compatibility. Secondly, the NIC must have an associated DPDK Poll Mode +Driver (PMD) which supports `TSO`. + +Enabling TSO +~~~~~~~~~~~~ + +The TSO support may be enabled via a global config value ``tso-support``. +Setting this to ``true`` enables TSO support for all ports. + + $ ovs-vsctl set Open_vSwitch . other_config:tso-support=true + +The default value is ``false``. + +When using :doc:`vHost User ports `, TSO may be enabled as follows. + +`TSO` is enabled in OvS by the DPDK vHost User backend; when a new guest +connection is established, `TSO` is thus advertised to the guest as an +available feature: + +QEMU Command Line Parameter:: + + $ sudo $QEMU_DIR/x86_64-softmmu/qemu-system-x86_64 \ + ... + -device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1,\ + csum=on,guest_csum=on,guest_tso4=on,guest_tso6=on\ + ... + +2. Ethtool. Assuming that the guest's OS also supports `TSO`, ethtool can be used to enable same:: + + $ ethtool -K eth0 sg on # scatter-gather is a prerequisite for TSO + $ ethtool -K eth0 tso on + $ ethtool -k eth0 + +~~~~~~~~~~~ +Limitations +~~~~~~~~~~~ +The current OvS `TSO` implementation supports flat and VLAN networks only (i.e. +no support for `TSO` over tunneled connection [VxLAN, GRE, IPinIP, etc.]). + diff --git a/NEWS b/NEWS index 0d65d5a7f..df32930bf 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ Post-v2.12.0 * DPDK pdump packet capture support disabled by default. New configure option '--enable-dpdk-pdump' to enable it. * DPDK pdump support is deprecated and will be removed in next releases. + * Add experimental support for TSO in vhost-user ports. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/automake.mk b/lib/automake.mk index 17b36b43d..01c54d7f3 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -302,6 +302,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/tnl-neigh-cache.h \ lib/tnl-ports.c \ lib/tnl-ports.h \ + lib/tso.c \ + lib/tso.h \ lib/netdev-native-tnl.c \ lib/netdev-native-tnl.h \ lib/token-bucket.c \ diff --git a/lib/dp-packet.c b/lib/dp-packet.c index e02891449..095f543f4 100644 --- a/lib/dp-packet.c +++ b/lib/dp-packet.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "dp-packet.h" #include "netdev-afxdp.h" @@ -509,3 +510,48 @@ dp_packet_resize_l2(struct dp_packet *b, int increment) dp_packet_adjust_layer_offset(&b->l2_5_ofs, increment); return dp_packet_data(b); } + +#ifdef DPDK_NETDEV +void +dp_packet_prepend_vnet_hdr(struct dp_packet *b, int mtu) +{ + struct virtio_net_hdr *vnet; + uint64_t ol_flags = b->mbuf.ol_flags; + + vnet = dp_packet_push_zeros(b, sizeof *vnet); + if ((ol_flags & PKT_TX_TCP_SEG) && (dp_packet_size(b) > vnet->gso_size)) { + + if (ol_flags & PKT_TX_IPV4) { + vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + vnet->hdr_len = ETH_HLEN + IP_HEADER_LEN + TCP_HEADER_LEN; + } else { + vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + vnet->hdr_len = ETH_HLEN + IPV6_HEADER_LEN + TCP_HEADER_LEN; + } + + vnet->gso_size = mtu - vnet->hdr_len; + } else { + vnet->flags = VIRTIO_NET_HDR_GSO_NONE; + } + + uint64_t tx_l4_mask = ol_flags & PKT_TX_L4_MASK; + if (tx_l4_mask) { + vnet->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + vnet->csum_start = (char *) dp_packet_l4(b) - (char *) dp_packet_eth(b); + + if (tx_l4_mask == PKT_TX_TCP_CKSUM) { + vnet->csum_offset = __builtin_offsetof(struct tcp_header, tcp_csum); + } else if (tx_l4_mask == PKT_TX_UDP_CKSUM) { + vnet->csum_offset = __builtin_offsetof(struct udp_header, udp_csum); + } else if (tx_l4_mask == PKT_TX_SCTP_CKSUM) { + vnet->csum_offset = __builtin_offsetof(struct sctp_header, + sctp_csum); + } + } +} +#else +void +dp_packet_prepend_vnet_hdr(struct dp_packet *b OVS_UNUSED, int mtu OVS_UNUSED) +{ +} +#endif diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 325924eaa..d962daa4b 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -109,6 +109,9 @@ static inline void dp_packet_set_size(struct dp_packet *, uint32_t); static inline uint16_t dp_packet_get_allocated(const struct dp_packet *); static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t); +static inline bool dp_packet_is_tso(struct dp_packet *b); +void dp_packet_prepend_vnet_hdr(struct dp_packet *, int mtu); + void *dp_packet_resize_l2(struct dp_packet *, int increment); void *dp_packet_resize_l2_5(struct dp_packet *, int increment); static inline void *dp_packet_eth(const struct dp_packet *); @@ -451,7 +454,7 @@ dp_packet_init_specific(struct dp_packet *p) { /* This initialization is needed for packets that do not come from DPDK * interfaces, when vswitchd is built with --with-dpdk. */ - p->mbuf.tx_offload = p->mbuf.packet_type = 0; + p->mbuf.ol_flags = p->mbuf.tx_offload = p->mbuf.packet_type = 0; p->mbuf.nb_segs = 1; p->mbuf.next = NULL; } @@ -514,6 +517,14 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s) b->mbuf.buf_len = s; } +static inline bool +dp_packet_is_tso(struct dp_packet *b) +{ + return (b->mbuf.ol_flags & (PKT_TX_TCP_SEG | PKT_TX_L4_MASK)) + ? true + : false; +} + /* Returns the RSS hash of the packet 'p'. Note that the returned value is * correct only if 'dp_packet_rss_valid(p)' returns true */ static inline uint32_t @@ -544,8 +555,10 @@ dp_packet_reset_offload(struct dp_packet *p) static inline bool dp_packet_ip_checksum_valid(const struct dp_packet *p) { - return (p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) == - PKT_RX_IP_CKSUM_GOOD; + + return (p->mbuf.ol_flags & PKT_TX_L4_MASK) + || ((p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) == + PKT_RX_IP_CKSUM_GOOD); } static inline bool @@ -558,8 +571,9 @@ dp_packet_ip_checksum_bad(const struct dp_packet *p) static inline bool dp_packet_l4_checksum_valid(const struct dp_packet *p) { - return (p->mbuf.ol_flags & PKT_RX_L4_CKSUM_MASK) == - PKT_RX_L4_CKSUM_GOOD; + return (p->mbuf.ol_flags & PKT_TX_L4_MASK) + || ((p->mbuf.ol_flags & PKT_RX_L4_CKSUM_MASK) == + PKT_RX_L4_CKSUM_GOOD); } static inline bool @@ -643,6 +657,12 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s) b->allocated_ = s; } +static inline bool +dp_packet_is_tso(struct dp_packet *b OVS_UNUSED) +{ + return false; +} + /* Returns the RSS hash of the packet 'p'. Note that the returned value is * correct only if 'dp_packet_rss_valid(p)' returns true */ static inline uint32_t diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 7875636cc..ad6669f9f 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -703,6 +703,13 @@ netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED, const void *data = dp_packet_data(packet); size_t size = dp_packet_size(packet); + /* No TSO support in BSD netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN("%s: Dropping unsupported TSO packet of size %"PRIuSIZE, + name, size); + continue; + } + while (!error) { ssize_t retval; if (dev->tap_fd >= 0) { diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index cd035f76e..0551a7921 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -63,6 +63,7 @@ #include "smap.h" #include "sset.h" #include "timeval.h" +#include "tso.h" #include "unaligned.h" #include "unixctl.h" #include "util.h" @@ -355,7 +356,8 @@ struct ingress_policer { enum dpdk_hw_ol_features { NETDEV_RX_CHECKSUM_OFFLOAD = 1 << 0, NETDEV_RX_HW_CRC_STRIP = 1 << 1, - NETDEV_RX_HW_SCATTER = 1 << 2 + NETDEV_RX_HW_SCATTER = 1 << 2, + NETDEV_TX_TSO_OFFLOAD = 1 << 3, }; /* @@ -935,6 +937,12 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) conf.rxmode.offloads |= DEV_RX_OFFLOAD_KEEP_CRC; } + if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO; + conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM; + conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM; + } + /* Limit configured rss hash functions to only those supported * by the eth device. */ conf.rx_adv_conf.rss_conf.rss_hf &= info.flow_type_rss_offloads; @@ -1036,6 +1044,9 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) uint32_t rx_chksm_offload_capa = DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM | DEV_RX_OFFLOAD_IPV4_CKSUM; + uint32_t tx_tso_offload_capa = DEV_TX_OFFLOAD_TCP_TSO | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_IPV4_CKSUM; rte_eth_dev_info_get(dev->port_id, &info); @@ -1062,6 +1073,14 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) dev->hw_ol_features &= ~NETDEV_RX_HW_SCATTER; } + if (info.tx_offload_capa & tx_tso_offload_capa) { + dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + } else { + dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + VLOG_WARN("Tx TSO offload is not supported on port " + DPDK_PORT_ID_FMT, dev->port_id); + } + n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq); n_txq = MIN(info.max_tx_queues, dev->up.n_txq); @@ -1307,14 +1326,16 @@ netdev_dpdk_vhost_construct(struct netdev *netdev) goto out; } - err = rte_vhost_driver_disable_features(dev->vhost_id, - 1ULL << VIRTIO_NET_F_HOST_TSO4 - | 1ULL << VIRTIO_NET_F_HOST_TSO6 - | 1ULL << VIRTIO_NET_F_CSUM); - if (err) { - VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " - "port: %s\n", name); - goto out; + if (!tso_enabled()) { + err = rte_vhost_driver_disable_features(dev->vhost_id, + 1ULL << VIRTIO_NET_F_HOST_TSO4 + | 1ULL << VIRTIO_NET_F_HOST_TSO6 + | 1ULL << VIRTIO_NET_F_CSUM); + if (err) { + VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " + "port: %s\n", name); + goto out; + } } err = rte_vhost_driver_start(dev->vhost_id); @@ -1649,6 +1670,11 @@ netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args) } else { smap_add(args, "rx_csum_offload", "false"); } + if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + smap_add(args, "tx_tso_offload", "true"); + } else { + smap_add(args, "tx_tso_offload", "false"); + } smap_add(args, "lsc_interrupt_mode", dev->lsc_interrupt_mode ? "true" : "false"); } @@ -2048,6 +2074,30 @@ netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq) rte_free(rx); } +/* Prepare the packet for transmit TSO. + * It should be called only if PKT_TX_TCP_SEG is set in ol_flags. + * The flags PKT_TX_TCP_CKSUM and PKT_TX_IP_CKSUM are also set. */ +static void +netdev_dpdk_prep_tso_packet(struct rte_mbuf *mbuf, int mtu) +{ + struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); + struct tcp_header *th = dp_packet_l4(pkt); + + mbuf->l2_len = (char *) dp_packet_l3(pkt) - (char *) dp_packet_eth(pkt); + mbuf->l3_len = (char *) dp_packet_l4(pkt) - (char *) dp_packet_l3(pkt); + /* There's no layer 4 in the packet. */ + if (!th) { + VLOG_WARN_RL(&rl, "TSO packet without L4 header"); + return; + } + + mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4; + mbuf->ol_flags |= PKT_TX_TCP_CKSUM | PKT_TX_IP_CKSUM; + mbuf->tso_segsz = mtu - mbuf->l3_len - mbuf->l4_len; + mbuf->outer_l2_len = 0; + mbuf->outer_l3_len = 0; +} + /* Tries to transmit 'pkts' to txq 'qid' of device 'dev'. Takes ownership of * 'pkts', even in case of failure. * @@ -2345,11 +2395,18 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, int cnt = 0; struct rte_mbuf *pkt; + /* Filter oversized packets, unless are marked for TSO. */ for (i = 0; i < pkt_cnt; i++) { pkt = pkts[i]; - if (OVS_UNLIKELY(pkt->pkt_len > dev->max_packet_len)) { - VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " max_packet_len %d", - dev->up.name, pkt->pkt_len, dev->max_packet_len); + if ((pkt->ol_flags & PKT_TX_TCP_SEG)) { + /* vhost user client doesn't require 'pkt' to be prepared */ + if (dev->type != DPDK_DEV_VHOST) { + netdev_dpdk_prep_tso_packet(pkt, dev->mtu); + } + } else if (OVS_UNLIKELY(pkt->pkt_len > dev->max_packet_len)) { + VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " " + "max_packet_len %d", dev->up.name, pkt->pkt_len, + dev->max_packet_len); rte_pktmbuf_free(pkt); continue; } @@ -4303,6 +4360,11 @@ dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev) dev->tx_q[0].map = 0; } + if (tso_enabled()) { + dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + VLOG_DBG("%s: TSO enabled on vhost port", dev->up.name); + } + netdev_dpdk_remap_txqs(dev); err = netdev_dpdk_mempool_configure(dev); @@ -4375,6 +4437,11 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) vhost_flags |= RTE_VHOST_USER_DEQUEUE_ZERO_COPY; } + /* Enable External Buffers if TCP Segmentation Offload is enabled */ + if (tso_enabled()) { + vhost_flags |= RTE_VHOST_USER_EXTBUF_SUPPORT; + } + err = rte_vhost_driver_register(dev->vhost_id, vhost_flags); if (err) { VLOG_ERR("vhost-user device setup failure for device %s\n", @@ -4399,14 +4466,16 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) goto unlock; } - err = rte_vhost_driver_disable_features(dev->vhost_id, - 1ULL << VIRTIO_NET_F_HOST_TSO4 - | 1ULL << VIRTIO_NET_F_HOST_TSO6 - | 1ULL << VIRTIO_NET_F_CSUM); - if (err) { - VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " - "client port: %s\n", dev->up.name); - goto unlock; + if (!tso_enabled()) { + err = rte_vhost_driver_disable_features(dev->vhost_id, + 1ULL << VIRTIO_NET_F_HOST_TSO4 + | 1ULL << VIRTIO_NET_F_HOST_TSO6 + | 1ULL << VIRTIO_NET_F_CSUM); + if (err) { + VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " + "client port: %s\n", dev->up.name); + goto unlock; + } } err = rte_vhost_driver_start(dev->vhost_id); diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 71df29184..6e86149d7 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -1108,6 +1108,13 @@ netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED, const void *buffer = dp_packet_data(packet); size_t size = dp_packet_size(packet); + /* TSO not supported in Dummy netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN("%s: Dropping unsupported TSO packet of size %"PRIuSIZE, + netdev_get_name(netdev), size); + continue; + } + if (!dp_packet_is_eth(packet)) { error = EPFNOSUPPORT; break; diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 0a32cf9bc..154bd7ac1 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -29,16 +29,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -72,6 +73,7 @@ #include "socket-util.h" #include "sset.h" #include "tc.h" +#include "tso.h" #include "timer.h" #include "unaligned.h" #include "openvswitch/vlog.h" @@ -961,6 +963,10 @@ netdev_linux_construct_tap(struct netdev *netdev_) /* Create tap device. */ get_flags(&netdev->up, &netdev->ifi_flags); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (tso_enabled()) { + ifr.ifr_flags |= IFF_VNET_HDR; + } + ovs_strzcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); if (ioctl(netdev->tap_fd, TUNSETIFF, &ifr) == -1) { VLOG_WARN("%s: creating tap device failed: %s", name, @@ -1069,6 +1075,17 @@ netdev_linux_rxq_construct(struct netdev_rxq *rxq_) goto error; } + if (tso_enabled()) { + error = setsockopt(rx->fd, SOL_PACKET, PACKET_VNET_HDR, &val, + sizeof val); + if (error) { + error = errno; + VLOG_ERR("%s: failed to enable vnet hdr in txq raw socket: %s", + netdev_get_name(netdev_), ovs_strerror(errno)); + goto error; + } + } + /* Set non-blocking mode. */ error = set_nonblocking(rx->fd); if (error) { @@ -1151,6 +1168,7 @@ auxdata_has_vlan_tci(const struct tpacket_auxdata *aux) return aux->tp_vlan_tci || aux->tp_status & TP_STATUS_VLAN_VALID; } + static int netdev_linux_rxq_recv_sock(int fd, struct dp_packet *buffer) { @@ -1245,6 +1263,7 @@ netdev_linux_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch, struct netdev_rxq_linux *rx = netdev_rxq_linux_cast(rxq_); struct netdev *netdev = rx->up.netdev; struct dp_packet *buffer; + size_t buffer_len; ssize_t retval; int mtu; @@ -1252,9 +1271,13 @@ netdev_linux_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch, mtu = ETH_PAYLOAD_MAX; } + buffer_len = VLAN_ETH_HEADER_LEN + mtu; + if (tso_enabled()) { + buffer_len += sizeof(struct virtio_net_hdr); + } + /* Assume Ethernet port. No need to set packet_type. */ - buffer = dp_packet_new_with_headroom(VLAN_ETH_HEADER_LEN + mtu, - DP_NETDEV_HEADROOM); + buffer = dp_packet_new_with_headroom(buffer_len, DP_NETDEV_HEADROOM); retval = (rx->is_tap ? netdev_linux_rxq_recv_tap(rx->fd, buffer) : netdev_linux_rxq_recv_sock(rx->fd, buffer)); @@ -1266,6 +1289,10 @@ netdev_linux_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch, } dp_packet_delete(buffer); } else { + if (tso_enabled()) { + dp_packet_pull(buffer, sizeof(struct virtio_net_hdr)); + } + dp_packet_batch_init_packet(batch, buffer); } @@ -1302,7 +1329,7 @@ netdev_linux_rxq_drain(struct netdev_rxq *rxq_) } static int -netdev_linux_sock_batch_send(int sock, int ifindex, +netdev_linux_sock_batch_send(int sock, int ifindex, bool tso, int mtu, struct dp_packet_batch *batch) { const size_t size = dp_packet_batch_size(batch); @@ -1316,6 +1343,10 @@ netdev_linux_sock_batch_send(int sock, int ifindex, struct dp_packet *packet; DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { + if (tso) { + dp_packet_prepend_vnet_hdr(packet, mtu); + } + iov[i].iov_base = dp_packet_data(packet); iov[i].iov_len = dp_packet_size(packet); mmsg[i].msg_hdr = (struct msghdr) { .msg_name = &sll, @@ -1348,7 +1379,7 @@ netdev_linux_sock_batch_send(int sock, int ifindex, * on other interface types because we attach a socket filter to the rx * socket. */ static int -netdev_linux_tap_batch_send(struct netdev *netdev_, +netdev_linux_tap_batch_send(struct netdev *netdev_, bool tso, int mtu, struct dp_packet_batch *batch) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); @@ -1365,10 +1396,15 @@ netdev_linux_tap_batch_send(struct netdev *netdev_, } DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { - size_t size = dp_packet_size(packet); + size_t size; ssize_t retval; int error; + if (tso) { + dp_packet_prepend_vnet_hdr(packet, mtu); + } + + size = dp_packet_size(packet); do { retval = write(netdev->tap_fd, dp_packet_data(packet), size); error = retval < 0 ? errno : 0; @@ -1403,9 +1439,15 @@ netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED, struct dp_packet_batch *batch, bool concurrent_txq OVS_UNUSED) { + bool tso = tso_enabled(); + int mtu = ETH_PAYLOAD_MAX; int error = 0; int sock = 0; + if (tso) { + netdev_linux_get_mtu__(netdev_linux_cast(netdev_), &mtu); + } + if (!is_tap_netdev(netdev_)) { if (netdev_linux_netnsid_is_remote(netdev_linux_cast(netdev_))) { error = EOPNOTSUPP; @@ -1424,9 +1466,9 @@ netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED, goto free_batch; } - error = netdev_linux_sock_batch_send(sock, ifindex, batch); + error = netdev_linux_sock_batch_send(sock, ifindex, tso, mtu, batch); } else { - error = netdev_linux_tap_batch_send(netdev_, batch); + error = netdev_linux_tap_batch_send(netdev_, tso, mtu, batch); } if (error) { if (error == ENOBUFS) { @@ -6170,6 +6212,19 @@ af_packet_sock(void) close(sock); sock = -error; } + + if (tso_enabled()) { + int val = 1; + error = setsockopt(sock, SOL_PACKET, PACKET_VNET_HDR, &val, + sizeof val); + if (error) { + error = errno; + VLOG_ERR("failed to enable vnet hdr in raw socket: %s", + ovs_strerror(errno)); + close(sock); + sock = -error; + } + } } else { sock = -errno; VLOG_ERR("failed to create packet socket: %s", diff --git a/lib/tso.c b/lib/tso.c new file mode 100644 index 000000000..2b062d14a --- /dev/null +++ b/lib/tso.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "smap.h" +#include "ovs-thread.h" +#include "openvswitch/vlog.h" +#include "dpdk.h" +#include "tso.h" +#include "vswitch-idl.h" + +VLOG_DEFINE_THIS_MODULE(tso); + +static bool tso_support_enabled = false; + +void +tso_init(const struct smap *ovs_other_config) +{ + if (smap_get_bool(ovs_other_config, "tso-support", false)) { + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + + if (ovsthread_once_start(&once)) { + if (dpdk_available()) { + VLOG_INFO("TCP Segmentation Offloading (TSO) support enabled"); + tso_support_enabled = true; + } else { + VLOG_ERR("TCP Segmentation Offloading (TSO) is unsupported " + "without enabling DPDK"); + tso_support_enabled = false; + } + ovsthread_once_done(&once); + } + } +} + +bool +tso_enabled(void) +{ + return tso_support_enabled; +} diff --git a/lib/tso.h b/lib/tso.h new file mode 100644 index 000000000..5cc6993f3 --- /dev/null +++ b/lib/tso.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Red Hat Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TSO_H +#define TSO_H 1 + +void tso_init(const struct smap *ovs_other_config); +bool tso_enabled(void); + +#endif /* tso.h */ diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 9095ebf5d..a1cd1c541 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -65,6 +65,7 @@ #include "system-stats.h" #include "timeval.h" #include "tnl-ports.h" +#include "tso.h" #include "util.h" #include "unixctl.h" #include "lib/vswitch-idl.h" @@ -3234,6 +3235,7 @@ bridge_run(void) if (cfg) { netdev_set_flow_api_enabled(&cfg->other_config); dpdk_init(&cfg->other_config); + tso_init(&cfg->other_config); } /* Initialize the ofproto library. This only needs to run once, but diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index efdfb83bb..69aec3154 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -690,6 +690,20 @@ once in few hours or a day or a week.

+ +

+ Set this value to true to enable support for TSO (TCP + Segmentation Offloading). When TSO is enabled, vhost-user client + interfaces can transmit packets up to 64KB which can be delivered + directly to other vhost-user client ports or to network cards with + TSO support. +

+

+ The default value is false. Changing this value requires + restarting the daemon +

+