mirror of
https://github.com/tailscale/tailscale.git
synced 2026-04-04 06:36:01 -04:00
add capability check
This commit is contained in:
@@ -21,3 +21,42 @@ func Available() bool {
|
||||
|
||||
// DisabledError indicates that io_uring was explicitly disabled.
|
||||
var DisabledError = errors.New("io_uring disabled")
|
||||
|
||||
type IORingOp = int
|
||||
|
||||
//https://unixism.net/loti/tutorial/probe_liburing.html
|
||||
const (
|
||||
IORING_OP_NOP IORingOp = iota
|
||||
IORING_OP_READV
|
||||
IORING_OP_WRITEV
|
||||
IORING_OP_FSYNC
|
||||
IORING_OP_READ_FIXED
|
||||
IORING_OP_WRITE_FIXED
|
||||
IORING_OP_POLL_ADD
|
||||
IORING_OP_POLL_REMOVE
|
||||
IORING_OP_SYNC_FILE_RANGE
|
||||
IORING_OP_SENDMSG
|
||||
IORING_OP_RECVMSG
|
||||
IORING_OP_TIMEOUT
|
||||
IORING_OP_TIMEOUT_REMOVE
|
||||
IORING_OP_ACCEPT
|
||||
IORING_OP_ASYNC_CANCEL
|
||||
IORING_OP_LINK_TIMEOUT
|
||||
IORING_OP_CONNECT
|
||||
IORING_OP_FALLOCATE
|
||||
IORING_OP_OPENAT
|
||||
IORING_OP_CLOSE
|
||||
IORING_OP_FILES_UPDATE
|
||||
IORING_OP_STATX
|
||||
IORING_OP_READ
|
||||
IORING_OP_WRITE
|
||||
IORING_OP_FADVISE
|
||||
IORING_OP_MADVISE
|
||||
IORING_OP_SEND
|
||||
IORING_OP_RECV
|
||||
IORING_OP_OPENAT2
|
||||
IORING_OP_EPOLL_CTL
|
||||
IORING_OP_SPLICE
|
||||
IORING_OP_PROVIDE_BUFFERS
|
||||
IORING_OP_REMOVE_BUFFERS
|
||||
)
|
||||
|
||||
@@ -182,6 +182,15 @@ static int set_deadline(struct io_uring *ring, int64_t sec, long long ns) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// index of io uring capability
|
||||
static int has_capability(int i) {
|
||||
int supported;
|
||||
struct io_uring_probe *probe = io_uring_get_probe();
|
||||
supported = io_uring_opcode_supported(probe, i);
|
||||
free(probe);
|
||||
return supported;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int has_io_uring(void) {
|
||||
|
||||
@@ -71,6 +71,24 @@ type UDPConn struct {
|
||||
reads int32
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
// checks capabilities available on this system
|
||||
capabilities map[IORingOp]bool
|
||||
)
|
||||
|
||||
func checkCapability(op IORingOp) bool {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if v, ok := capabilities[op]; ok {
|
||||
return v
|
||||
}
|
||||
|
||||
has_op := C.has_capability(C.int(op)) == 1
|
||||
capabilities[op] = has_op
|
||||
return has_op
|
||||
}
|
||||
|
||||
func NewUDPConn(pconn net.PacketConn) (*UDPConn, error) {
|
||||
if !*useIOURing {
|
||||
return nil, DisabledError
|
||||
|
||||
@@ -52,10 +52,10 @@ func TestUDPSendRecv(t *testing.T) {
|
||||
Port: TestPort,
|
||||
}
|
||||
|
||||
func NewUDPTestServer(t *testing.T) error {
|
||||
func NewUDPTestServer(t *testing.T) (closer func() error, err error) {
|
||||
conn, err := net.ListenUDP("udp", serverAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
@@ -67,7 +67,7 @@ func NewUDPTestServer(t *testing.T) error {
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
return conn.Close, nil
|
||||
}
|
||||
|
||||
func TestUDPConn(t *testing.T) {
|
||||
@@ -76,8 +76,9 @@ func TestUDPConn(t *testing.T) {
|
||||
}
|
||||
c := qt.New(t)
|
||||
// TODO add a closer here
|
||||
err := NewUDPTestServer(t)
|
||||
closer, err := NewUDPTestServer(t)
|
||||
c.Assert(err, qt.IsNil)
|
||||
t.Cleanup(func() { closer() })
|
||||
udpConn, err := net.DialUDP("udp", nil, serverAddr)
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer udpConn.Close()
|
||||
@@ -94,7 +95,7 @@ func TestUDPConn(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test many writes at once
|
||||
for i := 0; i < 1000; i++ {
|
||||
for i := 0; i < 256; i++ {
|
||||
n, err := conn.WriteTo(content, serverAddr)
|
||||
c.Assert(err, qt.IsNil)
|
||||
if n != len(content) {
|
||||
|
||||
Reference in New Issue
Block a user