diff options
| author | msaitoh <msaitoh@NetBSD.org> | 2021-09-16 09:55:28 +0000 |
|---|---|---|
| committer | msaitoh <msaitoh@NetBSD.org> | 2021-09-16 09:55:28 +0000 |
| commit | 9b9fa16f4b6e99f3f453222d6f816e1a18361649 (patch) | |
| tree | 9a2b5107c12645c5afcc385403e50b6157ee7460 /sys/dev/microcode | |
| parent | 6eb3797afe669b9d976b332677dbba603db903b0 (diff) | |
Fix a bug that an mbuf chain which has more than 63488bytes MAY fail on TX.
- Currently, The TX buffer dmamap's max number of segments is set to 32.
MCLBYTES(== 2048) * 32 = 65536 and it's enough for IP_MAXPACKET(65535).
If an mbuf chain has more than 32 mbufs, we call m_defrag() to make
it lower than equal to 32, but it might not work. The reason is that
our m_defrag() don't modify the first mbuf entry of the chain. e.g.:
if an mbuf chain contains 63600bytes data and the first mbuf has 100bytes
in the m_data, the new chain has 100+2048+2048+...+12 and the total number
of the chain is not 32 but 33. It result in 43 TCP packets will drop.
- One of the way to fix this problem is to change m_defrag() which add a
new mbuf cluster to the first mbuf. It's need discussion.
- Another solution is to change the max number of the TX DMA segment.
It should be at least 33 to avoid the m_defrag()'s current limitation.
The document (82599-X550 DS 7.2.1.1 "Transmit Storage in system Memory")
says that a packet can be fragmented into 40 - WTHRESH - 2 (for 82598,
the document say nothing and some people and code says it's unlimited).
Currently WTHRESH is set to 8. 40 - 8 - 2 = 30. !?!?!? {Net,Free,Open}BSD
and Linux use 32. Is that safe? Anyway, we change WTHRESH from 8 to 5
to fit it. The added comment in ixgbe.h is based on DragonFly's
though they don't use WTHRESH.
- Yet another solution is to use the Tx Head Pointer Write Back function
instead of WTHRESH based write back (see 82599-X550 DS 7.2.3.5.2
"Tx Head Pointer Write Back" or 82598 "Transmit Completions Head Write Back"
). DragonFly, illumos and DPDK use it.
- Yet yet another solution is to add tso_maxsize entry to struct ifnet
and use it in the TCP stack.
Diffstat (limited to 'sys/dev/microcode')
0 files changed, 0 insertions, 0 deletions
