gvisor-lx/pkg/abi/linux/iouring.go
Leadaxe 117243aa02 snapshot: sagernet/gvisor v0.0.0-20260727.0-sing-box-mod.1 + SPEC 048 guard
Обновление снапшота с v0.0.0-20250811.0 на пин, которого требует
sing-box после мержа 235 коммитов (upstream d620bbbf2 "Update gvisor to
20260727.0"). Прежний снапшот был взят 2026-08-04 ровно с той версии,
на которой тогда стоял апстрим; разрыв возник 2026-08-05 вместе с его
бампом.

За год апстрим-gvisor изменил ~14 000 строк в 292 файлах. Значимое для
нас — сетевой стек: tcp/connect.go (PMTU-discovery + исправление
начального RTT/RTO: раньше задержка ACK внутри стека завышала стартовый
таймаут на несколько RTT), tcp/snd.go, tcp/rcv.go, stack/conntrack.go,
stack/packet_buffer.go. Всего 30 файлов в TCP и 37 в stack.

Баг SPEC 048 апстрим НЕ исправил — проверено по коду новой версии:
handleConnecting по-прежнему проверяет состояние endpoint'а, но не ep.h,
а performHandshake так же зануляет h и отпускает мьютекс до Close().
Поэтому guard перенесён (12 строк) вместе со своим тестом (45 строк).

Red/green проверен на новой базе: без guard'а тест падает с той же
nil-паникой, что в полевом крашдампе; с ним зелёный.
2026-08-05 14:53:31 +03:00

249 lines
7.8 KiB
Go

// Copyright 2022 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"structs"
)
// Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h.
const (
IORING_SETUP_IOPOLL = (1 << 0)
IORING_SETUP_SQPOLL = (1 << 1)
IORING_SETUP_SQ_AFF = (1 << 2)
IORING_SETUP_CQSIZE = (1 << 3)
IORING_SETUP_CLAMP = (1 << 4)
IORING_SETUP_ATTACH_WQ = (1 << 5)
IORING_SETUP_R_DISABLED = (1 << 6)
IORING_SETUP_SUBMIT_ALL = (1 << 7)
)
// Constants for io_uring_enter(2). See include/uapi/linux/io_uring.h.
const (
IORING_ENTER_GETEVENTS = (1 << 0)
)
// Constants for IoUringParams.Features. See include/uapi/linux/io_uring.h.
const (
IORING_FEAT_SINGLE_MMAP = (1 << 0)
)
// Constants for IO_URING. See include/uapi/linux/io_uring.h.
const (
IORING_SETUP_COOP_TASKRUN = (1 << 8)
IORING_SETUP_TASKRUN_FLAG = (1 << 9)
IORING_SETUP_SQE128 = (1 << 10)
IORING_SETUP_CQE32 = (1 << 11)
)
// Constants for IO_URING. See io_uring/io_uring.c.
const (
IORING_MAX_ENTRIES = (1 << 15) // 32768
IORING_MAX_CQ_ENTRIES = (2 * IORING_MAX_ENTRIES)
)
// Constants for the offsets for the application to mmap the data it needs.
// See include/uapi/linux/io_uring.h.
const (
IORING_OFF_SQ_RING = 0
IORING_OFF_CQ_RING = 0x8000000
IORING_OFF_SQES = 0x10000000
)
// Constants for the IO_URING opcodes. See include/uapi/linux/io_uring.h.
const (
IORING_OP_NOP = 0
IORING_OP_READV = 1
)
// IORingIndex represents SQE array indexes.
//
// +marshal
type IORingIndex uint32
// IOSqRingOffsets implements io_sqring_offsets struct.
// IOSqRingOffsets represents offsets into IORings.
// See struct io_sqring_offsets in include/uapi/linux/io_uring.h.
//
// +marshal
type IOSqRingOffsets struct {
_ structs.HostLayout
Head uint32 // Offset to io_rings.sq.head
Tail uint32 // Offset to io_rings.sq.tail
RingMask uint32 // Offset to io_rings.sq_ring_mask
RingEntries uint32 // Offset to io_rings.sq_ring_entries
Flags uint32 // Offset to io_rings.sq_flags
Dropped uint32 // Offset to io_rings.sq_dropped
Array uint32 // Offset to an array of SQE indices
Resv1 uint32 // Currently reserved and expected to be zero
Resv2 uint64 // Currently reserved and expected to be zero
}
// IOCqRingOffsets implements io_cqring_offsets struct.
// IOCqRingOffsets represents offsets into IORings.
// See struct io_cqring_offsets in include/uapi/linux/io_uring.h.
//
// +marshal
type IOCqRingOffsets struct {
_ structs.HostLayout
Head uint32 // Offset to io_rings.cq.head
Tail uint32 // Offset to io_rings.cq.tail
RingMask uint32 // Offset to io_rings.cq_ring_mask
RingEntries uint32 // Offset to io_rings.cq_ring_entries
Overflow uint32 // Offset to io_rings.cq_overflow
Cqes uint32 // Offset to io_rings.cqes
Flags uint32 // Offset to io_rings.cq_flags
Resv1 uint32 // Currently reserved and expected to be zero
Resv2 uint64 // Currently reserved and expected to be zero
}
// IOUringParams implements io_uring_params struct.
// See struct io_uring_params in include/uapi/linux/io_uring.h.
//
// +marshal
type IOUringParams struct {
_ structs.HostLayout
SqEntries uint32
CqEntries uint32
Flags uint32
SqThreadCPU uint32
SqThreadIdle uint32
Features uint32
WqFd uint32
Resv [3]uint32
SqOff IOSqRingOffsets
CqOff IOCqRingOffsets
}
// IOUringCqe implements IO completion data structure (Completion Queue Entry)
// io_uring_cqe struct. As we don't currently support IORING_SETUP_CQE32 flag
// its size is 16 bytes.
// See struct io_uring_cqe in include/uapi/linux/io_uring.h.
//
// +marshal
// +stateify savable
type IOUringCqe struct {
_ structs.HostLayout
UserData uint64
Res int32
Flags uint32
}
// IOUring implements io_uring struct.
// See struct io_uring in io_uring/io_uring.c.
//
// +marshal
// +stateify savable
type IOUring struct {
_ structs.HostLayout
// Both head and tail should be cacheline aligned. And we assume that
// cacheline size is 64 bytes.
Head uint32
_ [60]byte
Tail uint32
_ [60]byte
}
// IORings implements io_rings struct.
// This struct describes layout of the mapped region backed by the ringBuffersFile.
// See struct io_rings in io_uring/io_uring.c.
//
// +marshal
// +stateify savable
type IORings struct {
_ structs.HostLayout
Sq IOUring
Cq IOUring
SqRingMask uint32
CqRingMask uint32
SqRingEntries uint32
CqRingEntries uint32
sqDropped uint32
sqFlags int32
cqFlags uint32
CqOverflow uint32
_ [32]byte // Padding so cqes is cacheline aligned
// Linux has an additional field struct io_uring_cqe cqes[], which represents
// a dynamic array. We don't include it here in order to enable marshalling.
}
// IOUringSqe implements io_uring_sqe struct.
// This struct represents IO submission data structure (Submission Queue Entry). As we don't yet
// support IORING_SETUP_SQE128 flag, its size is 64 bytes with no extra padding at the end.
// See include/uapi/linux/io_uring.h.
//
// +marshal
// +stateify savable
type IOUringSqe struct {
_ structs.HostLayout
Opcode uint8
Flags uint8
IoPrio uint16
Fd int32
OffOrAddrOrCmdOp uint64
AddrOrSpliceOff uint64
Len uint32
specialFlags uint32
UserData uint64
BufIndexOrGroup uint16
personality uint16
spliceFDOrFileIndex int32
addr3 uint64
_ uint64
}
const (
_IOSqRingOffset = 0 // +checkoffset . IORings.Sq
_IOSqRingOffsetHead = 0 // +checkoffset . IOUring.Head
_IOSqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
_IOSqRingOffsetMask = 256 // +checkoffset . IORings.SqRingMask
_IOSqRingOffsetEntries = 264 // +checkoffset . IORings.SqRingEntries
_IOSqRingOffsetFlags = 276 // +checkoffset . IORings.sqFlags
_IOSqRingOffsetDropped = 272 // +checkoffset . IORings.sqDropped
)
// PreComputedIOSqRingOffsets returns precomputed values for IOSqRingOffsets.
func PreComputedIOSqRingOffsets() IOSqRingOffsets {
return IOSqRingOffsets{
Head: _IOSqRingOffset + _IOSqRingOffsetHead,
Tail: _IOSqRingOffset + _IOSqRingOffsetTail,
RingMask: _IOSqRingOffsetMask,
RingEntries: _IOSqRingOffsetEntries,
Flags: _IOSqRingOffsetFlags,
Dropped: _IOSqRingOffsetDropped,
}
}
const (
_IOCqRingOffset = 128 // +checkoffset . IORings.Cq
_IOCqRingOffsetHead = 0 // +checkoffset . IOUring.Head
_IOCqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
_IOCqRingOffsetMask = 260 // +checkoffset . IORings.CqRingMask
_IOCqRingOffsetEntries = 268 // +checkoffset . IORings.CqRingEntries
_IOCqRingOffsetFlags = 280 // +checkoffset . IORings.cqFlags
_IOCqRingOffsetOverflow = 284 // +checkoffset . IORings.CqOverflow
)
// PreComputedIOCqRingOffsets returns precomputed values for IOCqRingOffsets.
func PreComputedIOCqRingOffsets() IOCqRingOffsets {
return IOCqRingOffsets{
Head: _IOCqRingOffset + _IOCqRingOffsetHead,
Tail: _IOCqRingOffset + _IOCqRingOffsetTail,
RingMask: _IOCqRingOffsetMask,
RingEntries: _IOCqRingOffsetEntries,
Overflow: _IOCqRingOffsetOverflow,
Flags: _IOCqRingOffsetFlags,
}
}