[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH for-7.2 v2] rtl8139: honor large send MSS value
From: |
Stefan Hajnoczi |
Subject: |
[PATCH for-7.2 v2] rtl8139: honor large send MSS value |
Date: |
Wed, 16 Nov 2022 10:41:22 -0500 |
The Large-Send Task Offload Tx Descriptor (9.2.1 Transmit) has a
Large-Send MSS value where the driver specifies the MSS. See the
datasheet here:
http://realtek.info/pdf/rtl8139cp.pdf
The code ignores this value and uses a hardcoded MSS of 1500 bytes
instead. When the MTU is less than 1500 bytes the hardcoded value
results in IP fragmentation and poor performance.
Use the Large-Send MSS value to correctly size Large-Send packets.
Jason Wang <jasowang@redhat.com> noticed that the Large-Send MSS value
mask was incorrect so it is adjusted to match the datasheet and Linux
8139cp driver.
This issue was discussed in the past here:
https://lore.kernel.org/all/20161114162505.GD26664@stefanha-x1.localdomain/
Reported-by: Russell King - ARM Linux <linux@armlinux.org.uk>
Reported-by: Tobias Fiebig <tobias+git@fiebig.nl>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1312
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/rtl8139.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
v2:
- Fix MSS mask [Jason]
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index e6643e3c9d..6c406f39ce 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -77,7 +77,6 @@
( ( input ) & ( size - 1 ) )
#define ETHER_TYPE_LEN 2
-#define ETH_MTU 1500
#define VLAN_TCI_LEN 2
#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
@@ -1934,8 +1933,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
#define CP_TX_LS (1<<28)
/* large send packet flag */
#define CP_TX_LGSEN (1<<27)
-/* large send MSS mask, bits 16...25 */
-#define CP_TC_LGSEN_MSS_MASK ((1 << 12) - 1)
+/* large send MSS mask, bits 16...26 */
+#define CP_TC_LGSEN_MSS_SHIFT 16
+#define CP_TC_LGSEN_MSS_MASK ((1 << 11) - 1)
/* IP checksum offload flag */
#define CP_TX_IPCS (1<<18)
@@ -2149,10 +2149,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
goto skip_offload;
}
- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
+ int large_send_mss = (txdw0 >> CP_TC_LGSEN_MSS_SHIFT) &
+ CP_TC_LGSEN_MSS_MASK;
- DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
- "frame data %d specified MSS=%d\n", ETH_MTU,
+ DPRINTF("+++ C+ mode offloaded task TSO IP data %d "
+ "frame data %d specified MSS=%d\n",
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
int tcp_send_offset = 0;
@@ -2177,9 +2178,13 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
goto skip_offload;
}
- /* ETH_MTU = ip header len + tcp header len + payload */
+ /* MSS too small? */
+ if (tcp_hlen + hlen >= large_send_mss) {
+ goto skip_offload;
+ }
+
int tcp_data_len = ip_data_len - tcp_hlen;
- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
+ int tcp_chunk_size = large_send_mss - hlen - tcp_hlen;
DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
"data len %d TCP chunk size %d\n", ip_data_len,
--
2.38.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH for-7.2 v2] rtl8139: honor large send MSS value,
Stefan Hajnoczi <=