• Albert Huang's avatar
    virtio_ring: don't update event idx on get_buf · 6c0b057c
    Albert Huang authored
    In virtio_net, if we disable napi_tx, when we trigger a tx interrupt,
    the vq->event_triggered will be set to true. It is then never reset
    until we explicitly call virtqueue_enable_cb_delayed or
    virtqueue_enable_cb_prepare.
    
    If we disable the napi_tx, virtqueue_enable_cb* will only be called when
    the tx ring is getting relatively empty.
    
    Since event_triggered is true, VRING_AVAIL_F_NO_INTERRUPT or
    VRING_PACKED_EVENT_FLAG_DISABLE will not be set. As a result we update
    vring_used_event(&vq->split.vring) or vq->packed.vring.driver->off_wrap
    every time we call virtqueue_get_buf_ctx. This causes more interrupts.
    
    To summarize:
    1) event_triggered was set to true in vring_interrupt()
    2) after this nothing will happen in virtqueue_disable_cb() so
       VRING_AVAIL_F_NO_INTERRUPT is not set in avail_flags_shadow
    3) virtqueue_get_buf_ctx_split() will still think the cb is enabled
       and then it will publish a new event index
    
    To fix:
    update VRING_AVAIL_F_NO_INTERRUPT or VRING_PACKED_EVENT_FLAG_DISABLE in
    the vq when we call virtqueue_disable_cb even when event_triggered is
    true.
    
    Tested with iperf:
    iperf3 tcp stream:
    vm1 -----------------> vm2
    vm2 just receives tcp data stream from vm1, and sends acks to vm1,
    there are many tx interrupts in vm2.
    with the patch applied there are just a few tx interrupts.
    
    v2->v3:
    -update the interrupt disable flag even with the event_triggered is set,
    -instead of checking whether event_triggered is set in
    -virtqueue_get_buf_ctx_{packed/split}, will cause the drivers  which have
    -not called virtqueue_{enable/disable}_cb to miss notifications.
    
    v3->v4:
    -remove change for
    -"if (vq->packed.event_flags_shadow != VRING_PACKED_EVENT_FLAG_DISABLE)"
    -in virtqueue_disable_cb_packed
    
    Fixes: 8d622d21 ("virtio: fix up virtio_disable_cb")
    Signed-off-by: default avatarAlbert Huang <huangjie.albert@bytedance.com>
    Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
    Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
    Message-Id: <20230329102300.61000-1-huangjie.albert@bytedance.com>
    Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
    6c0b057c
virtio_ring.c 75 KB