diff options
| author | Auke Kok <auke-jan.h.kok@intel.com> | 2006-04-14 22:05:18 -0400 |
|---|---|---|
| committer | Auke Kok <auke-jan.h.kok@intel.com> | 2006-04-14 22:05:18 -0400 |
| commit | 9e2feace1acd38d7a3b1275f7f9f8a397d09040e (patch) | |
| tree | 109e9bae993df91e2ff83ce7b4fccba9498d0273 | |
| parent | 6fc7a7eca70780dc1539ce68a6513f9b11891f3c (diff) | |
e1000: Buffer optimizations for small MTU
Remove multi-descriptor support from legacy recieve path
Add memory usage efficiency by using more correct size descriptors for
small MTU sizes and optimize using LPE for <= 1522 byte frame sizes
An extra performance fix that effected our TCP window size growth
as a receiver. Set our initial buffer to be 128 bytes instead of 256
to prevent over-socket charge when truesize is computed in the stack.
old way: truesize = 256 + l1 = 256 + 1460 = 1716
new way: truesize = 128 + l1 = 128 + 1460 = 1588
The magic value that we can't cross is 1648.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
| -rw-r--r-- | drivers/net/e1000/e1000.h | 2 | ||||
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 87 |
2 files changed, 52 insertions, 37 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 764808f3702e..2dfabdb29e7b 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
| @@ -114,6 +114,8 @@ struct e1000_adapter; | |||
| 114 | /* Supported Rx Buffer Sizes */ | 114 | /* Supported Rx Buffer Sizes */ |
| 115 | #define E1000_RXBUFFER_128 128 /* Used for packet split */ | 115 | #define E1000_RXBUFFER_128 128 /* Used for packet split */ |
| 116 | #define E1000_RXBUFFER_256 256 /* Used for packet split */ | 116 | #define E1000_RXBUFFER_256 256 /* Used for packet split */ |
| 117 | #define E1000_RXBUFFER_512 512 | ||
| 118 | #define E1000_RXBUFFER_1024 1024 | ||
| 117 | #define E1000_RXBUFFER_2048 2048 | 119 | #define E1000_RXBUFFER_2048 2048 |
| 118 | #define E1000_RXBUFFER_4096 4096 | 120 | #define E1000_RXBUFFER_4096 4096 |
| 119 | #define E1000_RXBUFFER_8192 8192 | 121 | #define E1000_RXBUFFER_8192 8192 |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6d7ba0bb233a..f604a1dea399 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -972,8 +972,8 @@ e1000_sw_init(struct e1000_adapter *adapter) | |||
| 972 | 972 | ||
| 973 | pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); | 973 | pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); |
| 974 | 974 | ||
| 975 | adapter->rx_buffer_len = E1000_RXBUFFER_2048; | 975 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE; |
| 976 | adapter->rx_ps_bsize0 = E1000_RXBUFFER_256; | 976 | adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; |
| 977 | hw->max_frame_size = netdev->mtu + | 977 | hw->max_frame_size = netdev->mtu + |
| 978 | ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; | 978 | ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; |
| 979 | hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; | 979 | hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; |
| @@ -1599,14 +1599,21 @@ e1000_setup_rctl(struct e1000_adapter *adapter) | |||
| 1599 | rctl |= E1000_RCTL_LPE; | 1599 | rctl |= E1000_RCTL_LPE; |
| 1600 | 1600 | ||
| 1601 | /* Setup buffer sizes */ | 1601 | /* Setup buffer sizes */ |
| 1602 | if (adapter->hw.mac_type >= e1000_82571) { | 1602 | rctl &= ~E1000_RCTL_SZ_4096; |
| 1603 | /* We can now specify buffers in 1K increments. | 1603 | rctl |= E1000_RCTL_BSEX; |
| 1604 | * BSIZE and BSEX are ignored in this case. */ | 1604 | switch (adapter->rx_buffer_len) { |
| 1605 | rctl |= adapter->rx_buffer_len << 0x11; | 1605 | case E1000_RXBUFFER_256: |
| 1606 | } else { | 1606 | rctl |= E1000_RCTL_SZ_256; |
| 1607 | rctl &= ~E1000_RCTL_SZ_4096; | 1607 | rctl &= ~E1000_RCTL_BSEX; |
| 1608 | rctl |= E1000_RCTL_BSEX; | 1608 | break; |
| 1609 | switch (adapter->rx_buffer_len) { | 1609 | case E1000_RXBUFFER_512: |
| 1610 | rctl |= E1000_RCTL_SZ_512; | ||
| 1611 | rctl &= ~E1000_RCTL_BSEX; | ||
| 1612 | break; | ||
| 1613 | case E1000_RXBUFFER_1024: | ||
| 1614 | rctl |= E1000_RCTL_SZ_1024; | ||
| 1615 | rctl &= ~E1000_RCTL_BSEX; | ||
| 1616 | break; | ||
| 1610 | case E1000_RXBUFFER_2048: | 1617 | case E1000_RXBUFFER_2048: |
| 1611 | default: | 1618 | default: |
| 1612 | rctl |= E1000_RCTL_SZ_2048; | 1619 | rctl |= E1000_RCTL_SZ_2048; |
| @@ -1621,7 +1628,6 @@ e1000_setup_rctl(struct e1000_adapter *adapter) | |||
| 1621 | case E1000_RXBUFFER_16384: | 1628 | case E1000_RXBUFFER_16384: |
| 1622 | rctl |= E1000_RCTL_SZ_16384; | 1629 | rctl |= E1000_RCTL_SZ_16384; |
| 1623 | break; | 1630 | break; |
| 1624 | } | ||
| 1625 | } | 1631 | } |
| 1626 | 1632 | ||
| 1627 | #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT | 1633 | #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT |
| @@ -2982,8 +2988,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 2982 | 2988 | ||
| 2983 | /* Adapter-specific max frame size limits. */ | 2989 | /* Adapter-specific max frame size limits. */ |
| 2984 | switch (adapter->hw.mac_type) { | 2990 | switch (adapter->hw.mac_type) { |
| 2985 | case e1000_82542_rev2_0: | 2991 | case e1000_undefined ... e1000_82542_rev2_1: |
| 2986 | case e1000_82542_rev2_1: | ||
| 2987 | if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { | 2992 | if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { |
| 2988 | DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); | 2993 | DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); |
| 2989 | return -EINVAL; | 2994 | return -EINVAL; |
| @@ -3017,27 +3022,32 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 3017 | break; | 3022 | break; |
| 3018 | } | 3023 | } |
| 3019 | 3024 | ||
| 3020 | 3025 | /* NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN | |
| 3021 | if (adapter->hw.mac_type > e1000_82547_rev_2) { | 3026 | * means we reserve 2 more, this pushes us to allocate from the next |
| 3022 | adapter->rx_buffer_len = max_frame; | 3027 | * larger slab size |
| 3023 | E1000_ROUNDUP(adapter->rx_buffer_len, 1024); | 3028 | * i.e. RXBUFFER_2048 --> size-4096 slab */ |
| 3024 | } else { | 3029 | |
| 3025 | if(unlikely((adapter->hw.mac_type < e1000_82543) && | 3030 | if (max_frame <= E1000_RXBUFFER_256) |
| 3026 | (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { | 3031 | adapter->rx_buffer_len = E1000_RXBUFFER_256; |
| 3027 | DPRINTK(PROBE, ERR, "Jumbo Frames not supported " | 3032 | else if (max_frame <= E1000_RXBUFFER_512) |
| 3028 | "on 82542\n"); | 3033 | adapter->rx_buffer_len = E1000_RXBUFFER_512; |
| 3029 | return -EINVAL; | 3034 | else if (max_frame <= E1000_RXBUFFER_1024) |
| 3030 | } else { | 3035 | adapter->rx_buffer_len = E1000_RXBUFFER_1024; |
| 3031 | if(max_frame <= E1000_RXBUFFER_2048) | 3036 | else if (max_frame <= E1000_RXBUFFER_2048) |
| 3032 | adapter->rx_buffer_len = E1000_RXBUFFER_2048; | 3037 | adapter->rx_buffer_len = E1000_RXBUFFER_2048; |
| 3033 | else if(max_frame <= E1000_RXBUFFER_4096) | 3038 | else if (max_frame <= E1000_RXBUFFER_4096) |
| 3034 | adapter->rx_buffer_len = E1000_RXBUFFER_4096; | 3039 | adapter->rx_buffer_len = E1000_RXBUFFER_4096; |
| 3035 | else if(max_frame <= E1000_RXBUFFER_8192) | 3040 | else if (max_frame <= E1000_RXBUFFER_8192) |
| 3036 | adapter->rx_buffer_len = E1000_RXBUFFER_8192; | 3041 | adapter->rx_buffer_len = E1000_RXBUFFER_8192; |
| 3037 | else if(max_frame <= E1000_RXBUFFER_16384) | 3042 | else if (max_frame <= E1000_RXBUFFER_16384) |
| 3038 | adapter->rx_buffer_len = E1000_RXBUFFER_16384; | 3043 | adapter->rx_buffer_len = E1000_RXBUFFER_16384; |
| 3039 | } | 3044 | |
| 3040 | } | 3045 | /* adjust allocation if LPE protects us, and we aren't using SBP */ |
| 3046 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 | ||
| 3047 | if (!adapter->hw.tbi_compatibility_on && | ||
| 3048 | ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || | ||
| 3049 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) | ||
| 3050 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; | ||
| 3041 | 3051 | ||
| 3042 | netdev->mtu = new_mtu; | 3052 | netdev->mtu = new_mtu; |
| 3043 | 3053 | ||
| @@ -3568,10 +3578,12 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
| 3568 | flags); | 3578 | flags); |
| 3569 | length--; | 3579 | length--; |
| 3570 | } else { | 3580 | } else { |
| 3571 | dev_kfree_skb_irq(skb); | 3581 | /* recycle */ |
| 3582 | buffer_info->skb = skb; | ||
| 3572 | goto next_desc; | 3583 | goto next_desc; |
| 3573 | } | 3584 | } |
| 3574 | } | 3585 | } else |
| 3586 | skb_put(skb, length); | ||
| 3575 | 3587 | ||
| 3576 | /* code added for copybreak, this should improve | 3588 | /* code added for copybreak, this should improve |
| 3577 | * performance for small packets with large amounts | 3589 | * performance for small packets with large amounts |
| @@ -3676,6 +3688,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 3676 | i = rx_ring->next_to_clean; | 3688 | i = rx_ring->next_to_clean; |
| 3677 | rx_desc = E1000_RX_DESC_PS(*rx_ring, i); | 3689 | rx_desc = E1000_RX_DESC_PS(*rx_ring, i); |
| 3678 | staterr = le32_to_cpu(rx_desc->wb.middle.status_error); | 3690 | staterr = le32_to_cpu(rx_desc->wb.middle.status_error); |
| 3691 | buffer_info = &rx_ring->buffer_info[i]; | ||
| 3679 | 3692 | ||
| 3680 | while (staterr & E1000_RXD_STAT_DD) { | 3693 | while (staterr & E1000_RXD_STAT_DD) { |
| 3681 | buffer_info = &rx_ring->buffer_info[i]; | 3694 | buffer_info = &rx_ring->buffer_info[i]; |
| @@ -3736,7 +3749,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 3736 | 3749 | ||
| 3737 | /* page alloc/put takes too long and effects small packet | 3750 | /* page alloc/put takes too long and effects small packet |
| 3738 | * throughput, so unsplit small packets and save the alloc/put*/ | 3751 | * throughput, so unsplit small packets and save the alloc/put*/ |
| 3739 | if (l1 && ((length + l1) < E1000_CB_LENGTH)) { | 3752 | if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { |
| 3740 | u8 *vaddr; | 3753 | u8 *vaddr; |
| 3741 | /* there is no documentation about how to call | 3754 | /* there is no documentation about how to call |
| 3742 | * kmap_atomic, so we can't hold the mapping | 3755 | * kmap_atomic, so we can't hold the mapping |
