This commit is contained in:
JackDoan
2026-04-28 14:53:03 -05:00
parent b9a7d1edf3
commit f5db77f214
3 changed files with 13 additions and 7 deletions

View File

@@ -397,7 +397,7 @@ func (c *TCPCoalescer) flushSlot(s *coalesceSlot) error {
tcsum := s.ipHdrLen + 16 tcsum := s.ipHdrLen + 16
binary.BigEndian.PutUint16(hdr[tcsum:tcsum+2], foldOnceNoInvert(psum)) binary.BigEndian.PutUint16(hdr[tcsum:tcsum+2], foldOnceNoInvert(psum))
return c.gsoW.WriteGSO(hdr, s.payIovs, uint16(s.gsoSize), s.isV6, uint16(s.ipHdrLen)) return c.gsoW.WriteGSO(hdr, s.payIovs, uint16(s.gsoSize), uint16(s.ipHdrLen))
} }
// headersMatch compares two IP+TCP header prefixes for byte-for-byte // headersMatch compares two IP+TCP header prefixes for byte-for-byte

View File

@@ -1,6 +1,8 @@
package tio package tio
import "io" import (
"io"
)
// defaultBatchBufSize is the per-Queue scratch size for Read on backends // defaultBatchBufSize is the per-Queue scratch size for Read on backends
// that don't do TSO segmentation. 65535 covers any single IP packet. // that don't do TSO segmentation. 65535 covers any single IP packet.
@@ -53,6 +55,6 @@ type Queue interface {
// hdr's TCP checksum field must already hold the pseudo-header partial // hdr's TCP checksum field must already hold the pseudo-header partial
// sum (single-fold, not inverted), per virtio NEEDS_CSUM semantics. // sum (single-fold, not inverted), per virtio NEEDS_CSUM semantics.
type GSOWriter interface { type GSOWriter interface {
WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, csumStart uint16) error WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, csumStart uint16) error
GSOSupported() bool GSOSupported() bool
} }

View File

@@ -298,7 +298,7 @@ func (r *Offload) GSOSupported() bool { return true }
// slice is read-only and must stay valid until return. gsoSize is the MSS; // slice is read-only and must stay valid until return. gsoSize is the MSS;
// every segment except possibly the last is exactly gsoSize bytes. // every segment except possibly the last is exactly gsoSize bytes.
// csumStart is the byte offset where the TCP header begins within hdr. // csumStart is the byte offset where the TCP header begins within hdr.
func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, csumStart uint16) error { func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, csumStart uint16) error {
if len(hdr) == 0 || len(pays) == 0 { if len(hdr) == 0 || len(pays) == 0 {
return nil return nil
} }
@@ -309,7 +309,7 @@ func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool,
vhdr := VirtioNetHdr{ vhdr := VirtioNetHdr{
Flags: unix.VIRTIO_NET_HDR_F_NEEDS_CSUM, Flags: unix.VIRTIO_NET_HDR_F_NEEDS_CSUM,
HdrLen: uint16(len(hdr)), HdrLen: uint16(len(hdr)),
GSOSize: gsoSize, GSOSize: uint16(len(pays[0])),
CsumStart: csumStart, CsumStart: csumStart,
CsumOffset: 16, // TCP checksum field lives 16 bytes into the TCP header CsumOffset: 16, // TCP checksum field lives 16 bytes into the TCP header
} }
@@ -318,10 +318,14 @@ func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool,
totalPay += len(p) totalPay += len(p)
} }
if totalPay > int(gsoSize) { if totalPay > int(gsoSize) {
if isV6 { ipVer := hdr[0] >> 4
if ipVer == 6 {
vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV6 vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV6
} else { } else if ipVer == 4 {
vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV4 vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV4
} else {
vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_NONE
vhdr.GSOSize = 0
} }
} else { } else {
vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_NONE vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_NONE