1. Fix PXE performance issue : enhance EfiPxeBcSetIpFilter() to eliminate unnecessary re-configure UdpRead operation.

Reviewed-by: xdu2
Signed-off-by: hhuan13


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11780 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
hhuan13 2011-06-09 09:25:48 +00:00
parent c82291bc31
commit 1812735204
2 changed files with 116 additions and 53 deletions

View File

@ -739,7 +739,7 @@ PxeBcCreateIp4Children (
Udp4CfgData = &Private->Udp4CfgData; Udp4CfgData = &Private->Udp4CfgData;
Ip4CfgData = &Private->Ip4CfgData; Ip4CfgData = &Private->Ip4CfgData;
Udp4CfgData->AcceptBroadcast = TRUE; Udp4CfgData->AcceptBroadcast = FALSE;
Udp4CfgData->AcceptAnyPort = TRUE; Udp4CfgData->AcceptAnyPort = TRUE;
Udp4CfgData->AllowDuplicatePort = TRUE; Udp4CfgData->AllowDuplicatePort = TRUE;
Udp4CfgData->TypeOfService = Mode->ToS; Udp4CfgData->TypeOfService = Mode->ToS;

View File

@ -1,7 +1,7 @@
/** @file /** @file
This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL. This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -402,6 +402,11 @@ EfiPxeBcDhcp (
// Start S.A.R.R. process to get a IPv6 address and other boot information. // Start S.A.R.R. process to get a IPv6 address and other boot information.
// //
Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6); Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6);
//
// Configure Udp6Read instance
//
Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else { } else {
// //
@ -413,6 +418,11 @@ EfiPxeBcDhcp (
// Start D.O.R.A. process to get a IPv4 address and other boot information. // Start D.O.R.A. process to get a IPv4 address and other boot information.
// //
Status = PxeBcDhcp4Dora (Private, Private->Dhcp4); Status = PxeBcDhcp4Dora (Private, Private->Dhcp4);
//
// Configure Udp4Read instance
//
Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
} }
// //
@ -678,6 +688,12 @@ EfiPxeBcDiscover (
ON_EXIT: ON_EXIT:
if (Mode->UsingIpv6) {
Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else {
Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
}
// //
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
@ -909,6 +925,12 @@ EfiPxeBcMtftp (
Mode->IcmpErrorReceived = TRUE; Mode->IcmpErrorReceived = TRUE;
} }
if (Mode->UsingIpv6) {
Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else {
Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
}
// //
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
@ -1408,10 +1430,13 @@ EfiPxeBcSetIpFilter (
EFI_STATUS Status; EFI_STATUS Status;
PXEBC_PRIVATE_DATA *Private; PXEBC_PRIVATE_DATA *Private;
EFI_PXE_BASE_CODE_MODE *Mode; EFI_PXE_BASE_CODE_MODE *Mode;
EFI_UDP4_CONFIG_DATA Udp4Cfg; EFI_UDP4_CONFIG_DATA *Udp4Cfg;
EFI_UDP6_CONFIG_DATA Udp6Cfg; EFI_UDP6_CONFIG_DATA *Udp6Cfg;
UINTN Index; UINTN Index;
BOOLEAN NeedPromiscuous; BOOLEAN NeedPromiscuous;
BOOLEAN AcceptPromiscuous;
BOOLEAN AcceptBroadcast;
BOOLEAN MultiCastUpdate;
if (This == NULL || NewFilter == NULL) { if (This == NULL || NewFilter == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -1446,19 +1471,9 @@ EfiPxeBcSetIpFilter (
} }
} }
// AcceptPromiscuous = FALSE;
// Clear configuration for UdpRead and leave the original group joined before. AcceptBroadcast = FALSE;
// MultiCastUpdate = FALSE;
if (Mode->UsingIpv6) {
CopyMem(&Udp6Cfg, &Private->Udp6CfgData, sizeof (EFI_UDP6_CONFIG_DATA));
Private->Udp6Read->Configure (Private->Udp6Read, NULL);
Udp6Cfg.AcceptPromiscuous = FALSE;
} else {
CopyMem(&Udp4Cfg, &Private->Udp4CfgData, sizeof (EFI_UDP4_CONFIG_DATA));
Private->Udp4Read->Configure (Private->Udp4Read, NULL);
Udp4Cfg.AcceptPromiscuous = FALSE;
Udp4Cfg.AcceptBroadcast = FALSE;
}
if (NeedPromiscuous || if (NeedPromiscuous ||
(NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0 || (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0 ||
@ -1466,55 +1481,104 @@ EfiPxeBcSetIpFilter (
// //
// Configure UDPv4/UDPv6 as promiscuous mode to receive all packets. // Configure UDPv4/UDPv6 as promiscuous mode to receive all packets.
// //
Udp4Cfg.AcceptPromiscuous = TRUE; AcceptPromiscuous = TRUE;
Udp6Cfg.AcceptPromiscuous = TRUE;
} else if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) { } else if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) {
// //
// Configure UDPv4 to receive all broadcast packets. // Configure UDPv4 to receive all broadcast packets.
// //
Udp4Cfg.AcceptBroadcast = TRUE; AcceptBroadcast = TRUE;
} }
// //
// Configure UDPv4/UDPv6 instance with the new configuration. // In multicast condition when Promiscuous FALSE and IpCnt no-zero.
// Here check if there is any update of the multicast ip address. If yes,
// we need leave the old multicast group (by Config UDP instance to NULL),
// and join the new multicast group.
// //
if (Mode->UsingIpv6) { if (!AcceptPromiscuous) {
Status = Private->Udp6Read->Configure (Private->Udp6Read, &Udp6Cfg); if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) {
} else { if (Mode->IpFilter.IpCnt != NewFilter->IpCnt) {
Status = Private->Udp4Read->Configure (Private->Udp4Read, &Udp4Cfg); MultiCastUpdate = TRUE;
} else if (CompareMem (Mode->IpFilter.IpList, NewFilter->IpList, NewFilter->IpCnt * sizeof (EFI_IP_ADDRESS)) != 0 ) {
MultiCastUpdate = TRUE;
}
}
} }
if (EFI_ERROR (Status)) { if (!Mode->UsingIpv6) {
goto ON_EXIT; //
} // Check whether we need reconfigure the UDP4 instance.
//
if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) { Udp4Cfg = &Private->Udp4CfgData;
if ((AcceptPromiscuous != Udp4Cfg->AcceptPromiscuous) ||
for (Index = 0; Index < NewFilter->IpCnt; Index++) { (AcceptBroadcast != Udp4Cfg->AcceptBroadcast) || MultiCastUpdate) {
// //
// Join the multicast group if needed. // Clear the UDP4 instance configuration, all joined groups will be left
// during the operation.
// //
if (Mode->UsingIpv6) { Private->Udp4Read->Configure (Private->Udp4Read, NULL);
if (IP6_IS_MULTICAST (&NewFilter->IpList[Index].v6)) {
Status = Private->Udp6Read->Groups ( //
Private->Udp6Read, // Configure the UDP instance with the new configuration.
TRUE, //
&NewFilter->IpList[Index].v6 Udp4Cfg->AcceptPromiscuous = AcceptPromiscuous;
); Udp4Cfg->AcceptBroadcast = AcceptBroadcast;
if (EFI_ERROR (Status)) { Status = Private->Udp4Read->Configure (Private->Udp4Read, Udp4Cfg);
goto ON_EXIT; if (EFI_ERROR (Status)) {
return Status;
}
//
// In not Promiscuous mode, need to join the new multicast group.
//
if (!AcceptPromiscuous) {
for (Index = 0; Index < NewFilter->IpCnt; ++Index) {
if (IP4_IS_MULTICAST (EFI_NTOHL (NewFilter->IpList[Index].v4))) {
//
// Join the mutilcast group.
//
Status = Private->Udp4Read->Groups (Private->Udp4Read, TRUE, &NewFilter->IpList[Index].v4);
if (EFI_ERROR (Status)) {
return Status;
}
} }
} }
} else { }
if (IP4_IS_MULTICAST (EFI_NTOHL (NewFilter->IpList[Index].v4))) { }
Status = Private->Udp4Read->Groups ( } else {
Private->Udp4Read, //
TRUE, // Check whether we need reconfigure the UDP6 instance.
&NewFilter->IpList[Index].v4 //
); Udp6Cfg = &Private->Udp6CfgData;
if (EFI_ERROR (Status)) { if ((AcceptPromiscuous != Udp6Cfg->AcceptPromiscuous) || MultiCastUpdate) {
goto ON_EXIT; //
// Clear the UDP6 instance configuration, all joined groups will be left
// during the operation.
//
Private->Udp6Read->Configure (Private->Udp6Read, NULL);
//
// Configure the UDP instance with the new configuration.
//
Udp6Cfg->AcceptPromiscuous = AcceptPromiscuous;
Status = Private->Udp6Read->Configure (Private->Udp6Read, Udp6Cfg);
if (EFI_ERROR (Status)) {
return Status;
}
//
// In not Promiscuous mode, need to join the new multicast group.
//
if (!AcceptPromiscuous) {
for (Index = 0; Index < NewFilter->IpCnt; ++Index) {
if (IP6_IS_MULTICAST (&NewFilter->IpList[Index].v6)) {
//
// Join the mutilcast group.
//
Status = Private->Udp6Read->Groups (Private->Udp6Read, TRUE, &NewFilter->IpList[Index].v6);
if (EFI_ERROR (Status)) {
return Status;
}
} }
} }
} }
@ -1526,7 +1590,6 @@ EfiPxeBcSetIpFilter (
// //
CopyMem (&Mode->IpFilter, NewFilter, sizeof (Mode->IpFilter)); CopyMem (&Mode->IpFilter, NewFilter, sizeof (Mode->IpFilter));
ON_EXIT:
return Status; return Status;
} }