On 2018年05月16日 20:32, Jason Wang wrote:
+static bool vhost_notify_packed(struct vhost_dev *dev, + struct vhost_virtqueue *vq) +{ + __virtio16 event_off_wrap, event_flags; + __u16 old, new, off_wrap; + bool v; + + /* Flush out used descriptors updates. This is paired + * with the barrier that the Guest executes when enabling + * interrupts. + */ + smp_mb(); + + if (vhost_get_avail(vq, event_flags, + &vq->driver_event->flags) < 0) { + vq_err(vq, "Failed to get driver desc_event_flags"); + return true; + } + + if (event_flags == cpu_to_vhost16(vq, RING_EVENT_FLAGS_DISABLE)) + return false; + else if (event_flags == cpu_to_vhost16(vq, RING_EVENT_FLAGS_ENABLE)) + return true; + + /* Read desc event flags before event_off and event_wrap */ + smp_rmb(); + + if (vhost_get_avail(vq, event_off_wrap, + &vq->driver_event->off_warp) < 0) { + vq_err(vq, "Failed to get driver desc_event_off/wrap"); + return true; + } + + off_wrap = vhost16_to_cpu(vq, event_off_wrap); + + old = vq->signalled_used; + v = vq->signalled_used_valid; + new = vq->signalled_used = vq->last_used_idx; + vq->signalled_used_valid = true;
We should move those idx tracking before checking event_flags. Otherwise we may lose interrupts because of a wrong signalled_used value.
Thanks
+ + if (unlikely(!v)) + return true; + + return vhost_vring_packed_need_event(vq, off_wrap, new, old); +}
_______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization