On Sun, Dec 14, 2025 at 06:38:22AM +0000, Melbin K Mathew wrote:


On 12/12/2025 12:26, Stefano Garzarella wrote:
On Fri, Dec 12, 2025 at 11:40:03AM +0000, Melbin K Mathew wrote:


On 12/12/2025 10:40, Stefano Garzarella wrote:
On Fri, Dec 12, 2025 at 09:56:28AM +0000, Melbin Mathew Antony wrote:
Hi Stefano, Michael,

Thanks for the suggestions and guidance.

You're welcome, but please avoid top-posting in the future:
https://www.kernel.org/doc/html/latest/process/submitting- patches.html#use-trimmed-interleaved-replies-in-email-discussions

Sure. Thanks

I’ve drafted a 4-part series based on the recap. I’ve included the
four diffs below for discussion. Can wait for comments, iterate, and
then send the patch series in a few days.

---

Patch 1/4 — vsock/virtio: make get_credit() s64-safe and clamp negatives

virtio_transport_get_credit() was doing unsigned arithmetic; if the
peer shrinks its window, the subtraction can underflow and look like
“lots of credit”. This makes it compute “space” in s64 and clamp < 0
to 0.

diff --git a/net/vmw_vsock/virtio_transport_common.c
b/net/vmw_vsock/virtio_transport_common.c
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -494,16 +494,23 @@ EXPORT_SYMBOL_GPL(virtio_transport_consume_skb_sent); u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)
{
+ s64 bytes;
 u32 ret;

 if (!credit)
 return 0;

 spin_lock_bh(&vvs->tx_lock);
- ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
- if (ret > credit)
- ret = credit;
+ bytes = (s64)vvs->peer_buf_alloc -

Why not just calling virtio_transport_has_space()?
virtio_transport_has_space() takes struct vsock_sock *, while virtio_transport_get_credit() takes struct virtio_vsock_sock *, so I cannot directly call has_space() from get_credit() without changing signatures.

Would you be OK if I factor the common “space” calculation into a small helper that operates on struct virtio_vsock_sock * and is used by both paths? Something like:

Why not just change the signature of virtio_transport_has_space()?
Thanks, that is cleaner.

For Patch 1 i'll change virtio_transport_has_space() to take
struct virtio_vsock_sock * and call it from both
virtio_transport_stream_has_space() and virtio_transport_get_credit().

/*
* Return available peer buffer space for TX (>= 0).
*
* Use s64 arithmetic so that if the peer shrinks peer_buf_alloc while
* we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction does
* not underflow into a large positive value as it would with u32.
*
* Must be called with vvs->tx_lock held.
*/
static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs)
{
        s64 bytes;

        bytes = (s64)vvs->peer_buf_alloc -
                ((s64)vvs->tx_cnt - (s64)vvs->peer_fwd_cnt);

wait, why casting also the counters?
they are supposed to wrap, so should be fine to avoid the cast there.

Please, avoid too many changes in a single patch.

        if (bytes < 0)
                bytes = 0;

        return bytes;
}

s64 virtio_transport_stream_has_space(struct vsock_sock *vsk)
{
        struct virtio_vsock_sock *vvs = vsk->trans;
        s64 bytes;

        spin_lock_bh(&vvs->tx_lock);
        bytes = virtio_transport_has_space(vvs);
        spin_unlock_bh(&vvs->tx_lock);

        return bytes;
}

u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)
{
        u32 ret;

        if (!credit)
                return 0;

        spin_lock_bh(&vvs->tx_lock);
        ret = min_t(u32, credit, (u32)virtio_transport_has_space(vvs));

min_t() is supposed to be use exactly to avoid to cast each member, so why adding the cast to the value returned by virtio_transport_has_space() ?

        vvs->tx_cnt += ret;
        vvs->bytes_unsent += ret;
        spin_unlock_bh(&vvs->tx_lock);

        return ret;
}

Does this look right?

Pretty much yes, a part some comments, but I'd like to see the final solution.

Thanks,
Stefano


Reply via email to