NIC Packet Loss and Performance: Diagnose Before Applying Legacy Tuning

The source investigates packet drops and poor throughput across a fleet, where OS, configuration or network conditions can be involved. Hardware, cabling and switch faults must still be checked. Establish a baseline, change one justified setting at a time and stop when the cause is resolved. These archived RHEL-era examples are not a universal tuning script.

1. Identify the interface, counters, driver and firmware

ifconfig <INTERFACE>
netstat -i
ethtool -i <INTERFACE>
ethtool -S <INTERFACE>
Original English interface and netstat counters with RX/TX statistics highlighted

Record link state and the specific increasing counters. Counter names and meanings depend on the driver. An absolute historical nonzero count alone does not show a current loss rate; correlate it with traffic, switch errors and application symptoms.

2. Check supported drivers and interrupt placement

For its Intel 82599 example, the source obtains an ixgbe package from Intel or Inspur, unpacks it and follows its README, then plans a reboot and uses its included set_irq_affinity script. Select a driver/firmware combination supported by the actual OS and adapter; “latest” is not automatically the right version. Other vendors such as Mellanox/NVIDIA or Chelsio have their own tools.

Original English ixgbe package and IRQ-affinity-script examples

The source’s manual-affinity workflow stops irqbalance before invoking the matching script, so the daemon does not immediately undo the mapping:

service irqbalance stop
./set_irq_affinity <INTERFACE>

This is the source’s legacy service syntax. Match the script version, CPU/NUMA topology and service manager. Manual IRQ placement and irqbalance are alternative policies to evaluate; record the prior state and do not disable balancing across a fleet without evidence.

3. Isolate bonding or teaming configuration

Verify bond/team and switch configuration using the supported mode. The source suggests a controlled single-port test or an active-backup mode 1 test to isolate aggregation issues. Active-backup does not require switch link aggregation, but the switch/VLAN configuration still matters. Plan for management-path interruption and compare measured results before changing the permanent design.

4. Evaluate IOMMU only for an applicable platform issue

The archived source suggests changing intel_iommu=on or amd_iommu=on to off in the active GRUB configuration if virtualization does not need it. The screenshot merely shows those flags; it does not establish a universal RHEL6 default or prove a performance penalty on all hardware.

Original English legacy GRUB lines highlighting intel_iommu and amd_iommu parameters

IOMMU can also be required for device assignment, isolation or platform policy. Check the exact issue and supported workaround before adapting the source’s /boot/grub/grub.conf or menu.lst example. Do not disable it solely because a drop counter exists.

5. Evaluate power and CPU options with measurements

The source next proposes disabling CPU/PCIe power savings, virtualization and Hyper-Threading. These settings affect power, thermals, security/features and workload scheduling, and can help or hurt different workloads. Treat them as individually tested, platform-specific hypotheses rather than steps that all systems should apply.

6. Distinguish disk I/O scheduling from NIC tuning

This source branch changes disk scheduling to deadline. It can affect a storage-bound workload but does not directly repair a network path. The source describes CFQ for its RHEL6 environment and deadline for RHEL7; actual defaults and available schedulers depend on device/kernel, and modern multiqueue kernels use other names.

English localization of the scheduler example with valid shell command and current-scheduler comment
echo deadline > /sys/block/<BLOCK_DEVICE>/queue/scheduler
cat /sys/block/<BLOCK_DEVICE>/queue/scheduler

For the source’s older RHEL4/5/6 branch, add elevator=deadline to the applicable kernel line in /etc/grub.conf. The sample shows an old 2.6.9 kernel:

Original English legacy GRUB kernel-line example with elevator=deadline

For its RHEL7 branch, place the same historical parameter in the existing GRUB_CMDLINE_LINUX string in /etc/default/grub, then regenerate the correct boot-mode path:

Original English GRUB_CMDLINE_LINUX example with elevator=deadline
# Source RHEL7 BIOS example
grub2-mkconfig -o /boot/grub2/grub.cfg
# Source RHEL7 Red Hat UEFI example
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

Do not execute both branches or overwrite an unrelated boot configuration. A temporary sysfs write and a boot-time change have different persistence; verify the supported scheduler and target block device first.

7. Inspect and, if justified, tune RX/TX rings

ethtool -S <INTERFACE> | grep rx_no_buffer_count
ethtool -g <INTERFACE>
ethtool -G <INTERFACE> rx <SUPPORTED_SIZE>

The source considers an increasing no-buffer counter and tests larger rings within the driver’s supported maximum, doubling incrementally while measuring. A counter’s interpretation is driver-specific and larger rings are not always better. Changing ring parameters may briefly interrupt connectivity.

Original English eth27 ring-buffer example, maximum4096 and current values changed from256 to512

The picture’s RX/TX maxima are 4096; each current value changes from 256 to 512 using separate rx/tx commands. The source proposes rc.local for persistence, which depends on the OS enabling/executing that file. Use the actual release’s supported persistent network configuration rather than assuming rc.local always runs.

8. Match MTU to the complete path

MTU limits the IP packet size on a link. A packet too large for the path can need fragmentation or appropriate packet-too-big signaling; blocked signaling and a no-fragment condition can cause loss. Tunnels such as IP-in-IP/IPsec add overhead, so account for the outer packet and every intervening interface/switch.

For basic IPv4 with 20-byte IP and 20-byte TCP headers, the source uses MSS = MTU − 40. This is not a universal equation for IPv6 or all header/options cases. In its example, a 1500-MTU client advertises an MSS of 1460 for what it can receive; a 1440-MTU server advertises 1400 for what it can receive. Advertised receive limits are directional; actual segment size must also fit the sender/path constraints, not blindly use one global number.

The source’s ICMP example reports a next-hop MTU of 1450 after rejecting an oversized no-fragment packet. Diagnose PMTU and tunnel overhead rather than merely enabling jumbo frames on one host.

# Temporary legacy ifconfig examples
ifconfig <INTERFACE> mtu <SIZE> up
ifconfig eth1 mtu 9000 up

These require the tool, device support and privileges and usually do not persist after reboot; they are not valid for every modern distribution. The source’s legacy network-scripts example is:

# /etc/sysconfig/network-scripts/ifcfg-eth0
MTU="9000"
# Source IPv6 example, only where appropriate
IPV6_MTU="1280"
# Applying through the old service manager can interrupt networking:
service network restart

Its Debian/Ubuntu ifupdown example adds mtu 9000 to the intended stanza in /etc/network/interfaces and uses /etc/init.d/networking restart. Those paths/services are not universal on NetworkManager/netplan/systemd-networkd systems. The value 1280 is the source’s IPv6 example, not a required match to every 9000-byte link. Configure the entire supported path and verify reachability before making the change persistent.

Sources

Can't find an answer?

Upload a log for AI diagnosis, or ask the AI assistant directly in the console.