vhost: fix interrupt suppression for the split ring

The VIRTIO_RING_F_EVENT_IDX feature of split ring might
be broken, as the value of signalled_used is invalid
after live migration, start up and virtio driver reload.
This patch fixes it by using signalled_used_valid.

In addition, this patch makes the VIRTIO_RING_F_EVENT_IDX
implementation of split ring match kernel backend to suppress
more interrupts.

Fixes: e37ff95440 ("vhost: support virtqueue interrupt/notification suppression")
Cc: stable@dpdk.org

Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
Tested-by: Yinan Wang <yinan.wang@intel.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
This commit is contained in:
Jiayu Hu 2019-03-17 14:38:32 +08:00 committed by Ferruh Yigit
parent bad78b4b8b
commit 2f706027c8
2 changed files with 10 additions and 4 deletions

View File

@ -633,16 +633,20 @@ vhost_vring_call_split(struct virtio_net *dev, struct vhost_virtqueue *vq)
if (dev->features & (1ULL << VIRTIO_RING_F_EVENT_IDX)) { if (dev->features & (1ULL << VIRTIO_RING_F_EVENT_IDX)) {
uint16_t old = vq->signalled_used; uint16_t old = vq->signalled_used;
uint16_t new = vq->last_used_idx; uint16_t new = vq->last_used_idx;
bool signalled_used_valid = vq->signalled_used_valid;
vq->signalled_used = new;
vq->signalled_used_valid = true;
VHOST_LOG_DEBUG(VHOST_DATA, "%s: used_event_idx=%d, old=%d, new=%d\n", VHOST_LOG_DEBUG(VHOST_DATA, "%s: used_event_idx=%d, old=%d, new=%d\n",
__func__, __func__,
vhost_used_event(vq), vhost_used_event(vq),
old, new); old, new);
if (vhost_need_event(vhost_used_event(vq), new, old)
&& (vq->callfd >= 0)) { if ((vhost_need_event(vhost_used_event(vq), new, old) &&
vq->signalled_used = vq->last_used_idx; (vq->callfd >= 0)) ||
unlikely(!signalled_used_valid))
eventfd_write(vq->callfd, (eventfd_t) 1); eventfd_write(vq->callfd, (eventfd_t) 1);
}
} else { } else {
/* Kick the guest if necessary. */ /* Kick the guest if necessary. */
if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT)

View File

@ -1298,6 +1298,8 @@ vhost_user_get_vring_base(struct virtio_net **pdev,
vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD; vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
vq->signalled_used_valid = false;
if (dev->dequeue_zero_copy) if (dev->dequeue_zero_copy)
free_zmbufs(vq); free_zmbufs(vq);
if (vq_is_packed(dev)) { if (vq_is_packed(dev)) {