From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 7F9B581D31 for ; Tue, 8 Nov 2016 18:28:24 -0800 (PST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP; 08 Nov 2016 18:28:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,612,1473145200"; d="scan'208";a="29122856" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga005.jf.intel.com with ESMTP; 08 Nov 2016 18:28:27 -0800 Received: from fmsmsx125.amr.corp.intel.com (10.18.125.40) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 8 Nov 2016 18:28:27 -0800 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by FMSMSX125.amr.corp.intel.com (10.18.125.40) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 8 Nov 2016 18:28:26 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.206]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.104]) with mapi id 14.03.0248.002; Wed, 9 Nov 2016 10:28:23 +0800 From: "Fu, Siyuan" To: "Zhang, Lubo" , "edk2-devel@lists.01.org" CC: "Ni, Ruiyu" , "Ye, Ting" Thread-Topic: [patch] ShellPkg: update ping6 to use timer service instead of timer arch protocol . Thread-Index: AQHSObB2fnm335dQrESDEyiqWMeNraDP7naA Date: Wed, 9 Nov 2016 02:28:23 +0000 Message-ID: References: <1478603284-27560-1-git-send-email-lubo.zhang@intel.com> In-Reply-To: <1478603284-27560-1-git-send-email-lubo.zhang@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ctpclassification: CTP_IC x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiY2UzODYzZWMtZjEzNC00OTRjLWFhNWMtNDczNGY5ZWY0M2JjIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6IkliK09VSnZHVXlUVm10b2wwVXI2bk5IYW9DNXlWV0ExMDdYcFNPN21Ga2s9In0= x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [patch] ShellPkg: update ping6 to use timer service instead of timer arch protocol . X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Nov 2016 02:28:24 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Fu Siyuan > -----Original Message----- > From: Zhang, Lubo > Sent: Tuesday, November 8, 2016 7:08 PM > To: edk2-devel@lists.01.org > Cc: Ni, Ruiyu ; Ye, Ting ; Fu, > Siyuan > Subject: [patch] ShellPkg: update ping6 to use timer service instead of > timer arch protocol . >=20 > This patch update the shell ping command to use timer service to calculat= e > the > RTT time, instead of using the timer arch protocol. >=20 > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Zhang Lubo > Cc: Ni Ruiyu > Cc: Ye Ting > Cc: Fu Siyuan > --- > .../Library/UefiShellNetwork2CommandsLib/Ping6.c | 241 ++++++++++++++-= - > ----- > .../UefiShellNetwork2CommandsLib.inf | 1 + > .../UefiShellNetwork2CommandsLib.uni | 4 +- > 3 files changed, 170 insertions(+), 76 deletions(-) >=20 > diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > index 90a2604..a30c064 100644 > --- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > +++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > @@ -17,45 +17,44 @@ >=20 > #define PING6_DEFAULT_TIMEOUT 5000 > #define PING6_MAX_SEND_NUMBER 10000 > #define PING6_MAX_BUFFER_SIZE 32768 > #define PING6_ONE_SECOND 10000000 > - > -// > -// A similar amount of time that passes in femtoseconds > -// for each increment of TimerValue. It is for NT32 only. > -// > -#define NTTIMERPERIOD 358049 > +#define STALL_1_MILLI_SECOND 1000 >=20 > #pragma pack(1) >=20 > typedef struct _ICMP6_ECHO_REQUEST_REPLY { > UINT8 Type; > UINT8 Code; > UINT16 Checksum; > UINT16 Identifier; > UINT16 SequenceNum; > - UINT64 TimeStamp; > + UINT32 TimeStamp; > UINT8 Data[1]; > } ICMP6_ECHO_REQUEST_REPLY; >=20 > #pragma pack() >=20 > typedef struct _PING6_ICMP6_TX_INFO { > LIST_ENTRY Link; > UINT16 SequenceNum; > - UINT64 TimeStamp; > + UINT32 TimeStamp; > EFI_IP6_COMPLETION_TOKEN *Token; > } PING6_ICMP6_TX_INFO; >=20 > typedef struct _PING6_PRIVATE_DATA { > EFI_HANDLE ImageHandle; > EFI_HANDLE NicHandle; > EFI_HANDLE Ip6ChildHandle; > EFI_IP6_PROTOCOL *Ip6; > EFI_EVENT Timer; >=20 > + UINT32 TimerPeriod; > + UINT32 RttTimerTick; > + EFI_EVENT RttTimer; > + > EFI_STATUS Status; > LIST_ENTRY TxList; > EFI_IP6_COMPLETION_TOKEN RxToken; > UINT16 RxCount; > UINT16 TxCount; > @@ -97,100 +96,193 @@ SHELL_PARAM_ITEM Ping6ParamList[] =3D { > // > // Global Variables in Ping6 application. > // > CONST CHAR16 *mIp6DstString; > CONST CHAR16 *mIp6SrcString; > -UINT64 mFrequency =3D 0; > -UINT64 mIp6CurrentTick =3D 0; > EFI_CPU_ARCH_PROTOCOL *Cpu =3D NULL; >=20 > +/** > + RTT timer tick routine. >=20 > + @param[in] Event A EFI_EVENT type event. > + @param[in] Context The pointer to Context. > + > +**/ > +VOID > +EFIAPI > +Ping6RttTimerTickRoutine ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + UINT32 *RttTimerTick; > + > + RttTimerTick =3D (UINT32*) Context; > + (*RttTimerTick)++; > +} >=20 > /** > - Reads and returns the current value of the Time. > + Get the timer period of the system. > + > + This function tries to get the system timer period by creating > + an 1ms period timer. >=20 > - @return The current tick value. > + @return System timer period in MS, or 0 if operation failed. >=20 > **/ > -UINT64 > -Ping6ReadTime () > +UINT32 > +Ping6GetTimerPeriod( > + VOID > + ) > { > - UINT64 TimerPeriod; > - EFI_STATUS Status; > + EFI_STATUS Status; > + UINT32 RttTimerTick; > + EFI_EVENT TimerEvent; > + UINT32 StallCounter; > + EFI_TPL OldTpl; >=20 > - ASSERT (Cpu !=3D NULL); > + RttTimerTick =3D 0; > + StallCounter =3D 0; >=20 > - Status =3D Cpu->GetTimerValue (Cpu, 0, &mIp6CurrentTick, &TimerPeriod)= ; > + Status =3D gBS->CreateEvent ( > + EVT_TIMER | EVT_NOTIFY_SIGNAL, > + TPL_NOTIFY, > + Ping6RttTimerTickRoutine, > + &RttTimerTick, > + &TimerEvent > + ); > if (EFI_ERROR (Status)) { > - // > - // The WinntGetTimerValue will return EFI_UNSUPPORTED. Set the > - // TimerPeriod by ourselves. > - // > - mIp6CurrentTick +=3D 1000000; > + return 0; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + Status =3D gBS->SetTimer ( > + TimerEvent, > + TimerPeriodic, > + TICKS_PER_MS > + ); > + if (EFI_ERROR (Status)) { > + gBS->CloseEvent (TimerEvent); > + return 0; > + } > + > + while (RttTimerTick < 10) { > + gBS->Stall (STALL_1_MILLI_SECOND); > + ++StallCounter; > } >=20 > - return mIp6CurrentTick; > + gBS->RestoreTPL (OldTpl); > + > + gBS->SetTimer (TimerEvent, TimerCancel, 0); > + gBS->CloseEvent (TimerEvent); > + > + return StallCounter / RttTimerTick; > } >=20 > + > /** > - Get and calculate the frequency in tick/ms. > - The result is saved in the globle variable mFrequency > + Initialize the timer event for RTT (round trip time). >=20 > - @retval EFI_SUCCESS Calculated the frequency successfully. > - @retval Others Failed to calculate the frequency. > + @param[in] Private The pointer to PING6_PRIVATE_DATA. > + > + @retval EFI_SUCCESS RTT timer is started. > + @retval Others Failed to start the RTT timer. >=20 > **/ > EFI_STATUS > -Ping6GetFrequency ( > - VOID > +Ping6InitRttTimer ( > + IN PING6_PRIVATE_DATA *Private > ) > { > - EFI_STATUS Status; > - UINT64 CurrentTick; > - UINT64 TimerPeriod; > - > - Status =3D gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID = **) > &Cpu); > + EFI_STATUS Status; >=20 > + Private->TimerPeriod =3D Ping6GetTimerPeriod (); > + if (Private->TimerPeriod =3D=3D 0) { > + return EFI_ABORTED; > + } > + > + Private->RttTimerTick =3D 0; > + Status =3D gBS->CreateEvent ( > + EVT_TIMER | EVT_NOTIFY_SIGNAL, > + TPL_NOTIFY, > + Ping6RttTimerTickRoutine, > + &Private->RttTimerTick, > + &Private->RttTimer > + ); > if (EFI_ERROR (Status)) { > return Status; > } >=20 > - Status =3D Cpu->GetTimerValue (Cpu, 0, &CurrentTick, &TimerPeriod); > - > + Status =3D gBS->SetTimer ( > + Private->RttTimer, > + TimerPeriodic, > + TICKS_PER_MS > + ); > if (EFI_ERROR (Status)) { > - // > - // For NT32 Simulator only. 358049 is a similar value to keep timer > granularity. > - // Set the timer period by ourselves. > - // > - TimerPeriod =3D (UINT64) NTTIMERPERIOD; > + gBS->CloseEvent (Private->RttTimer); > + return Status; > } > - // > - // The timer period is in femtosecond (1 femtosecond is 1e-15 second). > - // So 1e+12 is divided by timer period to produce the freq in tick/ms. > - // > - mFrequency =3D DivU64x64Remainder (1000000000000ULL, TimerPeriod, NULL= ); >=20 > return EFI_SUCCESS; > + > +} > + > +/** > + Free RTT timer event resource. > + > + @param[in] Private The pointer to PING6_PRIVATE_DATA. > + > +**/ > +VOID > +Ping6FreeRttTimer ( > + IN PING6_PRIVATE_DATA *Private > + ) > +{ > + if (Private->RttTimer !=3D NULL) { > + gBS->SetTimer (Private->RttTimer, TimerCancel, 0); > + gBS->CloseEvent (Private->RttTimer); > + } > +} > + > +/** > + Read the current time. > + > + @param[in] Private The pointer to PING6_PRIVATE_DATA. > + > + @retval the current tick value. > +**/ > +UINT32 > +Ping6ReadTime ( > + IN PING6_PRIVATE_DATA *Private > + ) > +{ > + return Private->RttTimerTick; > } >=20 > /** > Get and calculate the duration in ms. >=20 > + @param[in] Private The pointer to PING6_PRIVATE_DATA. > @param[in] Begin The start point of time. > @param[in] End The end point of time. >=20 > @return The duration in ms. >=20 > **/ > -UINT64 > +UINT32 > Ping6CalculateTick ( > - IN UINT64 Begin, > - IN UINT64 End > + IN PING6_PRIVATE_DATA *Private, > + IN UINT32 Begin, > + IN UINT32 End > ) > { > - ASSERT (End > Begin); > - return DivU64x64Remainder (End - Begin, mFrequency, NULL); > + if (End < Begin) { > + return (0); > + } > + > + return (End - Begin) * Private->TimerPeriod; > + > } >=20 > /** > Destroy IPING6_ICMP6_TX_INFO, and recollect the memory. >=20 > @@ -310,12 +402,11 @@ Ping6OnEchoReplyReceived6 ( > PING6_PRIVATE_DATA *Private; > EFI_IP6_COMPLETION_TOKEN *RxToken; > EFI_IP6_RECEIVE_DATA *RxData; > ICMP6_ECHO_REQUEST_REPLY *Reply; > UINT32 PayLoad; > - UINT64 Rtt; > - CHAR8 Near; > + UINT32 Rtt; >=20 > Private =3D (PING6_PRIVATE_DATA *) Context; >=20 > if (Private->Status =3D=3D EFI_ABORTED) { > return; > @@ -350,16 +441,11 @@ Ping6OnEchoReplyReceived6 ( > goto ON_EXIT; > } > // > // Display statistics on this icmp6 echo reply packet. > // > - Rtt =3D Ping6CalculateTick (Reply->TimeStamp, Ping6ReadTime ()); > - if (Rtt !=3D 0) { > - Near =3D (CHAR8) '=3D'; > - } else { > - Near =3D (CHAR8) '<'; > - } > + Rtt =3D Ping6CalculateTick (Private, Reply->TimeStamp, Ping6ReadTime > (Private)); >=20 > Private->RttSum +=3D Rtt; > Private->RttMin =3D Private->RttMin > Rtt ? Rtt : Private->RttMin; > Private->RttMax =3D Private->RttMax < Rtt ? Rtt : Private->RttMax; >=20 > @@ -371,12 +457,12 @@ Ping6OnEchoReplyReceived6 ( > gShellNetwork2HiiHandle, > PayLoad, > mIp6DstString, > Reply->SequenceNum, > RxData->Header->HopLimit, > - Near, > - Rtt > + Rtt, > + Rtt + Private->TimerPeriod > ); >=20 > ON_EXIT: >=20 > if (Private->RxCount < Private->SendNum) { > @@ -413,11 +499,11 @@ ON_EXIT: >=20 > **/ > EFI_IP6_COMPLETION_TOKEN * > Ping6GenerateToken ( > IN PING6_PRIVATE_DATA *Private, > - IN UINT64 TimeStamp, > + IN UINT32 TimeStamp, > IN UINT16 SequenceNum > ) > { > EFI_STATUS Status; > EFI_IP6_COMPLETION_TOKEN *Token; > @@ -511,11 +597,11 @@ Ping6SendEchoRequest ( >=20 > if (TxInfo =3D=3D NULL) { > return EFI_OUT_OF_RESOURCES; > } >=20 > - TxInfo->TimeStamp =3D Ping6ReadTime (); > + TxInfo->TimeStamp =3D Ping6ReadTime (Private); > TxInfo->SequenceNum =3D (UINT16) (Private->TxCount + 1); >=20 > TxInfo->Token =3D Ping6GenerateToken ( > Private, > TxInfo->TimeStamp, > @@ -613,11 +699,11 @@ Ping6OnTimerRoutine6 ( > // > // Check whether any icmp6 echo request in the list timeout. > // > NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) { > TxInfo =3D BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link); > - Time =3D Ping6CalculateTick (TxInfo->TimeStamp, Ping6ReadTime ()); > + Time =3D Ping6CalculateTick (Private, TxInfo->TimeStamp, > Ping6ReadTime (Private)); >=20 > // > // Remove the timeout echo request from txlist. > // > if (Time > PING6_DEFAULT_TIMEOUT) { > @@ -1013,10 +1099,20 @@ ShellPing6 ( >=20 > if (EFI_ERROR (Status)) { > ShellStatus =3D SHELL_ACCESS_DENIED; > goto ON_EXIT; > } > + > + // > + // Start a timer to calculate the RTT. > + // > + Status =3D Ping6InitRttTimer (Private); > + if (EFI_ERROR (Status)) { > + ShellStatus =3D SHELL_ACCESS_DENIED; > + goto ON_EXIT; > + } > + > // > // Create a ipv6 token to send the first icmp6 echo request packet. > // > Status =3D Ping6SendEchoRequest (Private); > // > @@ -1091,12 +1187,15 @@ ON_STAT: > -1, > NULL, > STRING_TOKEN (STR_PING6_RTT), > gShellNetwork2HiiHandle, > Private->RttMin, > + Private->RttMin + Private->TimerPeriod, > Private->RttMax, > - DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL) > + Private->RttMax + Private->TimerPeriod, > + DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL), > + DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL) + > Private->TimerPeriod > ); > } >=20 > ON_EXIT: >=20 > @@ -1110,10 +1209,12 @@ ON_EXIT: >=20 > RemoveEntryList (&TxInfo->Link); > Ping6DestroyTxInfo (TxInfo); > } >=20 > + Ping6FreeRttTimer (Private); > + > if (Private->Timer !=3D NULL) { > gBS->CloseEvent (Private->Timer); > } >=20 > if (Private->Ip6 !=3D NULL) { > @@ -1246,19 +1347,11 @@ ShellCommandRunPing6 ( > ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP)= , > gShellNetwork2HiiHandle, ValueStr); > ShellStatus =3D SHELL_INVALID_PARAMETER; > goto ON_EXIT; > } > } > - // > - // Get frequency to calculate the time from ticks. > - // > - Status =3D Ping6GetFrequency (); >=20 > - if (EFI_ERROR(Status)) { > - ShellStatus =3D SHELL_ACCESS_DENIED; > - goto ON_EXIT; > - } > // > // Enter into ping6 process. > // > ShellStatus =3D ShellPing6 ( > ImageHandle, > diff --git > a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.inf > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.inf > index 426efcc..8f253d2 100644 > --- > a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.inf > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.inf > @@ -53,10 +53,11 @@ > [Pcd] > gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES >=20 > [Protocols] > gEfiCpuArchProtocolGuid ## CONSUMES > + gEfiTimerArchProtocolGuid > gEfiIp6ProtocolGuid ## SOMETIMES_CONSUMES > gEfiIp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES > gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES >=20 > [Guids] > diff --git > a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.uni > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.uni > index 89e8e37..c3445bb 100644 > --- > a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.uni > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Commands= L > ib.uni > @@ -36,13 +36,13 @@ > #string STR_PING6_SEND_REQUEST #language en-US "Echo reques= t > sequence %d fails.\r\n" > #string STR_PING6_CONFIGD_NIC_NF #language en-US "%Ping6: No > configured interfaces were found.\r\n" > #string STR_PING6_NOSOURCE_INDOMAIN #language en-US "No sources > in %s's multicast domain.\r\n" > #string STR_PING6_START #language en-US "Ping %s %d > data bytes\r\n" > #string STR_PING6_TIMEOUT #language en-US "Echo reques= t > sequence %d timeout.\r\n" > -#string STR_PING6_REPLY_INFO #language en-US "%d bytes > from %s : icmp_seq=3D%d ttl=3D%d time%c%dms\r\n" > +#string STR_PING6_REPLY_INFO #language en-US "%d bytes > from %s : icmp_seq=3D%d ttl=3D%d time%d~%dms\r\n" > #string STR_PING6_STAT #language en-US "\n%d packet= s > transmitted, %d received, %d%% packet loss, time %dms\r\n" > -#string STR_PING6_RTT #language en-US "\nRtt(round > trip time) min=3D%dms max=3D%dms avg=3D%dms\r\n" > +#string STR_PING6_RTT #language en-US "\nRtt(round > trip time) min=3D%d~%dms max=3D%d~%dms avg=3D%d~%dms\r\n" >=20 > #string STR_IFCONFIG6_ERR_IP6CFG_GETDATA #language en-US "Get > data of the interface information %hr\r\n" > #string STR_IFCONFIG6_INFO_BREAK #language en-US "-----= - > -----------------------------------------------------------" > #string STR_IFCONFIG6_INFO_COLON #language en-US ":" > #string STR_IFCONFIG6_INFO_JOINT #language en-US " >> " > -- > 1.9.5.msysgit.1