>
> On Sat, Oct 10, 2026 at 10:22:45PM +0800, Jia Jia wrote:
> > An RX lock batch still looks up the socket for every packet and takes a
> > temporary lookup reference, even though the batch already holds a reference
> > to the locked socket.
> >
> > Record the network namespace and packet address tuple when a batch starts.
> > Reuse the batch socket for later STREAM/RW packets with the same tuple, and
> > release the batch before looking up a different flow.
> >
> > The cached path still traces every packet, takes an skb owner reference,
> > validates socket state, source and transport, updates credit, and runs the
> > receive state machine. Only the socket table lookup and its temporary
> > reference are skipped.
> >
> > Signed-off-by: Jia Jia <[email protected]>
> > ---
> > include/linux/virtio_vsock.h | 3 ++
> > net/vmw_vsock/virtio_transport_common.c | 58 +++++++++++++++----------
> > 2 files changed, 38 insertions(+), 23 deletions(-)
> >
> > diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
> > index 26dde6909c4e..d6528681e052 100644
> > --- a/include/linux/virtio_vsock.h
> > +++ b/include/linux/virtio_vsock.h
> > @@ -287,6 +287,9 @@ struct virtio_transport_rx_batch {
> > struct sock *sk;
> > unsigned int pkts;
> > size_t bytes;
> > + struct net *net;
> > + struct sockaddr_vm src;
> > + struct sockaddr_vm dst;
> > };
> >
> > void virtio_transport_recv_pkt_batch(struct virtio_transport *t,
> > diff --git a/net/vmw_vsock/virtio_transport_common.c
> > b/net/vmw_vsock/virtio_transport_common.c
> > index e67dfcaa279c..73e5c7dfe8b4 100644
> > --- a/net/vmw_vsock/virtio_transport_common.c
> > +++ b/net/vmw_vsock/virtio_transport_common.c
> > @@ -1977,6 +1977,7 @@ void virtio_transport_rx_batch_finish(struct
> > virtio_transport_rx_batch *batch)
> > batch->sk = NULL;
> > batch->pkts = 0;
> > batch->bytes = 0;
> > + batch->net = NULL;
> >
> > if (!sk)
> > return;
> > @@ -2008,6 +2009,37 @@ void virtio_transport_recv_pkt_batch(struct
> > virtio_transport *t,
> > virtio_transport_recv_pkt_init_addrs(skb, &src, &dst);
> > virtio_transport_trace_recv_pkt(skb, &src, &dst);
> >
> > + if (batch->sk) {
> > + if (batch->net == net &&
> > + vsock_addr_equals_addr(&batch->src, &src) &&
> > + vsock_addr_equals_addr(&batch->dst, &dst) &&
> > + virtio_transport_recv_pkt_batchable(t, batch->sk)) {
> > + sk = batch->sk;
> > + if (!skb_set_owner_sk_safe(skb, sk)) {
> > + WARN_ONCE(1, "receiving vsock socket has
> > sk_refcnt == 0\n");
> > + virtio_transport_rx_batch_finish(batch);
> > + kfree_skb(skb);
> > + return;
> > + }
> > +
> > + ctx = (struct virtio_transport_rx_pkt_ctx) {
> > + .net = net,
> > + .src = &src,
> > + .dst = &dst,
> > + .batchable = &batchable,
> > + };
> > + free_pkt = virtio_transport_recv_pkt_locked(t, skb,
> > sk, &ctx);
> > +
> > + if (!batchable)
> > + virtio_transport_rx_batch_finish(batch);
> > + if (free_pkt)
> > + kfree_skb(skb);
> > + return;
> > + }
> > +
> > + virtio_transport_rx_batch_finish(batch);
> > + }
> > +
> > sk = virtio_transport_recv_pkt_find_socket(skb, &src, &dst, net);
> > if (!sk) {
> > virtio_transport_rx_batch_finish(batch);
> > @@ -2018,33 +2050,10 @@ void virtio_transport_recv_pkt_batch(struct
> > virtio_transport *t,
> >
> > if (!skb_set_owner_sk_safe(skb, sk)) {
> > WARN_ONCE(1, "receiving vsock socket has sk_refcnt == 0\n");
> > - virtio_transport_rx_batch_finish(batch);
> > kfree_skb(skb);
> > return;
> > }
> >
> > - if (batch->sk && batch->sk != sk) {
> > - /* Never acquire a second socket lock. */
> > - virtio_transport_rx_batch_finish(batch);
> > - }
> > -
> > - if (batch->sk == sk) {
> > - /* Keep the batch reference; drop this packet's lookup
> > reference. */
> > - sock_put(sk);
> > - ctx = (struct virtio_transport_rx_pkt_ctx) {
> > - .net = net,
> > - .src = &src,
> > - .dst = &dst,
> > - .batchable = &batchable,
> > - };
> > - free_pkt = virtio_transport_recv_pkt_locked(t, skb, sk, &ctx);
> > - if (!batchable)
> > - virtio_transport_rx_batch_finish(batch);
> > - if (free_pkt)
> > - kfree_skb(skb);
> > - return;
> > - }
> > -
>
> Not sure I love adding code and then removing it in the same series.
> Seems like these are asking to be squashed?
>
I'll fold patch 3 into patch 2 so batching is introduced with
same-flow lookup reuse from the start.
> > lock_sock(sk);
> > /*
> > * Sockmap removal restores the native protocol under
> > sk_callback_lock.
> > @@ -2063,6 +2072,9 @@ void virtio_transport_recv_pkt_batch(struct
> > virtio_transport *t,
> > free_pkt = virtio_transport_recv_pkt_locked(t, skb, sk, &ctx);
> > if (start_batch && batchable) {
> > /* Keep the lookup reference until the batch is released. */
> > + batch->net = net;
> > + batch->src = src;
> > + batch->dst = dst;
>
> Similar to my comment in the other patch, seems these are all in sk
> already?
>
For the batch cache, yes. I'll use the locked socket state for the
same-flow check. The packet values still need to be passed to the
locked receive path for source validation and reset handling.
> Best,
> Bobby