Skip to contentSkip to conversation

io_uring cmd for tx timestamps

PATCH Applied Pavel Begunkov 5 participants 28 messages Jun 16, 2025 – Jul 8, 2025

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v5 cover io_uring cmd for tx timestamps

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

It should be reasonable to take it through the io_uring tree once we have consensus, but let me know if there are any concerns.

v5: return SOF_TIMESTAMPING_TX_* from net helpers

v4: rename uapi flags, etc.

v3: Add a flag to distinguish sw vs hw timestamp. skb_get_tx_timestamp()
from Patch 1 now returns the indication of that, and in Patch 5 it's converted into a io_uring CQE bit flag.

v2: remove (rx) false timestamp handling
fix skipping already queued events on request submission constantize socket in a helper

Pavel Begunkov (5):
net: timestamp: add helper returning skb's tx tstamp io_uring/poll: introduce io_arm_apoll() io_uring/cmd: allow multishot polled commands
io_uring: add mshot helper for posting CQE32 io_uring/netcmd: add tx timestamping cmd support

 include/net/sock.h            |  4 ++
 include/uapi/linux/io_uring.h | 16 +++++++
 io_uring/cmd_net.c            | 82 +++++++++++++++++++++++++++++++++++
 io_uring/io_uring.c           | 40 +++++++++++++++++
 io_uring/io_uring.h           |  1 +
 io_uring/poll.c               | 44 +++++++++++--------
 io_uring/poll.h               |  1 +
 io_uring/uring_cmd.c          | 34 +++++++++++++++
 io_uring/uring_cmd.h          |  7 +++
 net/socket.c                  | 46 ++++++++++++++++++++
 10 files changed, 258 insertions(+), 17 deletions(-)
Signature · 1 line
2.49.0
#1 lore raw

PATCH v5 1/5 net: timestamp: add helper returning skb's tx tstamp

Add a helper function skb_get_tx_timestamp() that returns a tx timestamp associated with an error queue skb.

---
 include/net/sock.h |  4 ++++
 net/socket.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
include/net/sock.h +4 -0
index 92e7c1aae3cc..f5f5a9ad290b 100644
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
 			     struct sk_buff *skb);
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
+int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
+			 struct timespec64 *ts);
+
 static inline void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
net/socket.c +46 -0

52 lines not on this page · raw message

Signature · 1 line
2.49.0
#3 lore raw

Re: [PATCH v5 1/5] net: timestamp: add helper returning skb's tx tstamp

In reply to Pavel Begunkov
Quoted 29 lines · Pavel Begunkov

Add a helper function skb_get_tx_timestamp() that returns a tx timestamp associated with an error queue skb.

---
 include/net/sock.h |  4 ++++
 net/socket.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
include/net/sock.h +4 -0
index 92e7c1aae3cc..f5f5a9ad290b 100644
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
 			     struct sk_buff *skb);
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
+int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
+			 struct timespec64 *ts);
+
 static inline void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
net/socket.c +0 -0
index 9a0e720f0859..2cab805943c0 100644

net/socket.c static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, · line 847

Quoted 5 lines
net/socket.c +2 -0
@@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
 		 sizeof(ts_pktinfo), &ts_pktinfo);
 }
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk)
+{

I forgot to ask earlier, and not a reason for a respin.

Is the only reason that skb is not const here skb_hwtstamps?

I can send a patch to make that container_of_const

#4 lore raw

Re: [PATCH v5 1/5] net: timestamp: add helper returning skb's tx tstamp

Quoted 33 lines · Willem de Bruijn
Quoted 32 lines · Pavel Begunkov

Add a helper function skb_get_tx_timestamp() that returns a tx timestamp associated with an error queue skb.

---
  include/net/sock.h |  4 ++++
  net/socket.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 50 insertions(+)
include/net/sock.h +4 -0
index 92e7c1aae3cc..f5f5a9ad290b 100644
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
  void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
  			     struct sk_buff *skb);
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
+int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
+			 struct timespec64 *ts);
+
  static inline void
  sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
  {
net/socket.c +0 -0
index 9a0e720f0859..2cab805943c0 100644
@@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
  		 sizeof(ts_pktinfo), &ts_pktinfo);
  }
 
Quoted 6 lines

net/socket.c static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, · line 847

Quoted 2 lines
net/socket.c +2 -0
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk)
+{

I forgot to ask earlier, and not a reason for a respin.

Is the only reason that skb is not const here skb_hwtstamps?

Yes, and also get_timestamp() for skb_get_tx_timestamp(). It's easy to patch, but I was hoping we can merge it through the io_uring tree without deps on net-next and add const to the new helpers after. It's definitely less trouble than orchestrating a separate branch otherwise. FWIW, it'd be fine to add const to the existing helpers in the meantime as long as the new functions stay non-const for now. Hope that works

Signature · 1 line
Pavel Begunkov
#5 lore raw

Re: [PATCH v5 1/5] net: timestamp: add helper returning skb's tx tstamp

Quoted 39 lines · Pavel Begunkov
Quoted 38 lines · Willem de Bruijn
Quoted 29 lines · Pavel Begunkov

Add a helper function skb_get_tx_timestamp() that returns a tx timestamp associated with an error queue skb.

---
  include/net/sock.h |  4 ++++
  net/socket.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 50 insertions(+)
include/net/sock.h +4 -0
index 92e7c1aae3cc..f5f5a9ad290b 100644
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
  void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
  			     struct sk_buff *skb);
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
+int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
+			 struct timespec64 *ts);
+
  static inline void
  sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
  {
net/socket.c +0 -0
index 9a0e720f0859..2cab805943c0 100644

net/socket.c static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, · line 847

Quoted 5 lines
net/socket.c +2 -0
@@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
  		 sizeof(ts_pktinfo), &ts_pktinfo);
  }
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk)
+{

I forgot to ask earlier, and not a reason for a respin.

Quoted 6 lines
Quoted 1 line

Is the only reason that skb is not const here skb_hwtstamps?

Yes, and also get_timestamp() for skb_get_tx_timestamp(). It's easy to patch, but I was hoping we can merge it through the io_uring tree without deps on net-next and add const to the new helpers after. It's definitely less trouble than orchestrating a separate branch otherwise.

Makes sense.

Quoted 3 lines

FWIW, it'd be fine to add
const to the existing helpers in the meantime as long as the new functions stay non-const for now. Hope that works

Yeah, agreed no need to add such dependencies.

Quoted 3 lines
Signature · 1 line
Pavel Begunkov
#6 lore raw

Re: [PATCH v5 1/5] net: timestamp: add helper returning skb's tx tstamp

In reply to Willem de Bruijn
Quoted 33 lines · Willem de Bruijn
Quoted 32 lines · Pavel Begunkov

Add a helper function skb_get_tx_timestamp() that returns a tx timestamp associated with an error queue skb.

---
 include/net/sock.h |  4 ++++
 net/socket.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
include/net/sock.h +4 -0
index 92e7c1aae3cc..f5f5a9ad290b 100644
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
 			     struct sk_buff *skb);
 
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
+int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
+			 struct timespec64 *ts);
+
 static inline void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
net/socket.c +0 -0
index 9a0e720f0859..2cab805943c0 100644
@@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
 		 sizeof(ts_pktinfo), &ts_pktinfo);
 }
 
Quoted 8 lines

net/socket.c static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, · line 847

Quoted 2 lines
net/socket.c +2 -0
+bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk)
+{

I forgot to ask earlier, and not a reason for a respin.

Is the only reason that skb is not const here skb_hwtstamps?

I can send a patch to make that container_of_const

Just to follow up.

The container_of_const is not applicable here. As skb_shared_info is a (cast) pointer, into skb linear.

So even simpler, the skb can be const even if what its member points to is not. This works fine.

-static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) +static inline struct skb_shared_hwtstamps *skb_hwtstamps(const struct sk_buff *skb)

 {
        return &skb_shinfo(skb)->hwtstamps;

}

And same for skb_zcopy, skb_zcopy_init, skb_zcopy_set, skb_zcopy_set_nouarg, skb_zcopy_is_nouarg, skb_zcopy_get_nouarg, skb_zcopy_clear, __skb_zcopy_downgrade_managed, skb_zcopy_downgrade_managed, skb_frag_ref and the ubuf_info_ops complete and link callbacks.

But that's a lot of churn, especially if including ubuf_info implementations like io_uring.

Not sure it's worth that.

#8 lore raw

PATCH v5 2/5 io_uring/poll: introduce io_arm_apoll()

In reply to Pavel Begunkov

In preparation to allowing commands to do file polling, add a helper that takes the desired poll event mask and arms it for polling. We won't be able to use io_arm_poll_handler() with IORING_OP_URING_CMD as it tries to infer the mask from the opcode data, and we can't unify it across all commands.

---
 io_uring/poll.c | 44 +++++++++++++++++++++++++++-----------------
 io_uring/poll.h |  1 +
 2 files changed, 28 insertions(+), 17 deletions(-)
io_uring/poll.c +27 -17
index 0526062e2f81..c7e9fb34563d 100644
@@ -669,33 +669,18 @@ static struct async_poll *io_req_alloc_apoll(struct io_kiocb *req,
 	return apoll;
 }
 
-int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
+int io_arm_apoll(struct io_kiocb *req, unsigned issue_flags, __poll_t mask)
 {
-	const struct io_issue_def *def = &io_issue_defs[req->opcode];
 	struct async_poll *apoll;
 	struct io_poll_table ipt;
-	__poll_t mask = POLLPRI | POLLERR | EPOLLET;
 	int ret;
 
-	if (!def->pollin && !def->pollout)
-		return IO_APOLL_ABORTED;
+	mask |= EPOLLET;
 	if (!io_file_can_poll(req))
 		return IO_APOLL_ABORTED;
 	if (!(req->flags & REQ_F_APOLL_MULTISHOT))
 		mask |= EPOLLONESHOT;
 
-	if (def->pollin) {
-		mask |= EPOLLIN | EPOLLRDNORM;
-
-		/* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */
-		if (req->flags & REQ_F_CLEAR_POLLIN)
-			mask &= ~EPOLLIN;
-	} else {
-		mask |= EPOLLOUT | EPOLLWRNORM;
-	}
-	if (def->poll_exclusive)
-		mask |= EPOLLEXCLUSIVE;
-
 	apoll = io_req_alloc_apoll(req, issue_flags);
 	if (!apoll)
 		return IO_APOLL_ABORTED;
@@ -712,6 +697,31 @@ int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
 	return IO_APOLL_OK;
 }
 
+int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
+{
+	const struct io_issue_def *def = &io_issue_defs[req->opcode];
+	__poll_t mask = POLLPRI | POLLERR;
+
+	if (!def->pollin && !def->pollout)
+		return IO_APOLL_ABORTED;
+	if (!io_file_can_poll(req))
+		return IO_APOLL_ABORTED;
+
+	if (def->pollin) {
+		mask |= EPOLLIN | EPOLLRDNORM;
+
+		/* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */
+		if (req->flags & REQ_F_CLEAR_POLLIN)
+			mask &= ~EPOLLIN;
+	} else {
+		mask |= EPOLLOUT | EPOLLWRNORM;
+	}
+	if (def->poll_exclusive)
+		mask |= EPOLLEXCLUSIVE;
+
+	return io_arm_apoll(req, issue_flags, mask);
+}
+
 /*
  * Returns true if we found and killed one or more poll requests
  */
io_uring/poll.h +1 -0
index 27e2db2ed4ae..c8438286dfa0 100644
@@ -41,6 +41,7 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags);
 struct io_cancel_data;
 int io_poll_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
 		   unsigned issue_flags);
+int io_arm_apoll(struct io_kiocb *req, unsigned issue_flags, __poll_t mask);
 int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags);
 bool io_poll_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx,
 			bool cancel_all);
Signature · 1 line
2.49.0
#9 lore raw

PATCH v5 3/5 io_uring/cmd: allow multishot polled commands

In reply to Pavel Begunkov

Some commands like timestamping in the next patch can make use of multishot polling, i.e. REQ_F_APOLL_MULTISHOT. Add support for that, which is condensed in a single helper called io_cmd_poll_multishot().

The user who wants to continue with a request in a multishot mode must call the function, and only if it returns 0 the user is free to proceed. Apart from normal terminal errors, it can also end up with -EIOCBQUEUED, in which case the user must forward it to the core io_uring. It's forbidden to use task work while the request is executing in a multishot mode.

The API is not foolproof, hence it's not exported to modules nor exposed in public headers.

---
 io_uring/uring_cmd.c | 23 +++++++++++++++++++++++
 io_uring/uring_cmd.h |  3 +++
 2 files changed, 26 insertions(+)
io_uring/uring_cmd.c +23 -0
index 9ad0ea5398c2..02cec6231831 100644
@@ -12,6 +12,7 @@
 #include "alloc_cache.h"
 #include "rsrc.h"
 #include "uring_cmd.h"
+#include "poll.h"
 
 void io_cmd_cache_free(const void *entry)
 {
@@ -136,6 +137,9 @@ void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
 {
 	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
 
+	if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT))
+		return;
+
 	ioucmd->task_work_cb = task_work_cb;
 	req->io_task_work.func = io_uring_cmd_work;
 	__io_req_task_work_add(req, flags);
@@ -158,6 +162,9 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, u64 res2,
 {
 	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
 
+	if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT))
+		return;
+
 	io_uring_cmd_del_cancelable(ioucmd, issue_flags);
 
 	if (ret < 0)
@@ -305,3 +312,19 @@ void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd)
 
 	io_req_queue_iowq(req);
 }
+
+int io_cmd_poll_multishot(struct io_uring_cmd *cmd,
+			  unsigned int issue_flags, __poll_t mask)
+{
+	struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+	int ret;
+
+	if (likely(req->flags & REQ_F_APOLL_MULTISHOT))
+		return 0;
+
+	req->flags |= REQ_F_APOLL_MULTISHOT;
+	mask &= ~EPOLLONESHOT;
+
+	ret = io_arm_apoll(req, issue_flags, mask);
+	return ret == IO_APOLL_OK ? -EIOCBQUEUED : -ECANCELED;
+}
io_uring/uring_cmd.h +3 -0
index a6dad47afc6b..50a6ccb831df 100644
@@ -18,3 +18,6 @@ bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
 				   struct io_uring_task *tctx, bool cancel_all);
 
 void io_cmd_cache_free(const void *entry);
+
+int io_cmd_poll_multishot(struct io_uring_cmd *cmd,
+			  unsigned int issue_flags, __poll_t mask);
Signature · 1 line
2.49.0
#10 lore raw

PATCH v5 4/5 io_uring: add mshot helper for posting CQE32

In reply to Pavel Begunkov

Add a helper for posting 32 byte CQEs in a multishot mode and add a cmd helper on top. As it specifically works with requests, the helper ignore the passed in cqe->user_data and sets it to the one stored in the request.

The command helper is only valid with multishot requests.

---
 io_uring/io_uring.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 io_uring/io_uring.h  |  1 +
 io_uring/uring_cmd.c | 11 +++++++++++
 io_uring/uring_cmd.h |  4 ++++
 4 files changed, 56 insertions(+)
io_uring/io_uring.c +40 -0
index 98a701fc56cc..4352cf209450 100644
@@ -793,6 +793,21 @@ bool io_cqe_cache_refill(struct io_ring_ctx *ctx, bool overflow)
 	return true;
 }
 
+static bool io_fill_cqe_aux32(struct io_ring_ctx *ctx,
+			      struct io_uring_cqe src_cqe[2])
+{
+	struct io_uring_cqe *cqe;
+
+	if (WARN_ON_ONCE(!(ctx->flags & IORING_SETUP_CQE32)))
+		return false;
+	if (unlikely(!io_get_cqe(ctx, &cqe)))
+		return false;
+
+	memcpy(cqe, src_cqe, 2 * sizeof(*cqe));
+	trace_io_uring_complete(ctx, NULL, cqe);
+	return true;
+}
+
 static bool io_fill_cqe_aux(struct io_ring_ctx *ctx, u64 user_data, s32 res,
 			      u32 cflags)
 {
@@ -904,6 +919,31 @@ bool io_req_post_cqe(struct io_kiocb *req, s32 res, u32 cflags)
 	return posted;
 }
 
+/*
+ * A helper for multishot requests posting additional CQEs.
+ * Should only be used from a task_work including IO_URING_F_MULTISHOT.
+ */
+bool io_req_post_cqe32(struct io_kiocb *req, struct io_uring_cqe cqe[2])
+{
+	struct io_ring_ctx *ctx = req->ctx;
+	bool posted;
+
+	lockdep_assert(!io_wq_current_is_worker());
+	lockdep_assert_held(&ctx->uring_lock);
+
+	cqe[0].user_data = req->cqe.user_data;
+	if (!ctx->lockless_cq) {
+		spin_lock(&ctx->completion_lock);
+		posted = io_fill_cqe_aux32(ctx, cqe);
+		spin_unlock(&ctx->completion_lock);
+	} else {
+		posted = io_fill_cqe_aux32(ctx, cqe);
+	}
+
+	ctx->submit_state.cq_flush = true;
+	return posted;
+}
+
 static void io_req_complete_post(struct io_kiocb *req, unsigned issue_flags)
 {
 	struct io_ring_ctx *ctx = req->ctx;
io_uring/io_uring.h +1 -0
index d59c12277d58..1263af818c47 100644
@@ -81,6 +81,7 @@ void io_req_defer_failed(struct io_kiocb *req, s32 res);
 bool io_post_aux_cqe(struct io_ring_ctx *ctx, u64 user_data, s32 res, u32 cflags);
 void io_add_aux_cqe(struct io_ring_ctx *ctx, u64 user_data, s32 res, u32 cflags);
 bool io_req_post_cqe(struct io_kiocb *req, s32 res, u32 cflags);
+bool io_req_post_cqe32(struct io_kiocb *req, struct io_uring_cqe src_cqe[2]);
 void __io_commit_cqring_flush(struct io_ring_ctx *ctx);
 
 void io_req_track_inflight(struct io_kiocb *req);
io_uring/uring_cmd.c +11 -0
index 02cec6231831..b228b84a510f 100644
@@ -328,3 +328,14 @@ int io_cmd_poll_multishot(struct io_uring_cmd *cmd,
 	ret = io_arm_apoll(req, issue_flags, mask);
 	return ret == IO_APOLL_OK ? -EIOCBQUEUED : -ECANCELED;
 }
+
+bool io_uring_cmd_post_mshot_cqe32(struct io_uring_cmd *cmd,
+				   unsigned int issue_flags,
+				   struct io_uring_cqe cqe[2])
+{
+	struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+
+	if (WARN_ON_ONCE(!(issue_flags & IO_URING_F_MULTISHOT)))
+		return false;
+	return io_req_post_cqe32(req, cqe);
+}
io_uring/uring_cmd.h +4 -0
index 50a6ccb831df..9e11da10ecab 100644
@@ -17,6 +17,10 @@ void io_uring_cmd_cleanup(struct io_kiocb *req);
 bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
 				   struct io_uring_task *tctx, bool cancel_all);
 
+bool io_uring_cmd_post_mshot_cqe32(struct io_uring_cmd *cmd,
+				   unsigned int issue_flags,
+				   struct io_uring_cqe cqe[2]);
+
 void io_cmd_cache_free(const void *entry);
 
 int io_cmd_poll_multishot(struct io_uring_cmd *cmd,
Signature · 1 line
2.49.0
#11 lore raw

PATCH v5 5/5 io_uring/netcmd: add tx timestamping cmd support

In reply to Pavel Begunkov

Add a new socket command which returns tx time stamps to the user. It provide an alternative to the existing error queue recvmsg interface. The command works in a polled multishot mode, which means io_uring will poll the socket and keep posting timestamps until the request is cancelled or fails in any other way (e.g. with no space in the CQ). It reuses the net infra and grabs timestamps from the socket's error queue.

The command requires IORING_SETUP_CQE32. All non-final CQEs (marked with IORING_CQE_F_MORE) have cqe->res set to the tskey, and the upper 16 bits of cqe->flags keep tstype (i.e. offset by IORING_CQE_BUFFER_SHIFT). The timevalue is store in the upper part of the extended CQE. The final completion won't have IORING_CQE_F_MORE and will have cqe->res storing 0/error.

---
 include/uapi/linux/io_uring.h | 16 +++++++
 io_uring/cmd_net.c            | 82 +++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)
include/uapi/linux/io_uring.h +16 -0
index cfd17e382082..dcadf709bfc4 100644
@@ -968,6 +968,22 @@ enum io_uring_socket_op {
 	SOCKET_URING_OP_SIOCOUTQ,
 	SOCKET_URING_OP_GETSOCKOPT,
 	SOCKET_URING_OP_SETSOCKOPT,
+	SOCKET_URING_OP_TX_TIMESTAMP,
+};
+
+/*
+ * SOCKET_URING_OP_TX_TIMESTAMP definitions
+ */
+
+#define IORING_TIMESTAMP_HW_SHIFT	16
+/* The cqe->flags bit from which the timestamp type is stored */
+#define IORING_TIMESTAMP_TYPE_SHIFT	(IORING_TIMESTAMP_HW_SHIFT + 1)
+/* The cqe->flags flag signifying whether it's a hardware timestamp */
+#define IORING_CQE_F_TSTAMP_HW		((__u32)1 << IORING_TIMESTAMP_HW_SHIFT);
+
+struct io_timespec {
+	__u64		tv_sec;
+	__u64		tv_nsec;
 };
 
 /* Zero copy receive refill queue entry */
io_uring/cmd_net.c +82 -0

99 lines not on this page · raw message

Signature · 1 line
2.49.0
maintainer
#12 lore raw
In reply to Pavel Begunkov
Quoted 6 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

Quoted 6 lines

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

It should be reasonable to take it through the io_uring tree once we have consensus, but let me know if there are any concerns.

Sounds like we're good to queue this up for 6.17?

Signature · 1 line
Jens Axboe
maintainer
#13 lore raw
Quoted 7 lines · On Tue, 17 Jun 2025 08:52:35 -0600 Jens Axboe wrote:
Quoted 6 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

Quoted 8 lines
Quoted 6 lines

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

It should be reasonable to take it through the io_uring tree once we have consensus, but let me know if there are any concerns.

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

maintainer
#14 lore raw
Quoted 12 lines · Jakub Kicinski
Quoted 11 lines · On Tue, 17 Jun 2025 08:52:35 -0600 Jens Axboe wrote:
Quoted 10 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

It should be reasonable to take it through the io_uring tree once we have consensus, but let me know if there are any concerns.

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Signature · 1 line
Jens Axboe
maintainer
#15 lore raw
Quoted 9 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:
Quoted 5 lines
Quoted 1 line

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

maintainer
#16 lore raw
Quoted 7 lines · Jakub Kicinski
Quoted 6 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:
Quoted 5 lines
Quoted 1 line

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

Quoted 7 lines
Quoted 3 lines

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Perfect, thanks Jakub!

Signature · 1 line
Jens Axboe
maintainer
#17 lore raw
In reply to Jakub Kicinski
Quoted 7 lines · Jakub Kicinski
Quoted 6 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:
Quoted 5 lines
Quoted 1 line

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

Quoted 7 lines
Quoted 3 lines

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Branch seems to be gone?

Signature · 1 line
Jens Axboe
#18 lore raw
Quoted 12 lines · Jens Axboe
Quoted 11 lines · Jakub Kicinski
Quoted 9 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:
Quoted 5 lines
Quoted 1 line

Sounds like we're good to queue this up for 6.17?

I think so. Can I apply patch 1 off v6.16-rc1 and merge it in to net-next? Hash will be 2410251cde0bac9f6, you can pull that across. LMK if that works.

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Quoted 5 lines
Quoted 3 lines

Like this?

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Branch seems to be gone?

Anything against just taking the hash from net-next, turning into a branch and then merging that? E.g.

https://github.com/isilence/linux.git io_uring-tx-timestamp-net-helpers

Signature · 1 line
Pavel Begunkov
maintainer
#19 lore raw
In reply to Jens Axboe
Quoted 11 lines · On Fri, 20 Jun 2025 08:31:25 -0600 Jens Axboe wrote:
Quoted 8 lines · Jakub Kicinski
Quoted 3 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Branch seems to be gone?

Ah, I deleted when I was forwarding to Linus yesterday. I figured you already pulled, sorry about that. I've pushed it out again now.

maintainer
#20 lore raw
Quoted 9 lines · Jakub Kicinski
Quoted 8 lines · On Fri, 20 Jun 2025 08:31:25 -0600 Jens Axboe wrote:
Quoted 7 lines · Jakub Kicinski
Quoted 3 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Branch seems to be gone?

Ah, I deleted when I was forwarding to Linus yesterday. I figured you already pulled, sorry about that. I've pushed it out again now.

Thanks! Usually I would have, but waiting on -rc3 for that branch. I'll reply here when I've pulled, should be on Sunday.

Signature · 1 line
Jens Axboe
maintainer
#21 lore raw
In reply to Jakub Kicinski
Quoted 9 lines · Jakub Kicinski
Quoted 8 lines · On Fri, 20 Jun 2025 08:31:25 -0600 Jens Axboe wrote:
Quoted 7 lines · Jakub Kicinski
Quoted 3 lines · On Tue, 17 Jun 2025 16:33:20 -0600 Jens Axboe wrote:

Can we put it in a separate branch and merge it into both? Otherwise my branch will get a bunch of unrelated commits, and pulling an unnamed sha is pretty iffy.

Like this?

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git timestamp-for-jens

Branch seems to be gone?

Ah, I deleted when I was forwarding to Linus yesterday. I figured you already pulled, sorry about that. I've pushed it out again now.

I've pulled it now, thanks Jakub.

Signature · 1 line
Jens Axboe
maintainer Applied
#22 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

In reply to Pavel Begunkov
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

[2/5] io_uring/poll: introduce io_arm_apoll()

      commit: 162151889267089bb920609830c35f9272087c3f
[3/5] io_uring/cmd: allow multishot polled commands
      commit: b95575495948a81ac9b0110aa721ea061dd850d9
[4/5] io_uring: add mshot helper for posting CQE32
      commit: ac479eac22e81c0ff56c6bdb93fad787015149cc
[5/5] io_uring/netcmd: add tx timestamping cmd support
      commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a

Best regards,

Signature · 1 line
Jens Axboe
maintainer
#23 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

Quoted 16 lines · Jens Axboe
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

Quoted 8 lines

[2/5] io_uring/poll: introduce io_arm_apoll()

      commit: 162151889267089bb920609830c35f9272087c3f
[3/5] io_uring/cmd: allow multishot polled commands
      commit: b95575495948a81ac9b0110aa721ea061dd850d9
[4/5] io_uring: add mshot helper for posting CQE32
      commit: ac479eac22e81c0ff56c6bdb93fad787015149cc
[5/5] io_uring/netcmd: add tx timestamping cmd support
      commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a

Pavel, can you send in the liburing PR for these, please?

Signature · 1 line
Jens Axboe
#24 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

Quoted 26 lines · Jens Axboe
Quoted 16 lines · Jens Axboe
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

Quoted 8 lines

[2/5] io_uring/poll: introduce io_arm_apoll()

       commit: 162151889267089bb920609830c35f9272087c3f
[3/5] io_uring/cmd: allow multishot polled commands
       commit: b95575495948a81ac9b0110aa721ea061dd850d9
[4/5] io_uring: add mshot helper for posting CQE32
       commit: ac479eac22e81c0ff56c6bdb93fad787015149cc
[5/5] io_uring/netcmd: add tx timestamping cmd support
       commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a
Quoted 1 line

Pavel, can you send in the liburing PR for these, please?

It needs a minor clean up, I'll send it by Monday

Signature · 1 line
Pavel Begunkov
maintainer
#25 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

Quoted 27 lines · Pavel Begunkov
Quoted 26 lines · Jens Axboe
Quoted 24 lines · Jens Axboe
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

[2/5] io_uring/poll: introduce io_arm_apoll()
       commit: 162151889267089bb920609830c35f9272087c3f [3/5] io_uring/cmd: allow multishot polled commands
       commit: b95575495948a81ac9b0110aa721ea061dd850d9 [4/5] io_uring: add mshot helper for posting CQE32
       commit: ac479eac22e81c0ff56c6bdb93fad787015149cc [5/5] io_uring/netcmd: add tx timestamping cmd support
       commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a

Quoted 3 lines
Quoted 1 line

Pavel, can you send in the liburing PR for these, please?

It needs a minor clean up, I'll send it by Monday

Gentle reminder on this. No rush, just want to make sure it isn't forgotten.

Signature · 1 line
Jens Axboe
#26 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

Quoted 28 lines · Jens Axboe
Quoted 27 lines · Pavel Begunkov
Quoted 26 lines · Jens Axboe
Quoted 24 lines · Jens Axboe
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

[2/5] io_uring/poll: introduce io_arm_apoll()
       commit: 162151889267089bb920609830c35f9272087c3f
[3/5] io_uring/cmd: allow multishot polled commands
       commit: b95575495948a81ac9b0110aa721ea061dd850d9
[4/5] io_uring: add mshot helper for posting CQE32
       commit: ac479eac22e81c0ff56c6bdb93fad787015149cc
[5/5] io_uring/netcmd: add tx timestamping cmd support
       commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Pavel, can you send in the liburing PR for these, please?

It needs a minor clean up, I'll send it by Monday

Gentle reminder on this. No rush, just want to make sure it isn't forgotten.

You already merged the (liburing) test

commit 21224848af24d379d54fbf1bd43a60861fe19f9b

Author: Pavel Begunkov <[email protected]>
Date:   Mon Jun 30 18:10:31 2025 +0100

tests: add a tx timestamp test

Signature · 1 line
Pavel Begunkov
maintainer
#27 lore raw

Re: (subset) [PATCH v5 0/5] io_uring cmd for tx timestamps

Quoted 36 lines · Pavel Begunkov
Quoted 28 lines · Jens Axboe
Quoted 27 lines · Pavel Begunkov
Quoted 26 lines · Jens Axboe
Quoted 24 lines · Jens Axboe
Quoted 11 lines · Pavel Begunkov

Vadim Fedorenko suggested to add an alternative API for receiving tx timestamps through io_uring. The series introduces io_uring socket cmd for fetching tx timestamps, which is a polled multishot request, i.e. internally polling the socket for POLLERR and posts timestamps when they're arrives. For the API description see Patch 5.

It reuses existing timestamp infra and takes them from the socket's error queue. For networking people the important parts are Patch 1, and io_uring_cmd_timestamp() from Patch 5 walking the error queue.

[...]

Applied, thanks!

[2/5] io_uring/poll: introduce io_arm_apoll()

        commit: 162151889267089bb920609830c35f9272087c3f
[3/5] io_uring/cmd: allow multishot polled commands
        commit: b95575495948a81ac9b0110aa721ea061dd850d9
[4/5] io_uring: add mshot helper for posting CQE32
        commit: ac479eac22e81c0ff56c6bdb93fad787015149cc
[5/5] io_uring/netcmd: add tx timestamping cmd support
        commit: 9e4ed359b8efad0e8ad4510d8ad22bf0b060526a
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Pavel, can you send in the liburing PR for these, please?

It needs a minor clean up, I'll send it by Monday

Gentle reminder on this. No rush, just want to make sure it isn't forgotten.

Quoted 7 lines

You already merged the (liburing) test

commit 21224848af24d379d54fbf1bd43a60861fe19f9b

Author: Pavel Begunkov <[email protected]>
Date:   Mon Jun 30 18:10:31 2025 +0100

tests: add a tx timestamp test

I totally did... Just going over old emails, guess it got lost in post vacation juggling. Sorry for the noise!

Signature · 1 line
Jens Axboe