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:
parent
bad78b4b8b
commit
2f706027c8
@ -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)
|
||||||
|
@ -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)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user