Skip to content

Commit b27917a

Browse files
committed
Merge branch 'for-6.17/io_uring' into for-next
* for-6.17/io_uring: io_uring/rw: cast rw->flags assignment to rwf_t io_uring: don't use int for ABI io_uring/rsrc: skip atomic refcount for uncloned buffers io_uring/mock: add trivial poll handler io_uring/mock: support for async read/write io_uring/mock: allow to choose FMODE_NOWAIT io_uring/mock: add sync read/write io_uring/mock: add cmd using vectored regbufs io_uring/mock: add basic infra for test mock files io_uring: remove errant ';' from IORING_CQE_F_TSTAMP_HW definition io_uring/netcmd: add tx timestamping cmd support io_uring: add mshot helper for posting CQE32 io_uring/cmd: allow multishot polled commands io_uring/poll: introduce io_arm_apoll() io_uring/nop: add IORING_NOP_TW completion flag io_uring/uring_cmd: implement ->sqe_copy() to avoid unnecessary copies io_uring/uring_cmd: get rid of io_uring_cmd_prep_setup() io_uring: add struct io_cold_def->sqe_copy() method io_uring: add IO_URING_F_INLINE issue flag net: timestamp: add helper returning skb's tx tstamp
2 parents 48cf0fa + 825aea6 commit b27917a

21 files changed

Lines changed: 754 additions & 53 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12681,6 +12681,7 @@ F: include/linux/io_uring.h
1268112681
F: include/linux/io_uring_types.h
1268212682
F: include/trace/events/io_uring.h
1268312683
F: include/uapi/linux/io_uring.h
12684+
F: include/uapi/linux/io_uring/
1268412685
F: io_uring/
1268512686

1268612687
IPMI SUBSYSTEM

include/linux/io_uring_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ enum io_uring_cmd_flags {
2626
IO_URING_F_MULTISHOT = 4,
2727
/* executed by io-wq */
2828
IO_URING_F_IOWQ = 8,
29+
/* executed inline from syscall */
30+
IO_URING_F_INLINE = 16,
2931
/* int's last bit, sign checks are usually faster than a bit test */
3032
IO_URING_F_NONBLOCK = INT_MIN,
3133

@@ -502,6 +504,7 @@ enum {
502504
REQ_F_BUF_NODE_BIT,
503505
REQ_F_HAS_METADATA_BIT,
504506
REQ_F_IMPORT_BUFFER_BIT,
507+
REQ_F_SQE_COPIED_BIT,
505508

506509
/* not a real bit, just to check we're not overflowing the space */
507510
__REQ_F_LAST_BIT,
@@ -591,6 +594,8 @@ enum {
591594
* For SEND_ZC, whether to import buffers (i.e. the first issue).
592595
*/
593596
REQ_F_IMPORT_BUFFER = IO_REQ_FLAG(REQ_F_IMPORT_BUFFER_BIT),
597+
/* ->sqe_copy() has been called, if necessary */
598+
REQ_F_SQE_COPIED = IO_REQ_FLAG(REQ_F_SQE_COPIED_BIT),
594599
};
595600

596601
typedef void (*io_req_tw_func_t)(struct io_kiocb *req, io_tw_token_t tw);

include/net/sock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
26772677
void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
26782678
struct sk_buff *skb);
26792679

2680+
bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
2681+
int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
2682+
struct timespec64 *ts);
2683+
26802684
static inline void
26812685
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
26822686
{

include/uapi/linux/io_uring.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct io_uring_sqe {
5050
};
5151
__u32 len; /* buffer size or number of iovecs */
5252
union {
53-
__kernel_rwf_t rw_flags;
53+
__u32 rw_flags;
5454
__u32 fsync_flags;
5555
__u16 poll_events; /* compatibility */
5656
__u32 poll32_events; /* word-reversed for BE */
@@ -449,6 +449,7 @@ enum io_uring_msg_ring_flags {
449449
#define IORING_NOP_FILE (1U << 1)
450450
#define IORING_NOP_FIXED_FILE (1U << 2)
451451
#define IORING_NOP_FIXED_BUFFER (1U << 3)
452+
#define IORING_NOP_TW (1U << 4)
452453

453454
/*
454455
* IO completion data structure (Completion Queue Entry)
@@ -968,6 +969,22 @@ enum io_uring_socket_op {
968969
SOCKET_URING_OP_SIOCOUTQ,
969970
SOCKET_URING_OP_GETSOCKOPT,
970971
SOCKET_URING_OP_SETSOCKOPT,
972+
SOCKET_URING_OP_TX_TIMESTAMP,
973+
};
974+
975+
/*
976+
* SOCKET_URING_OP_TX_TIMESTAMP definitions
977+
*/
978+
979+
#define IORING_TIMESTAMP_HW_SHIFT 16
980+
/* The cqe->flags bit from which the timestamp type is stored */
981+
#define IORING_TIMESTAMP_TYPE_SHIFT (IORING_TIMESTAMP_HW_SHIFT + 1)
982+
/* The cqe->flags flag signifying whether it's a hardware timestamp */
983+
#define IORING_CQE_F_TSTAMP_HW ((__u32)1 << IORING_TIMESTAMP_HW_SHIFT)
984+
985+
struct io_timespec {
986+
__u64 tv_sec;
987+
__u64 tv_nsec;
971988
};
972989

973990
/* Zero copy receive refill queue entry */
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef LINUX_IO_URING_MOCK_FILE_H
2+
#define LINUX_IO_URING_MOCK_FILE_H
3+
4+
#include <linux/types.h>
5+
6+
enum {
7+
IORING_MOCK_FEAT_CMD_COPY,
8+
IORING_MOCK_FEAT_RW_ZERO,
9+
IORING_MOCK_FEAT_RW_NOWAIT,
10+
IORING_MOCK_FEAT_RW_ASYNC,
11+
IORING_MOCK_FEAT_POLL,
12+
13+
IORING_MOCK_FEAT_END,
14+
};
15+
16+
struct io_uring_mock_probe {
17+
__u64 features;
18+
__u64 __resv[9];
19+
};
20+
21+
enum {
22+
IORING_MOCK_CREATE_F_SUPPORT_NOWAIT = 1,
23+
IORING_MOCK_CREATE_F_POLL = 2,
24+
};
25+
26+
struct io_uring_mock_create {
27+
__u32 out_fd;
28+
__u32 flags;
29+
__u64 file_size;
30+
__u64 rw_delay_ns;
31+
__u64 __resv[13];
32+
};
33+
34+
enum {
35+
IORING_MOCK_MGR_CMD_PROBE,
36+
IORING_MOCK_MGR_CMD_CREATE,
37+
};
38+
39+
enum {
40+
IORING_MOCK_CMD_COPY_REGBUF,
41+
};
42+
43+
enum {
44+
IORING_MOCK_COPY_FROM = 1,
45+
};
46+
47+
#endif

init/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,6 +1805,17 @@ config GCOV_PROFILE_URING
18051805
the io_uring subsystem, hence this should only be enabled for
18061806
specific test purposes.
18071807

1808+
config IO_URING_MOCK_FILE
1809+
tristate "Enable io_uring mock files (Experimental)" if EXPERT
1810+
default n
1811+
depends on IO_URING
1812+
help
1813+
Enable mock files for io_uring subststem testing. The ABI might
1814+
still change, so it's still experimental and should only be enabled
1815+
for specific test purposes.
1816+
1817+
If unsure, say N.
1818+
18081819
config ADVISE_SYSCALLS
18091820
bool "Enable madvise/fadvise syscalls" if EXPERT
18101821
default y

io_uring/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ obj-$(CONFIG_EPOLL) += epoll.o
2121
obj-$(CONFIG_NET_RX_BUSY_POLL) += napi.o
2222
obj-$(CONFIG_NET) += net.o cmd_net.o
2323
obj-$(CONFIG_PROC_FS) += fdinfo.o
24+
obj-$(CONFIG_IO_URING_MOCK_FILE) += mock_file.o

io_uring/cmd_net.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <asm/ioctls.h>
22
#include <linux/io_uring/net.h>
3+
#include <linux/errqueue.h>
34
#include <net/sock.h>
45

56
#include "uring_cmd.h"
@@ -51,6 +52,85 @@ static inline int io_uring_cmd_setsockopt(struct socket *sock,
5152
optlen);
5253
}
5354

55+
static bool io_process_timestamp_skb(struct io_uring_cmd *cmd, struct sock *sk,
56+
struct sk_buff *skb, unsigned issue_flags)
57+
{
58+
struct sock_exterr_skb *serr = SKB_EXT_ERR(skb);
59+
struct io_uring_cqe cqe[2];
60+
struct io_timespec *iots;
61+
struct timespec64 ts;
62+
u32 tstype, tskey;
63+
int ret;
64+
65+
BUILD_BUG_ON(sizeof(struct io_uring_cqe) != sizeof(struct io_timespec));
66+
67+
ret = skb_get_tx_timestamp(skb, sk, &ts);
68+
if (ret < 0)
69+
return false;
70+
71+
tskey = serr->ee.ee_data;
72+
tstype = serr->ee.ee_info;
73+
74+
cqe->user_data = 0;
75+
cqe->res = tskey;
76+
cqe->flags = IORING_CQE_F_MORE;
77+
cqe->flags |= tstype << IORING_TIMESTAMP_TYPE_SHIFT;
78+
if (ret == SOF_TIMESTAMPING_TX_HARDWARE)
79+
cqe->flags |= IORING_CQE_F_TSTAMP_HW;
80+
81+
iots = (struct io_timespec *)&cqe[1];
82+
iots->tv_sec = ts.tv_sec;
83+
iots->tv_nsec = ts.tv_nsec;
84+
return io_uring_cmd_post_mshot_cqe32(cmd, issue_flags, cqe);
85+
}
86+
87+
static int io_uring_cmd_timestamp(struct socket *sock,
88+
struct io_uring_cmd *cmd,
89+
unsigned int issue_flags)
90+
{
91+
struct sock *sk = sock->sk;
92+
struct sk_buff_head *q = &sk->sk_error_queue;
93+
struct sk_buff *skb, *tmp;
94+
struct sk_buff_head list;
95+
int ret;
96+
97+
if (!(issue_flags & IO_URING_F_CQE32))
98+
return -EINVAL;
99+
ret = io_cmd_poll_multishot(cmd, issue_flags, EPOLLERR);
100+
if (unlikely(ret))
101+
return ret;
102+
103+
if (skb_queue_empty_lockless(q))
104+
return -EAGAIN;
105+
__skb_queue_head_init(&list);
106+
107+
scoped_guard(spinlock_irq, &q->lock) {
108+
skb_queue_walk_safe(q, skb, tmp) {
109+
/* don't support skbs with payload */
110+
if (!skb_has_tx_timestamp(skb, sk) || skb->len)
111+
continue;
112+
__skb_unlink(skb, q);
113+
__skb_queue_tail(&list, skb);
114+
}
115+
}
116+
117+
while (1) {
118+
skb = skb_peek(&list);
119+
if (!skb)
120+
break;
121+
if (!io_process_timestamp_skb(cmd, sk, skb, issue_flags))
122+
break;
123+
__skb_dequeue(&list);
124+
consume_skb(skb);
125+
}
126+
127+
if (!unlikely(skb_queue_empty(&list))) {
128+
scoped_guard(spinlock_irqsave, &q->lock)
129+
skb_queue_splice(q, &list);
130+
}
131+
return -EAGAIN;
132+
}
133+
54134
int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
55135
{
56136
struct socket *sock = cmd->file->private_data;
@@ -76,6 +156,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
76156
return io_uring_cmd_getsockopt(sock, cmd, issue_flags);
77157
case SOCKET_URING_OP_SETSOCKOPT:
78158
return io_uring_cmd_setsockopt(sock, cmd, issue_flags);
159+
case SOCKET_URING_OP_TX_TIMESTAMP:
160+
return io_uring_cmd_timestamp(sock, cmd, issue_flags);
79161
default:
80162
return -EOPNOTSUPP;
81163
}

0 commit comments

Comments
 (0)