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:
parent
3f313bef34
commit
159793ac86
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user