From patchwork Wed Aug 31 18:06:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 664641 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3sPYHX25wqz9sCY for ; Thu, 1 Sep 2016 04:06:48 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id A454110996; Wed, 31 Aug 2016 11:06:25 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id C65201098B for ; Wed, 31 Aug 2016 11:06:23 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id 5B267420122 for ; Wed, 31 Aug 2016 12:06:23 -0600 (MDT) X-ASG-Debug-ID: 1472666782-09eadd33575a9b0001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id EwqDf1HdnsO9Qec8 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 31 Aug 2016 12:06:22 -0600 (MDT) X-Barracuda-Envelope-From: joe@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO relay3-d.mail.gandi.net) (217.70.183.195) by mx1-pf2.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 31 Aug 2016 18:06:22 -0000 Received-SPF: pass (mx1-pf2.cudamail.com: SPF record at ovn.org designates 217.70.183.195 as permitted sender) X-Barracuda-Apparent-Source-IP: 217.70.183.195 X-Barracuda-RBL-IP: 217.70.183.195 Received: from mfilter16-d.gandi.net (mfilter16-d.gandi.net [217.70.178.144]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id 28EB9A80C0; Wed, 31 Aug 2016 20:06:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter16-d.gandi.net Received: from relay3-d.mail.gandi.net ([IPv6:::ffff:217.70.183.195]) by mfilter16-d.gandi.net (mfilter16-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id ttDeYY_fTWg9; Wed, 31 Aug 2016 20:06:19 +0200 (CEST) X-Originating-IP: 208.91.1.34 Received: from archer.eng.vmware.com (unknown [208.91.1.34]) (Authenticated sender: joe@ovn.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 2078CA80DF; Wed, 31 Aug 2016 20:06:17 +0200 (CEST) X-CudaMail-Envelope-Sender: joe@ovn.org From: Joe Stringer To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-830053167 X-CudaMail-DTE: 083116 X-CudaMail-Originating-IP: 217.70.183.195 Date: Wed, 31 Aug 2016 11:06:05 -0700 X-ASG-Orig-Subj: [##CM-E2-830053167##][PATCHv2 4/4] upcall: Replace ukeys for deleted flows. Message-Id: <20160831180605.20969-5-joe@ovn.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160831180605.20969-1-joe@ovn.org> References: <20160831180605.20969-1-joe@ovn.org> X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1472666782 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCHv2 4/4] upcall: Replace ukeys for deleted flows. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" If a revalidator dumps/revalidates a flow during the 'dump' phase, resulting in the deletion of the flow, then ukey->flow_exists is set to false, and the ukey is kept around until the 'sweep' phase. The ukey is kept around to ensure that cases like duplicated dumps from the datapaths do not result in multiple attribution of the same stats. However, if an upcall for this flow comes for a handler between the revalidator 'dump' and 'sweep' phases, the handler will lookup the ukey and find that the ukey exists, then skip installing a new flow entirely. As a result, for this period all traffic for the flow is slowpathed. If there is a lot of traffic hitting this flow, then it will all be handled in userspace until the 'sweep' phase. Eventually the revalidators will reach the sweep phase and delete the ukey, and subsequently the handlers should install a new flow. To reduce the slowpathing of this traffic during flow table transitions, allow the handler to identify this case during miss upcall handling and replace the existing ukey with a new ukey. The handler will then be able to install a flow for this traffic, allowing the traffic flow to return to the fastpath. Signed-off-by: Joe Stringer Acked-by: Jarno Rajahalme --- v2: Rebase against ukey lifecycle patch. --- ofproto/ofproto-dpif-upcall.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index ce5a392caf78..04873cc42fff 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -50,6 +50,7 @@ COVERAGE_DEFINE(dumped_duplicate_flow); COVERAGE_DEFINE(dumped_new_flow); COVERAGE_DEFINE(handler_duplicate_upcall); COVERAGE_DEFINE(upcall_ukey_contention); +COVERAGE_DEFINE(upcall_ukey_replace); COVERAGE_DEFINE(revalidate_missed_dp_flow); /* A thread that reads upcalls from dpif, forwards each upcall's packet, @@ -1568,6 +1569,36 @@ ukey_create_from_dpif_flow(const struct udpif *udpif, return 0; } +static bool +try_ukey_replace(struct umap *umap, struct udpif_key *old_ukey, + struct udpif_key *new_ukey) + OVS_REQUIRES(umap->mutex) + OVS_TRY_LOCK(true, new_ukey->mutex) +{ + bool replaced = false; + + if (!ovs_mutex_trylock(&old_ukey->mutex)) { + if (old_ukey->state == UKEY_EVICTED) { + COVERAGE_INC(upcall_ukey_replace); + + /* The flow was deleted during the current revalidator dump, + * but its ukey won't be fully cleaned up until the sweep phase. + * In the mean time, we are receiving upcalls for this traffic. + * Expedite the (new) flow install by replacing the ukey. */ + ovs_mutex_lock(&new_ukey->mutex); + cmap_replace(&umap->cmap, &old_ukey->cmap_node, + &new_ukey->cmap_node, new_ukey->hash); + ovsrcu_postpone(ukey_delete__, old_ukey); + transition_ukey(old_ukey, UKEY_DELETED); + transition_ukey(new_ukey, UKEY_VISIBLE); + replaced = true; + } + ovs_mutex_unlock(&old_ukey->mutex); + } + + return replaced; +} + /* Attempts to insert a ukey into the shared ukey maps. * * On success, returns true, installs the ukey and returns it in a locked @@ -1590,6 +1621,7 @@ ukey_install__(struct udpif *udpif, struct udpif_key *new_ukey) if (old_ukey->key_len == new_ukey->key_len && !memcmp(old_ukey->key, new_ukey->key, new_ukey->key_len)) { COVERAGE_INC(handler_duplicate_upcall); + locked = try_ukey_replace(umap, old_ukey, new_ukey); } else { struct ds ds = DS_EMPTY_INITIALIZER;