In io_uring_cmd_timestamp(), the skb processing loop terminates whenever io_process_timestamp_skb() returns a non-zero value. If the failure is due to a full CQ ring (-ENOBUFS), the loop stops and returns -ENOBUFS, ending the multishot command so userspace can drain the CQ. However, if io_process_timestamp_skb() fails because skb_get_tx_timestamp() returns a negative error (such as -ENOENT when a timestamp cannot be extracted due to changed socket options or absent hardware timestamp data), ret is not -ENOBUFS. The unhandled skb is then spliced back onto the head of sk->sk_error_queue and the function returns -EAGAIN. Because -EAGAIN leaves the multishot apoll armed on EPOLLERR, and the unextractable skb remains in sk_error_queue asserting EPOLLERR, io_uring_cmd_timestamp() is immediately re-invoked on the same skb. This results in an infinite busy-loop consuming 100% CPU and completely blocking progress on any subsequent valid timestamp packets queued behind it. Only break out of the processing loop when CQ space is exhausted (ret == -ENOBUFS). For skbs where timestamp extraction fails, dequeue and consume the invalid skb matching the behavior of sock_recv_errqueue(), allowing the queue to make forward progress. The issue was discovered via manual code audit of io_uring/cmd_net.c and review of the error handling paths in TX_TIMESTAMP command. Fixes: 9e4ed359b8ef ("io_uring/netcmd: add tx timestamping cmd support") Cc: stable@vger.kernel.org Signed-off-by: Bui Viet Dung --- io_uring/cmd_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index 90d4ec7cc761..a5a1b8b66b1f 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -138,7 +138,7 @@ static int io_uring_cmd_timestamp(struct socket *sock, if (!skb) break; ret = io_process_timestamp_skb(cmd, sk, skb, issue_flags); - if (ret) + if (ret == -ENOBUFS) break; __skb_dequeue(&list); consume_skb(skb); -- 2.43.0