Hi Laszlo, On Tue, Apr 01, 2014 at 11:54:35AM +0200, Laszlo Ersek wrote: > Hi Gary, > > On 04/01/14 09:30, Gary Ching-Pang Lin wrote: > > Hi, > > > > I am using OVMF to test OS PXE installation. The function basically > > works except the transmission rate of tftp is much lower than expected. > > > > Here is my setup: > > > > A virtual net device, tap0, was created to connect the host and the guest > > in QEMU like this: > > > > [ HOST ] ---- [tap0] ---- [ guest ] > > dhcp server OVMF r15416 > > tftp server > > ftp server > > > > Here is my command to create the virtual machine: > > qemu-system-x86_64 -s -bios <path ot ovmf> -drive file=disk.img,if=virtio \ > > -m 1024 -enable-kvm -fsdev > > local,id=exp,path=share,security_model=mapped-file \ > > -device virtio-9p-pci,fsdev=exp,mount_tag=v_share -monitor stdio \ > > -debugcon file:debug.log -global isa-debugcon.iobase=0x402 \ > > -netdev tap,id=vmnet0,ifname=tap0,script=no,downscript=no -device > > virtio-net-pci,netdev=vmnet0 > > > > The host runs openSUSE 13.1, and I use dnsmasq to set up the dhcp and > > tftp servers for the preboot images and a ftp server for the installation > > of packages. > > > > The boot procedure is: > > > > [OVMF] -> [shim.efi] -> [grub.efi] -> [Linux kernel + initrd] -> > > [Installation] > > > > I noticed the slowness while grub2 loading the kernel and initrd. The two > > files are 50~60 MB in total, and grub2 took 8~10 minutes to finish loading. > > Then I used tcpdump to capture packets through tap0 and found the > > transmission > > rate was just 1~2 Mbits/s. > > > > I switched the firmware to SeaBIOS and changed the boot procedure to > > > > [SeaBIOS] -> [grub2] -> [Linux kernel + initrd] -> [Installation] > > > > It took only seconds to load the kernel and initrd. > > > > I also tried the proprietary e1000 EFI driver, and the result was the same. > > Did anyone also have the slow tftp issue? > > Yes. > > There are two (possible) reasons to consider. > > > (1) The first possible reason is the frequency of the timer, which (if I > understand correctly) provides the ticks for the higher level network > drivers. In OVMF we use "PcAtChipsetPkg/8254TimerDxe". > > For example, whenever I tested the DataSource test app (from AppPkg), > the best speed it achieved (between guest and host, mind you) was > 280-300KB/s (about 200 packets/s). This seems to be limited by the timer > resolution. > > (I always used TCP in this app, so there might have been other factors > at play.) > > The "default timer tick duration is set to 10 ms" (see near > DEFAULT_TIMER_TICK_DURATION in "PcAtChipsetPkg/8254TimerDxe/Timer.h"). > > Unfortunately, there doesn't seem to be a PCD for this. Also, we can't > just call the EFI_TIMER_ARCH_PROTOCOL.SetTimerPeriod() member function > ourselves, in platform code, because the PI spec vol2 says: > > 12.10 Timer Architectural Protocol > EFI_TIMER_ARCH_PROTOCOL > > Summary > > Used to set up a periodic timer interrupt using a platform specific > timer, and a processor-specific interrupt vector. This protocol > enables the use of the SetTimer() Boot Service. This protocol > must be produce by a boot service or runtime DXE driver and may > only be consumed by the DXE Foundation or DXE drivers that produce > other DXE Architectural Protocols. > > The HPET flavor (PcAtChipsetPkg/HpetTimerDxe) *is* controllable with a > PCD (PcdHpetDefaultTimerPeriod), but in OVMF we don't use that. (AFAIR > qemu has some problems with HPET emulation, but I'm not fully sure.) > Changing the timer duration didn't improve the performance, so the timer doesn't matter.
> > (2) The second possible reason is a grub2 bug which has bitten us before. > > Importantly, you are using grub2's PXE and TFTP clients, not the ones > built into edk2 (UefiPxeBcDxe and Mtftp4Dxe under > MdeModulePkg/Universal/Network/). > > If I remember correctly our earlier analysis, grub2 opens the SNP > interface without kicking off other consumers of the service; notably, > ARP (MdeModulePkg/Universal/Network/ArpDxe). > > The result is that the edk2 ARP driver and grub2's TFTP client compete > for incoming packets. The ARP driver steals some packets, and throws off > grub2's TFTP client. > > The idea is that grub2 should open SNP with the EXCLUSIVE attribute: > > If Attributes is [...] EXCLUSIVE, and there is an item on the open > list of the protocol interface with an attribute of BY_DRIVER, then > the boot service DisconnectController() is called for the driver on > the open list. [...] > > and > > EXCLUSIVE Used by applications to gain exclusive access to a > protocol interface. If any drivers have the protocol > interface opened with an attribute of BY_DRIVER, then an > attempt will be made to remove them by calling the > driver’s Stop() function. > > Please try the attached grub2 patch. (Note: I'm not sure this was the > final patch that we ended up with.) > The attached patch made grub2 failed to fetch the config file, so I searched grub2 in koji and found the there are a few more lines in the final patch to check the status of the net device and start the device if necessary. The patch in koji fixed my problem :-) Thanks a lot! Gary Lin > > If fiddling with DEFAULT_TIMER_TICK_DURATION in (1) helps, then we > should submit a patch for PcAtChipsetPkg that adds a PCD, similar to > PcdHpetDefaultTimerPeriod, for 8254TimerDxe. > > Thanks > Laszlo > diff --git a/grub-core/net/drivers/efi/efinet.c > b/grub-core/net/drivers/efi/efinet.c > index 2b344d6..d775e7b 100644 > --- a/grub-core/net/drivers/efi/efinet.c > +++ b/grub-core/net/drivers/efi/efinet.c > @@ -164,7 +164,7 @@ grub_efinet_findcards (void) > struct grub_net_card *card; > > net = grub_efi_open_protocol (*handle, &net_io_guid, > - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); > + GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); > if (! net) > /* This should not happen... Why? */ > continue; ------------------------------------------------------------------------------ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel