Understanding ethtool Ring Buffer Parameters: RX/TX Buffer Count vs Size Explained


2 views

When examining ethtool -g output, the numbers displayed (like 4096) represent the number of ring buffer descriptors allocated for receive (RX) and transmit (TX) operations - not the size in bytes. Each descriptor points to a packet buffer in memory where actual frame data is stored.

For the example output:

Ring parameters for eth0:
Pre-set maximums:
RX:             4096
Current hardware settings:
RX:             4096

This indicates:

  • The driver supports up to 4096 RX descriptors (maximum configurable)
  • The current active setting uses all 4096 descriptors
  • Each descriptor typically manages one Ethernet frame (1500-9000 bytes depending on MTU)

The Linux kernel handles ring buffers through these key components:

struct net_device {
    /* RX queue */
    struct netdev_rx_queue *_rx;
    
    /* TX queue */
    struct netdev_queue *_tx;
};

And the NIC driver implements descriptor rings like this (simplified):

/* Typical NIC ring buffer initialization */
int init_ring(struct adapter *adapter) {
    adapter->rx_ring.size = 4096;  // Number of descriptors
    adapter->rx_ring.buffer_info = kcalloc(adapter->rx_ring.size,
                        sizeof(struct buffer_info), GFP_KERNEL);
    // Allocate DMA buffers for each descriptor
    for (i = 0; i < adapter->rx_ring.size; i++) {
        adapter->rx_ring.buffer_info[i].dma = dma_map_single(
            adapter->pdev, 
            netdev_alloc_frag(2048),  // Actual buffer size
            PAGE_SIZE, 
            DMA_FROM_DEVICE);
    }
}

Adjusting ring buffer sizes affects performance:

# Set RX ring to 2048 descriptors
ethtool -G eth0 rx 2048

# Verify changes
ethtool -g eth0

Common optimization scenarios:

  • High-throughput: Increase both RX/TX (4096-8192)
  • Latency-sensitive: Smaller values (256-1024) reduce bufferbloat
  • Packet capture: Larger RX helps prevent drops during bursts

After modifying an AWS c5n.2xlarge instance's ring buffers:

# Before (default)
iperf3 -c 10.0.1.10 -t 30
[  5]   0.00-30.00  sec  10.9 GBytes  3.12 Gbits/sec

# After tuning
ethtool -G eth0 rx 8192 tx 8192
iperf3 -c 10.0.1.10 -t 30  
[  5]   0.00-30.00  sec  12.1 GBytes  3.46 Gbits/sec

The output from ethtool -g eth0 displays two critical sets of values:

Pre-set maximums:
RX:             4096
Current hardware settings:
RX:             4096

These numbers represent the count of buffer descriptors in the NIC's ring buffer, not the size in bytes. Each descriptor points to a memory buffer (typically 2KB-8KB in size) where packet data is stored.

Modern NICs use ring buffers with these characteristics:

  • RX ring buffers store incoming packets until the kernel can process them
  • TX ring buffers hold outgoing packets waiting for transmission
  • Each buffer slot contains a descriptor pointing to packet data in memory

Here's a practical example showing how to adjust these values:

# Set RX ring buffer to 2048 descriptors
sudo ethtool -G eth0 rx 2048

# Verify changes
ethtool -g eth0

The 4096 value in your output indicates:

  • Your NIC supports up to 4096 descriptors per ring
  • The current setting uses the maximum available
  • Higher values can reduce packet drops during traffic bursts

For monitoring actual buffer usage:

# Check for dropped packets
ethtool -S eth0 | grep -i drop
# Output might show:
rx_queue_0_drops: 0
tx_queue_0_drops: 0

The relationship between ring buffers and kernel networking:

  • Each descriptor typically corresponds to one SKB (socket buffer) in Linux
  • Driver-specific limitations may apply (check ethtool -i eth0)
  • Virtualized environments may have additional constraints

Example driver information check:

ethtool -i eth0 | grep driver
driver: ixgbe
version: 5.1.0-k