Skip to content

Commit

Permalink
vhost: fix barrier pairing
Browse files Browse the repository at this point in the history
According to memory-barriers.txt, an smp memory barrier in guest
should always be paired with an smp memory barrier in host,
and I quote "a lack of appropriate pairing is almost certainly an
error". In case of vhost, failure to flush out used index
update before looking at the interrupt disable flag
could result in missed interrupts, resulting in
networking hang under stress.

This might happen when flags read bypasses used index write.
So we see interrupts disabled and do not interrupt, at the
same time guest writes flags value to enable interrupt,
reads an old used index value, thinks that
used ring is empty and waits for interrupt.

Note: the barrier we pair with here is in
drivers/virtio/virtio_ring.c, function
vring_enable_cb.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Juan Quintela <quintela@redhat.com>
  • Loading branch information
Michael S. Tsirkin committed May 12, 2010
1 parent de02d72 commit 0d49935
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion drivers/vhost/vhost.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
/* This actually signals the guest, using eventfd. */
void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
{
__u16 flags = 0;
__u16 flags;
/* Flush out used index updates. This is paired
* with the barrier that the Guest executes when enabling
* interrupts. */
smp_mb();

if (get_user(flags, &vq->avail->flags)) {
vq_err(vq, "Failed to get flags");
return;
Expand Down

0 comments on commit 0d49935

Please sign in to comment.