From patchwork Tue Apr 9 16:03:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li,Rongqing via dev" X-Patchwork-Id: 1082465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=openvswitch.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44dsYr3cD4z9sSC for ; Wed, 10 Apr 2019 02:04:47 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8E1FA101D; Tue, 9 Apr 2019 16:04:45 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 065591014 for ; Tue, 9 Apr 2019 16:04:44 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from EX13-EDG-OU-001.vmware.com (ex13-edg-ou-001.vmware.com [208.91.0.189]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6D143F4 for ; Tue, 9 Apr 2019 16:04:43 +0000 (UTC) Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Tue, 9 Apr 2019 09:04:28 -0700 Received: from WIN-ANAND1.vmware.com (win-anand1.prom.eng.vmware.com [10.33.79.212]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id D8B02B272B; Tue, 9 Apr 2019 12:04:41 -0400 (EDT) To: Date: Tue, 9 Apr 2019 09:03:57 -0700 Message-ID: <20190409160357.5096-1-kumaranand@vmware.com> X-Mailer: git-send-email 2.9.3.windows.1 MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-001.vmware.com: kumaranand@vmware.com does not designate permitted sender hosts) X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v1] datapath-windows: Do not send out nbls when cloned nbls are being accessed X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Anand Kumar via dev From: "Li,Rongqing via dev" Reply-To: Anand Kumar Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org As per MSDN documentation, "As soon as a filter driver calls the NdisFSendNetBufferLists function, it relinquishes ownership of the NET_BUFFER_LIST structures and all associated resources. A filter driver should never try to examine the NET_BUFFER_LIST structures or any associated data after calling NdisFSendNetBufferLists". https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ndis/nf-ndis-ndisfsendnetbufferlists When freeing up memory of a cloned nbl, parent's nbl and context is being accessed, which is incorrect can cause BSOD. With this patch, original nbl is sent out only when cloned nbl is done with packet processing and its memory is freed. Signed-off-by: Anand Kumar Change-Id: Ie662133a6fcd5a26ca3c87d31c9cee1fc56c2d27 --- datapath-windows/ovsext/BufferMgmt.c | 9 ++++++++- datapath-windows/ovsext/BufferMgmt.h | 2 ++ datapath-windows/ovsext/PacketIO.c | 13 +++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath-windows/ovsext/BufferMgmt.c index 47d872d..6627acf 100644 --- a/datapath-windows/ovsext/BufferMgmt.c +++ b/datapath-windows/ovsext/BufferMgmt.c @@ -81,6 +81,7 @@ #include "Flow.h" #include "Offload.h" #include "NetProto.h" +#include "PacketIO.h" #include "PacketParser.h" #include "Switch.h" #include "Vport.h" @@ -267,6 +268,7 @@ OvsInitNBLContext(POVS_BUFFER_CONTEXT ctx, ctx->srcPortNo = srcPortNo; ctx->origDataLength = origDataLength; ctx->mru = 0; + ctx->pendingSend = 0; } @@ -1746,8 +1748,13 @@ OvsCompleteNBL(PVOID switch_ctx, if (parent != NULL) { ctx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(parent); ASSERT(ctx && ctx->magic == OVS_CTX_MAGIC); + UINT16 pendingSend = 1, exchange = 0; value = InterlockedDecrement((LONG volatile *)&ctx->refCount); - if (value == 0) { + InterlockedCompareExchange16((SHORT volatile *)&pendingSend, exchange, (SHORT)ctx->pendingSend); + if (value == 1 && pendingSend == exchange) { + InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 0); + OvsSendNBLIngress(context, parent, ctx->sendFlags); + } else if (value == 0){ return OvsCompleteNBL(context, parent, FALSE); } } diff --git a/datapath-windows/ovsext/BufferMgmt.h b/datapath-windows/ovsext/BufferMgmt.h index 2a74988..2ae3272 100644 --- a/datapath-windows/ovsext/BufferMgmt.h +++ b/datapath-windows/ovsext/BufferMgmt.h @@ -55,7 +55,9 @@ typedef union _OVS_BUFFER_CONTEXT { UINT32 origDataLength; UINT32 dataOffsetDelta; }; + ULONG sendFlags; UINT16 mru; + UINT16 pendingSend; /* Indicates packet can be sent or not. */ }; CHAR value[MEM_ALIGN_SIZE(sizeof(struct dummy))]; diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c index 57c583c..56876f2 100644 --- a/datapath-windows/ovsext/PacketIO.c +++ b/datapath-windows/ovsext/PacketIO.c @@ -161,8 +161,17 @@ OvsSendNBLIngress(POVS_SWITCH_CONTEXT switchContext, ASSERT(switchContext->dataFlowState == OvsSwitchRunning); - NdisFSendNetBufferLists(switchContext->NdisFilterHandle, netBufferLists, - NDIS_DEFAULT_PORT_NUMBER, sendFlags); + POVS_BUFFER_CONTEXT ctx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(netBufferLists); + LONG refCount = 1, exchange = 0; + InterlockedCompareExchange((LONG volatile *)&refCount, exchange, (LONG)ctx->refCount); + if (refCount != exchange) { + InterlockedExchange((LONG volatile *)&ctx->sendFlags, sendFlags); + InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 1); + } else { + InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 0); + NdisFSendNetBufferLists(switchContext->NdisFilterHandle, netBufferLists, + NDIS_DEFAULT_PORT_NUMBER, sendFlags); + } } static __inline VOID