This article covers the configuration I have come up with to get reasonable performance over a gigabit ethernet connection on systems running Windows XP Professional and FreeBSD versions 4.8 through 6.2. I have copied the configuration across computers of differing levels of performance and each time, the network performance has improved over "stock" settings.
My benchmark tool of choice is Iperf. Initial tests between a FreeBSD machine with an Intel Pro/1000 MT adapter connected to a Windows XP machine with a Marvell Yukon adapter reported around 134MBit/s, which is hardly better than the 100MBit ethernet adapters I had before. Most 100Mbit adapters I have dealt with can get up to approximately 85MBit/s.
After some chat on IRC, hours on Google, and mailing list hunting, I managed to find settings that yield up to 626Mbit/s, which certainly makes the jump from 100MBit parts worthwhile. In fact, 626Mbit/s (74.6MB/s) is faster than most hard disks.
Increasing MTU
Increasing the MTU is definitely the first step.
Unfortunately, the Intel Pro/1000MT Windows XP and FreeBSD
drivers disagree on "legal" MTU values, so I had to pick between 4088
and 9014 bytes. I chose 9014, because it is larger than
2*PAGE_SIZE on x86 hardware, and because
it is a fairly common setting for various switches, which I aspire to purchase one day.
In Windows, it is done using the utility that came with
the NIC. In FreeBSD, it is done with the following command:
# ifconfig em0 mtu 9014
/etc/rc.conf:
ifconfig_em0="inet 10.0.0.1 netmask 255.255.255.0 mtu 9014"
Initially, I thought that was all that needed to be done. However, it actually increased latency with very little in improved throughput. To fully take advantage of the larger MTU, the data itself must be sent in larger chunks. This parameter is known as the TCP window size.
FreeBSD Settings
/etc/sysctl.conf:
kern.polling.enable=1 net.inet.ip.check_interface=0 net.inet.tcp.sendspace=262144 net.inet.tcp.recvspace=262144 kern.ipc.maxsockbuf=1048576 net.inet.tcp.inflight_enable=1 net.inet.tcp.inflight_debug=0 net.inet.tcp.msl=30000 net.inet.tcp.inflight_min=6144 net.isr.enable=1 # Not in 6.x
In my case, performance plateaued using a value of 262144 bytes
for net.inet.tcp.(send|recv)space,
so to avoid wasting memory, I chose not to go any higher. Note that
kern.ipc.maxsockbuf must be a multiple larger than
net.inet.tcp.(send|recv)space. I chose to use four
times larger, and haven't had any problems so far.
/boot/loader.conf:
kern.ipc.nmbclusters="30720"
Without the above setting, someone (even a local user) could run the system out of mbufs rapidly,
possibly bringing the computer to its knees. It took five occurences for me to
realize this. Mbuf usage can be checked with netstat -m, or
systat -mbuf. Using a lower setting may save memory, but
going too low will definitely cause problems.
Windows XP Settings
Registry Editing
On the Windows XP Box, the TCP window size needed to be changed as well. I opened up Regedit, and went to the following directory:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
I then added two new DWORD values: GlobalMaxTcpWindowSize and
MaxTcpWindowSize. I made them the same value as the
net.inet.tcp.(send|recv)space syctls
on the FreeBSD box. Also, I set both SackOpts and Tcp1323Opts
to 1.
Registry File
The above settings for Windows XP can be applied with my registry file. Download the file, and then right-click on it and choose "Merge" to install the information to the registry. The registry file can also be customized with a text editor if need be.
If this helped, or caused a fire, please Let me know.