From 77eee189397df7ef8a19cf279db6845ab839662e Mon Sep 17 00:00:00 2001 From: Raf Dickson Date: Fri, 12 Jun 2026 04:52:13 +0000 Subject: vsock: introduce vsock_pending_to_accept() helper Add vsock_pending_to_accept() to move a socket directly from the pending list to the accept queue in a single operation, avoiding the sock_put/sock_hold dance and the sk_acceptq_removed()/ sk_acceptq_added() pair that would otherwise be needed when calling vsock_remove_pending() followed by vsock_enqueue_accept(). Use it in vmci_transport_recv_connecting_server() where a completed handshake transitions the socket from pending to accept queue. Suggested-by: Stefano Garzarella Signed-off-by: Raf Dickson Reviewed-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Reviewed-by: Bobby Eshleman Link: https://patch.msgid.link/20260612045216.105796-2-rafdog35@gmail.com Signed-off-by: Jakub Kicinski --- include/net/af_vsock.h | 1 + net/vmw_vsock/af_vsock.c | 10 ++++++++++ net/vmw_vsock/vmci_transport.c | 3 +-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 4e40063adab4..30046a3c20f7 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -220,6 +220,7 @@ static inline bool __vsock_in_connected_table(struct vsock_sock *vsk) void vsock_add_pending(struct sock *listener, struct sock *pending); void vsock_remove_pending(struct sock *listener, struct sock *pending); void vsock_enqueue_accept(struct sock *listener, struct sock *connected); +void vsock_pending_to_accept(struct sock *listener, struct sock *pending); void vsock_insert_connected(struct vsock_sock *vsk); void vsock_remove_bound(struct vsock_sock *vsk); void vsock_remove_connected(struct vsock_sock *vsk); diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 1b20ec498518..2a267283aef8 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -497,6 +497,16 @@ void vsock_remove_pending(struct sock *listener, struct sock *pending) } EXPORT_SYMBOL_GPL(vsock_remove_pending); +void vsock_pending_to_accept(struct sock *listener, struct sock *pending) +{ + struct vsock_sock *vpending = vsock_sk(pending); + struct vsock_sock *vlistener = vsock_sk(listener); + + list_del_init(&vpending->pending_links); + list_add_tail(&vpending->accept_queue, &vlistener->accept_queue); +} +EXPORT_SYMBOL_GPL(vsock_pending_to_accept); + void vsock_enqueue_accept(struct sock *listener, struct sock *connected) { struct vsock_sock *vlistener; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 56503bee3165..af64fd57c0c8 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -1258,8 +1258,7 @@ vmci_transport_recv_connecting_server(struct sock *listener, * listener's pending list to the accept queue so callers of accept() * can find it. */ - vsock_remove_pending(listener, pending); - vsock_enqueue_accept(listener, pending); + vsock_pending_to_accept(listener, pending); /* Callers of accept() will be waiting on the listening socket, not * the pending socket. -- cgit v1.2.3 From a6fd2cfdcdf5b271ed24e8816877a3e4b628105d Mon Sep 17 00:00:00 2001 From: Raf Dickson Date: Fri, 12 Jun 2026 04:52:14 +0000 Subject: vsock: fold sk_acceptq_added() into vsock_add_pending() Move sk_acceptq_added() into vsock_add_pending() so callers cannot forget it. vmci is the only transport using the pending list and is updated accordingly. Suggested-by: Stefano Garzarella Signed-off-by: Raf Dickson Reviewed-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Reviewed-by: Bobby Eshleman Link: https://patch.msgid.link/20260612045216.105796-3-rafdog35@gmail.com Signed-off-by: Jakub Kicinski --- net/vmw_vsock/af_vsock.c | 1 + net/vmw_vsock/vmci_transport.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 2a267283aef8..cbb71aca6cf1 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -484,6 +484,7 @@ void vsock_add_pending(struct sock *listener, struct sock *pending) sock_hold(pending); sock_hold(listener); list_add_tail(&vpending->pending_links, &vlistener->pending_links); + sk_acceptq_added(listener); } EXPORT_SYMBOL_GPL(vsock_add_pending); diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index af64fd57c0c8..2d8efeb8afe2 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -1109,7 +1109,6 @@ static int vmci_transport_recv_listen(struct sock *sk, } vsock_add_pending(sk, pending); - sk_acceptq_added(sk); pending->sk_state = TCP_SYN_SENT; vmci_trans(vpending)->produce_size = -- cgit v1.2.3 From 6f6f9b65a9919f8ddf801b96e70cc29fd32ae663 Mon Sep 17 00:00:00 2001 From: Raf Dickson Date: Fri, 12 Jun 2026 04:52:15 +0000 Subject: vsock: fold sk_acceptq_added() into vsock_enqueue_accept() virtio and hyperv call sk_acceptq_added() immediately before vsock_enqueue_accept(). Move the call into vsock_enqueue_accept() itself so callers cannot forget it and the accounting is consistent. Suggested-by: Paolo Abeni Suggested-by: Stefano Garzarella Signed-off-by: Raf Dickson Reviewed-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Reviewed-by: Bobby Eshleman Link: https://patch.msgid.link/20260612045216.105796-4-rafdog35@gmail.com Signed-off-by: Jakub Kicinski --- net/vmw_vsock/af_vsock.c | 1 + net/vmw_vsock/hyperv_transport.c | 1 - net/vmw_vsock/virtio_transport_common.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index cbb71aca6cf1..2e39656a798b 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -519,6 +519,7 @@ void vsock_enqueue_accept(struct sock *listener, struct sock *connected) sock_hold(connected); sock_hold(listener); list_add_tail(&vconnected->accept_queue, &vlistener->accept_queue); + sk_acceptq_added(listener); } EXPORT_SYMBOL_GPL(vsock_enqueue_accept); diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index e6adbc47011d..5405c2680dec 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -410,7 +410,6 @@ static void hvs_open_connection(struct vmbus_channel *chan) if (conn_from_host) { new->sk_state = TCP_ESTABLISHED; - sk_acceptq_added(sk); hvs_new->vm_srv_id = *if_type; hvs_new->host_srv_id = *if_instance; diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 3b294164b741..09475007165b 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -1582,7 +1582,6 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb, return ret; } - sk_acceptq_added(sk); if (virtio_transport_space_update(child, skb)) child->sk_write_space(child); -- cgit v1.2.3 From 27fc25bb82e6934cf4473539d58dd179961a5447 Mon Sep 17 00:00:00 2001 From: Raf Dickson Date: Fri, 12 Jun 2026 04:52:16 +0000 Subject: vsock: fold sk_acceptq_removed() into vsock_remove_pending() Callers of vsock_remove_pending() must also call sk_acceptq_removed() to keep sk_ack_backlog consistent. Move the call into vsock_remove_pending() itself to make it automatic and prevent future callers from forgetting it. Suggested-by: Stefano Garzarella Signed-off-by: Raf Dickson Reviewed-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Reviewed-by: Bobby Eshleman Link: https://patch.msgid.link/20260612045216.105796-5-rafdog35@gmail.com Signed-off-by: Jakub Kicinski --- net/vmw_vsock/af_vsock.c | 3 +-- net/vmw_vsock/vmci_transport.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 2e39656a798b..622dbd046799 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -495,6 +495,7 @@ void vsock_remove_pending(struct sock *listener, struct sock *pending) list_del_init(&vpending->pending_links); sock_put(listener); sock_put(pending); + sk_acceptq_removed(listener); } EXPORT_SYMBOL_GPL(vsock_remove_pending); @@ -773,8 +774,6 @@ static void vsock_pending_work(struct work_struct *work) if (vsock_is_pending(sk)) { vsock_remove_pending(listener, sk); - - sk_acceptq_removed(listener); } else if (!vsk->rejected) { /* We are not on the pending list and accept() did not reject * us, so we must have been accepted by our user process. We diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 2d8efeb8afe2..1c4ee039c166 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -980,10 +980,8 @@ static int vmci_transport_recv_listen(struct sock *sk, err = -EINVAL; } - if (err < 0) { + if (err < 0) vsock_remove_pending(sk, pending); - sk_acceptq_removed(sk); - } release_sock(pending); vmci_transport_release_pending(pending); -- cgit v1.2.3