From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=jiaxin.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2A00E22423828 for ; Thu, 1 Mar 2018 22:37:17 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Mar 2018 22:43:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,411,1515484800"; d="scan'208";a="204936208" Received: from jiaxinwu-mobl2.ccr.corp.intel.com ([10.239.196.74]) by orsmga005.jf.intel.com with ESMTP; 01 Mar 2018 22:43:25 -0800 From: Jiaxin Wu To: edk2-devel@lists.01.org Cc: Fu Siyuan , Wang Fan , Ye Ting Date: Fri, 2 Mar 2018 14:43:22 +0800 Message-Id: <20180302064322.3600-1-jiaxin.wu@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 Subject: [Patch] MdeModulePkg/Mtftp4Dxe: Separate the timer ticking to calculate the packet live time. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Mar 2018 06:37:18 -0000 From: Fu Siyuan TPL deadlock issue was enrolled by the commit of 39b0867d. To resolve the issue, this patch separated the timer ticking for all the MTFTP clients to calculate the packet live time in TPL_NOTIFY level. Cc: Wang Fan Cc: Fu Siyuan Cc: Ye Ting Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan Signed-off-by: Jiaxin Wu --- .../Universal/Network/Mtftp4Dxe/Mtftp4Driver.c | 34 ++++++++++--- .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.c | 5 +- .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.h | 6 ++- .../Universal/Network/Mtftp4Dxe/Mtftp4Support.c | 57 +++++++++++++++++----- .../Universal/Network/Mtftp4Dxe/Mtftp4Support.h | 16 +++++- 5 files changed, 97 insertions(+), 21 deletions(-) diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c index a23d405baa..713cc66dd1 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c @@ -1,9 +1,9 @@ /** @file Implementation of Mtftp drivers. -Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php
@@ -160,15 +160,16 @@ Mtftp4CreateService ( MtftpSb->Signature = MTFTP4_SERVICE_SIGNATURE; MtftpSb->ServiceBinding = gMtftp4ServiceBindingTemplete; MtftpSb->ChildrenNum = 0; InitializeListHead (&MtftpSb->Children); - MtftpSb->Timer = NULL; - MtftpSb->TimerToGetMap = NULL; - MtftpSb->Controller = Controller; - MtftpSb->Image = Image; - MtftpSb->ConnectUdp = NULL; + MtftpSb->Timer = NULL; + MtftpSb->TimerNotifyLevel = NULL; + MtftpSb->TimerToGetMap = NULL; + MtftpSb->Controller = Controller; + MtftpSb->Image = Image; + MtftpSb->ConnectUdp = NULL; // // Create the timer and a udp to be notified when UDP is uninstalled // Status = gBS->CreateEvent ( @@ -176,12 +177,24 @@ Mtftp4CreateService ( TPL_CALLBACK, Mtftp4OnTimerTick, MtftpSb, &MtftpSb->Timer ); + if (EFI_ERROR (Status)) { + FreePool (MtftpSb); + return Status; + } + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL | EVT_TIMER, + TPL_NOTIFY, + Mtftp4OnTimerTickNotifyLevel, + MtftpSb, + &MtftpSb->TimerNotifyLevel + ); if (EFI_ERROR (Status)) { + gBS->CloseEvent (MtftpSb->Timer); FreePool (MtftpSb); return Status; } // @@ -194,10 +207,11 @@ Mtftp4CreateService ( NULL, NULL, &MtftpSb->TimerToGetMap ); if (EFI_ERROR (Status)) { + gBS->CloseEvent (MtftpSb->TimerNotifyLevel); gBS->CloseEvent (MtftpSb->Timer); FreePool (MtftpSb); return Status; } @@ -209,10 +223,11 @@ Mtftp4CreateService ( NULL ); if (MtftpSb->ConnectUdp == NULL) { gBS->CloseEvent (MtftpSb->TimerToGetMap); + gBS->CloseEvent (MtftpSb->TimerNotifyLevel); gBS->CloseEvent (MtftpSb->Timer); FreePool (MtftpSb); return EFI_DEVICE_ERROR; } @@ -232,10 +247,11 @@ Mtftp4CleanService ( IN MTFTP4_SERVICE *MtftpSb ) { UdpIoFreeIo (MtftpSb->ConnectUdp); gBS->CloseEvent (MtftpSb->TimerToGetMap); + gBS->CloseEvent (MtftpSb->TimerNotifyLevel); gBS->CloseEvent (MtftpSb->Timer); } /** @@ -292,10 +308,16 @@ Mtftp4DriverBindingStart ( if (EFI_ERROR (Status)) { goto ON_ERROR; } + Status = gBS->SetTimer (MtftpSb->TimerNotifyLevel, TimerPeriodic, TICKS_PER_SECOND); + + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // // Install the Mtftp4ServiceBinding Protocol onto Controller // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index f5f9e6d8f7..d8c48ec8b2 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -1080,10 +1080,11 @@ EfiMtftp4Poll ( IN EFI_MTFTP4_PROTOCOL *This ) { MTFTP4_PROTOCOL *Instance; EFI_UDP4_PROTOCOL *Udp; + EFI_STATUS Status; if (This == NULL) { return EFI_INVALID_PARAMETER; } @@ -1094,11 +1095,13 @@ EfiMtftp4Poll ( } else if (Instance->State == MTFTP4_STATE_DESTROY) { return EFI_DEVICE_ERROR; } Udp = Instance->UnicastPort->Protocol.Udp4; - return Udp->Poll (Udp); + Status = Udp->Poll (Udp); + Mtftp4OnTimerTick (NULL, Instance->Service); + return Status; } EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = { EfiMtftp4GetModeData, EfiMtftp4Configure, diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h index 527fd1db10..851b595eee 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h @@ -7,11 +7,11 @@ RFC2090 - TFTP Multicast Option RFC2347 - TFTP Option Extension RFC2348 - TFTP Blocksize Option RFC2349 - TFTP Timeout Interval and Transfer Size Options -Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php
@@ -70,11 +70,12 @@ struct _MTFTP4_SERVICE { EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; UINT16 ChildrenNum; LIST_ENTRY Children; - EFI_EVENT Timer; ///< Ticking timer for all the MTFTP clients + EFI_EVENT Timer; ///< Ticking timer for all the MTFTP clients to handle the packet timeout case. + EFI_EVENT TimerNotifyLevel; ///< Ticking timer for all the MTFTP clients to calculate the packet live time. EFI_EVENT TimerToGetMap; EFI_HANDLE Controller; EFI_HANDLE Image; @@ -133,10 +134,11 @@ struct _MTFTP4_PROTOCOL { // // Timeout and retransmit status // NET_BUF *LastPacket; UINT32 PacketToLive; + BOOLEAN HasTimeout; UINT32 CurRetry; UINT32 MaxRetry; UINT32 Timeout; // diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c index c625fda020..e4366b6ddb 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c @@ -1,9 +1,9 @@ /** @file Support routines for Mtftp. -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php
@@ -566,10 +566,46 @@ Mtftp4Retransmit ( return Status; } +/** + The timer ticking function in TPL_NOTIFY level for the Mtftp service instance. + + @param Event The ticking event + @param Context The Mtftp service instance + +**/ +VOID +EFIAPI +Mtftp4OnTimerTickNotifyLevel ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + MTFTP4_SERVICE *MtftpSb; + LIST_ENTRY *Entry; + LIST_ENTRY *Next; + MTFTP4_PROTOCOL *Instance; + + MtftpSb = (MTFTP4_SERVICE *) Context; + + // + // Iterate through all the children of the Mtftp service instance. Time + // out the current packet transmit. + // + NET_LIST_FOR_EACH_SAFE (Entry, Next, &MtftpSb->Children) { + Instance = NET_LIST_USER_STRUCT (Entry, MTFTP4_PROTOCOL, Link); + if ((Instance->PacketToLive == 0) || (--Instance->PacketToLive > 0)) { + Instance->HasTimeout = FALSE; + } else { + Instance->HasTimeout = TRUE; + } + } +} + + /** The timer ticking function for the Mtftp service instance. @param Event The ticking event @param Context The Mtftp service instance @@ -589,33 +625,32 @@ Mtftp4OnTimerTick ( EFI_MTFTP4_TOKEN *Token; MtftpSb = (MTFTP4_SERVICE *) Context; // - // Iterate through all the children of the Mtftp service instance. Time - // out the packet. If maximum retries reached, clean the session up. + // Iterate through all the children of the Mtftp service instance. // NET_LIST_FOR_EACH_SAFE (Entry, Next, &MtftpSb->Children) { Instance = NET_LIST_USER_STRUCT (Entry, MTFTP4_PROTOCOL, Link); - - if ((Instance->PacketToLive == 0) || (--Instance->PacketToLive > 0)) { + if (!Instance->HasTimeout) { continue; } + + Instance->HasTimeout = FALSE; // // Call the user's time out handler // Token = Instance->Token; - if ((Token->TimeoutCallback != NULL) && + if (Token != NULL && Token->TimeoutCallback != NULL && EFI_ERROR (Token->TimeoutCallback (&Instance->Mtftp4, Token))) { - Mtftp4SendError ( - Instance, - EFI_MTFTP4_ERRORCODE_REQUEST_DENIED, - (UINT8 *) "User aborted the transfer in time out" - ); + Instance, + EFI_MTFTP4_ERRORCODE_REQUEST_DENIED, + (UINT8 *) "User aborted the transfer in time out" + ); Mtftp4CleanOperation (Instance, EFI_ABORTED); continue; } diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h index 802e3867db..fd8703a925 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h @@ -1,9 +1,9 @@ /** @file Support routines for MTFTP. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php
@@ -185,10 +185,24 @@ Mtftp4SendError ( EFI_STATUS Mtftp4Retransmit ( IN MTFTP4_PROTOCOL *Instance ); +/** + The timer ticking function in TPL_NOTIFY level for the Mtftp service instance. + + @param Event The ticking event + @param Context The Mtftp service instance + +**/ +VOID +EFIAPI +Mtftp4OnTimerTickNotifyLevel ( + IN EFI_EVENT Event, + IN VOID *Context + ); + /** The timer ticking function for the Mtftp service instance. @param Event The ticking event @param Context The Mtftp service instance -- 2.16.2.windows.1