The commit is pushed to "branch-rh10-6.12.0-55.52.1.5.x.vz10-ovz" and will 
appear at [email protected]:openvz/vzkernel.git
after rh10-6.12.0-55.52.1.5.28.vz10
------>
commit 965dba34b2a2212c91ef00fba750dc3138f8e38b
Author: Denis V. Lunev <[email protected]>
Date:   Tue May 26 18:53:15 2026 +0200

    vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
    
    QEMU's CPR live update issues VHOST_VSOCK_SET_RUNNING(0) on the source
    before VHOST_RESET_OWNER, nulling vq->private_data via
    vhost_vsock_drop_backends(). The fast-fail in vhost_transport_send_pkt()
    added by commit 4ff28534c799 ("ms/vhost/vsock: Refuse the connection
    immediately when guest isn't ready") then rejects every host send with
    -EHOSTUNREACH until the destination calls SET_RUNNING(1) -- the entire
    CPR window becomes a hard outage for host AF_VSOCK clients
    (VSTOR-131956).
    
    Add a cpr_paused flag set inside vhost_vsock_drop_backends() when the
    backend was previously live, cleared by vhost_vsock_start(). When set,
    vhost_transport_send_pkt() queues the skb instead of fast-failing; the
    existing kick of send_pkt_work in vhost_vsock_start() drains it on
    resume. A device that has never run keeps cpr_paused == false and the
    boot-time fast-fail behaviour is preserved.
    
    Pair the cpr_paused store with the backend store using an
    smp_wmb()/smp_rmb() pair so a concurrent sender on a weakly-ordered
    architecture never observes (NULL backend, !paused):
    
      - On pause:  WRITE_ONCE(cpr_paused, true); smp_wmb();
                   vhost_vq_set_backend(vq, NULL);
      - On resume: vhost_vq_set_backend(vq, vsock); smp_wmb();
                   WRITE_ONCE(cpr_paused, false);
      - In send_pkt: load backend; smp_rmb(); READ_ONCE(cpr_paused);
    
    On x86 (TSO) the barriers are compile-time only.
    
    https://virtuozzo.atlassian.net/browse/VSTOR-131956
    Signed-off-by: Denis V. Lunev <[email protected]>
    
    Feature: vhost-vsock: VHOST_RESET_OWNER ioctl
---
 drivers/vhost/vsock.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0a518c3d15965..1d7c5e5acc0a4 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -57,6 +57,7 @@ struct vhost_vsock {
 
        u32 guest_cid;
        bool seqpacket_allow;
+       bool cpr_paused;        /* between stop and next start; queues sends */
 };
 
 static u32 vhost_transport_get_local_cid(void)
@@ -295,10 +296,14 @@ vhost_transport_send_pkt(struct sk_buff *skb)
         * all the outcomes covered: if the backend becomes NULL right after 
the check,
         * vhost_transport_do_send_pkt() will check it under the mutex anyway.
         */
+       /* cpr_paused: queue across CPR; else NULL backend means not ready. */
        if 
(unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
-               rcu_read_unlock();
-               kfree_skb(skb);
-               return -EHOSTUNREACH;
+               smp_rmb();      /* pairs with smp_wmb() in start/drop_backends 
*/
+               if (!READ_ONCE(vsock->cpr_paused)) {
+                       rcu_read_unlock();
+                       kfree_skb(skb);
+                       return -EHOSTUNREACH;
+               }
        }
 
        if (virtio_vsock_skb_reply(skb))
@@ -610,6 +615,9 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
                mutex_unlock(&vq->mutex);
        }
 
+       smp_wmb();      /* pairs with smp_rmb() in send_pkt */
+       WRITE_ONCE(vsock->cpr_paused, false);
+
        /* Some packets may have been queued before the device was started,
         * let's kick the send worker to send them.
         */
@@ -641,6 +649,11 @@ static void vhost_vsock_drop_backends(struct vhost_vsock 
*vsock)
 
        lockdep_assert_held(&vsock->dev.mutex);
 
+       if (vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])) {
+               WRITE_ONCE(vsock->cpr_paused, true);
+               smp_wmb();      /* pairs with smp_rmb() in send_pkt */
+       }
+
        for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
                vq = &vsock->vqs[i];
 
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to