Skip to content
  • Toshiaki Makita's avatar
    vhost_net: Avoid tx vring kicks during busyloop · 027b1760
    Toshiaki Makita authored
    
    
    Under heavy load vhost busypoll may run without suppressing
    notification. For example tx zerocopy callback can push tx work while
    handle_tx() is running, then busyloop exits due to vhost_has_work()
    condition and enables notification but immediately reenters handle_tx()
    because the pushed work was tx. In this case handle_tx() tries to
    disable notification again, but when using event_idx it by design
    cannot. Then busyloop will run without suppressing notification.
    Another example is the case where handle_tx() tries to enable
    notification but avail idx is advanced so disables it again. This case
    also leads to the same situation with event_idx.
    
    The problem is that once we enter this situation busyloop does not work
    under heavy load for considerable amount of time, because notification
    is likely to happen during busyloop and handle_tx() immediately enables
    notification after notification happens. Specifically busyloop detects
    notification by vhost_has_work() and then handle_tx() calls
    vhost_enable_notify(). Because the detected work was the tx work, it
    enters handle_tx(), and enters busyloop without suppression again.
    This is likely to be repeated, so with event_idx we are almost not able
    to suppress notification in this case.
    
    To fix this, poll the work instead of enabling notification when
    busypoll is interrupted by something. IMHO vhost_has_work() is kind of
    interruption rather than a signal to completely cancel the busypoll, so
    let's run busypoll after the necessary work is done.
    
    Signed-off-by: default avatarToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
    Acked-by: default avatarJason Wang <jasowang@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    027b1760