From patchwork Thu Apr 11 16:14:21 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: 1084153 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 44g5jy1TWnz9s4V for ; Fri, 12 Apr 2019 02:16:04 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 756B929C2; Thu, 11 Apr 2019 16:16:01 +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 A2A7329B9 for ; Thu, 11 Apr 2019 16:15:11 +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 0CDB7F4 for ; Thu, 11 Apr 2019 16:15:10 +0000 (UTC) Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Thu, 11 Apr 2019 09:14:53 -0700 Received: from WIN-ANAND1.vmware.com (win-anand1.prom.eng.vmware.com [10.33.79.212]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id D8ECD40ECB; Thu, 11 Apr 2019 09:15:09 -0700 (PDT) To: Date: Thu, 11 Apr 2019 09:14:21 -0700 Message-ID: <20190411161421.2132-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 v2] 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 Acked-by: Alin Gabriel Serdean > --- v1->v2: - Remove the else block and by default try to send the packet out. --- datapath-windows/ovsext/BufferMgmt.c | 9 ++++++++- datapath-windows/ovsext/BufferMgmt.h | 2 ++ datapath-windows/ovsext/PacketIO.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) 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..cc08407 100644 --- a/datapath-windows/ovsext/PacketIO.c +++ b/datapath-windows/ovsext/PacketIO.c @@ -161,6 +161,16 @@ OvsSendNBLIngress(POVS_SWITCH_CONTEXT switchContext, ASSERT(switchContext->dataFlowState == OvsSwitchRunning); + 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); + return; + } + + InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 0); NdisFSendNetBufferLists(switchContext->NdisFilterHandle, netBufferLists, NDIS_DEFAULT_PORT_NUMBER, sendFlags); }