* [PATCH 4/5] vsock: coalesce RX write-space notifications in lock batches
@ 2026-10-02 7:45 physicalmtea
0 siblings, 0 replies; only message in thread
From: physicalmtea @ 2026-10-02 7:45 UTC (permalink / raw)
To: stefanha, sgarzare, mst
Cc: jasowangio, eperezma, xuanzhuo, davem, edumazet, kuba, pabeni,
horms, virtualization, kvm, netdev, linux-kernel
From: Jia Jia <physicalmtea@gmail.com>
Each received packet updates peer credit and calls sk_write_space() when
send space is available. A writer cannot use the newly advertised credit
until the socket lock is released, so repeated callbacks within one lock
batch cannot let it make progress sooner.
For the callback installed by sock_init_data(), record one pending
write-space notification and deliver it immediately before release_sock().
Save the initial sock_def_write_space() callback when the AF_VSOCK socket
is created because it is not visible to virtio_transport_common when built
as a module. Custom write-space callbacks retain per-packet notification
behavior.
Set the batch socket before processing its first packet so a batch
ending on that packet cannot lose the notification.
Packets outside the eligible STREAM/RW batch path retain per-packet
notification behavior. The 64-packet and 64K limits cap the packets whose
notifications can be coalesced.
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
include/linux/virtio_vsock.h | 1 +
include/net/af_vsock.h | 2 ++
net/vmw_vsock/af_vsock.c | 1 +
net/vmw_vsock/virtio_transport_common.c | 30 +++++++++++++++++++++++++-----
4 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 4369adc07..f67fa99ec 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -288,6 +288,7 @@ struct virtio_transport_rx_batch {
struct net *net;
struct sockaddr_vm src;
struct sockaddr_vm dst;
+ bool write_space_pending;
};
void virtio_transport_recv_pkt_batch(struct virtio_transport *t,
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 5549298c1..9d8ae6220 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -63,6 +63,8 @@ struct vsock_sock {
u32 peer_shutdown;
bool sent_request;
bool ignore_connecting_rst;
+ /* Initial callback, used to identify replacements. */
+ void (*default_write_space)(struct sock *sk);
/* Protected by lock_sock(sk) */
u64 buffer_size;
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 9b71479a2..e5290a3bb 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -958,6 +958,7 @@ static struct sock *__vsock_create(struct net *net,
sk->sk_type = type;
vsk = vsock_sk(sk);
+ vsk->default_write_space = sk->sk_write_space;
vsock_addr_init(&vsk->local_addr, VMADDR_CID_ANY, VMADDR_PORT_ANY);
vsock_addr_init(&vsk->remote_addr, VMADDR_CID_ANY, VMADDR_PORT_ANY);
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index d8c9c90c0..78c4e2f9e 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1835,6 +1835,7 @@ struct virtio_transport_rx_pkt_ctx {
const struct sockaddr_vm *src;
const struct sockaddr_vm *dst;
bool *batchable;
+ struct virtio_transport_rx_batch *batch;
};
static bool
@@ -1882,8 +1883,14 @@ virtio_transport_recv_pkt_locked(struct virtio_transport *t,
if (vsk->local_addr.svm_cid != VMADDR_CID_ANY)
vsk->local_addr.svm_cid = ctx->dst->svm_cid;
- if (space_available)
- sk->sk_write_space(sk);
+ if (space_available) {
+ if (ctx->batch &&
+ READ_ONCE(sk->sk_write_space) == vsk->default_write_space &&
+ virtio_transport_recv_pkt_batchable(t, sk))
+ ctx->batch->write_space_pending = true;
+ else
+ sk->sk_write_space(sk);
+ }
switch (sk->sk_state) {
case TCP_LISTEN:
@@ -1963,13 +1970,18 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);
void virtio_transport_rx_batch_finish(struct virtio_transport_rx_batch *batch)
{
struct sock *sk = batch->sk;
+ bool write_space_pending = batch->write_space_pending;
batch->sk = NULL;
batch->net = NULL;
+ batch->write_space_pending = false;
if (!sk)
return;
+ /* Notify before release_sock() to order it before a sockmap attachment. */
+ if (write_space_pending)
+ vsock_sk(sk)->default_write_space(sk);
release_sock(sk);
sock_put(sk);
}
@@ -2015,6 +2027,7 @@ void virtio_transport_recv_pkt_batch(struct virtio_transport *t,
.src = &src,
.dst = &dst,
.batchable = &batchable,
+ .batch = batch,
};
free_pkt = virtio_transport_recv_pkt_locked(t, skb, sk, &ctx);
if (!batchable)
@@ -2049,11 +2062,14 @@ void virtio_transport_recv_pkt_batch(struct virtio_transport *t,
start_batch = virtio_transport_recv_pkt_batchable(t, sk);
read_unlock_bh(&sk->sk_callback_lock);
+ if (start_batch)
+ batch->sk = sk;
ctx = (struct virtio_transport_rx_pkt_ctx) {
.net = net,
.src = &src,
.dst = &dst,
.batchable = start_batch ? &batchable : NULL,
+ .batch = start_batch ? batch : NULL,
};
free_pkt = virtio_transport_recv_pkt_locked(t, skb, sk, &ctx);
if (start_batch && batchable) {
@@ -2061,12 +2077,16 @@ void virtio_transport_recv_pkt_batch(struct virtio_transport *t,
batch->net = net;
batch->src = src;
batch->dst = dst;
- batch->sk = sk;
return;
}
- release_sock(sk);
- sock_put(sk);
+ if (start_batch) {
+ virtio_transport_rx_batch_finish(batch);
+ } else {
+ release_sock(sk);
+ sock_put(sk);
+ }
+
if (free_pkt)
kfree_skb(skb);
}
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-02 7:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-02 7:45 [PATCH 4/5] vsock: coalesce RX write-space notifications in lock batches physicalmtea
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®