On Wed, Jun 23, 2010 at 11:12 PM, Anthony Liguori <[email protected]> wrote:
> Shouldn't it be possible to just drop the lock before invoking
> virtqueue_kick() and reacquire it afterwards? There's nothing in that
> virtqueue_kick() path that the lock is protecting AFAICT.
No, that would lead to a race condition because vq->num_added is
modified by both virtqueue_add_buf_gfp() and virtqueue_kick().
Without a lock held during virtqueue_kick() another vcpu could add
bufs while vq->num_added is used and cleared by virtqueue_kick():
void virtqueue_kick(struct virtqueue *_vq, spinlock_t *lock)
{
struct vring_virtqueue *vq = to_vvq(_vq);
START_USE(vq);
/* Descriptors and available array need to be set before we expose the
* new available array entries. */
virtio_wmb();
vq->vring.avail->idx += vq->num_added;
vq->num_added = 0;
/* Need to update avail index before checking if we should notify */
virtio_mb();
if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) {
/* Release lock while doing the kick because the guest should
* not exit with the lock held. */
if (lock)
spin_unlock(lock);
/* Prod other side to tell it about changes. */
vq->notify(&vq->vq);
if (lock)
spin_lock(lock);
}
END_USE(vq);
}
Stefan
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization