vhost: fix virtio freeze due to missed interrupt

Update of used->idx and read of avail->flags could be reordered.
Memory fence should be used to ensure the order, otherwise guest could see
a stale used->idx value after it toggles the interrupt suppression flag.
After guest sets the interrupt suppression flag, it will check if there
is more buffer to process through used->idx. If it sees a stale value,
it will exit the processing while host won't send interrupt to guest.

Signed-off-by: Huawei Xie <huawei.xie@intel.com>
Reviewed-by: Luke Gorrie <luke@snabb.co>
This commit is contained in:
Huawei Xie 2015-04-29 19:11:24 +08:00 committed by Thomas Monjalon
parent 3f313bef34
commit 159793ac86

View File

@ -178,6 +178,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
*(volatile uint16_t *)&vq->used->idx += count;
vq->last_used_idx = res_end_idx;
/* flush used->idx update before we read avail->flags. */
rte_mb();
/* Kick the guest if necessary. */
if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
eventfd_write((int)vq->callfd, 1);
@ -505,6 +508,9 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
*(volatile uint16_t *)&vq->used->idx += entry_success;
vq->last_used_idx = res_end_idx;
/* flush used->idx update before we read avail->flags. */
rte_mb();
/* Kick the guest if necessary. */
if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
eventfd_write((int)vq->callfd, 1);