diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2015-12-17 05:20:39 -0500 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2016-01-12 13:47:02 -0500 |
| commit | 788e5b3a5da24cc8d93ce2f7c6508181cd7d7fb6 (patch) | |
| tree | 7e54e74c3f7373a04780ad14cb157089c76abeb2 /drivers/virtio | |
| parent | 9e3f84ce416663c84a191cb3ead300fc1a4adadc (diff) | |
virtio_ring: use virt_store_mb
We need a full barrier after writing out event index, using
virt_store_mb there seems better than open-coding. As usual, we need a
wrapper to account for strong barriers.
It's tempting to use this in vhost as well, for that, we'll
need a variant of smp_store_mb that works on __user pointers.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Diffstat (limited to 'drivers/virtio')
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index ee663c458b20..e12e385f7ac3 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
| @@ -517,10 +517,10 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) | |||
| 517 | /* If we expect an interrupt for the next entry, tell host | 517 | /* If we expect an interrupt for the next entry, tell host |
| 518 | * by writing event index and flush out the write before | 518 | * by writing event index and flush out the write before |
| 519 | * the read in the next get_buf call. */ | 519 | * the read in the next get_buf call. */ |
| 520 | if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) { | 520 | if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) |
| 521 | vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx); | 521 | virtio_store_mb(vq->weak_barriers, |
| 522 | virtio_mb(vq->weak_barriers); | 522 | &vring_used_event(&vq->vring), |
| 523 | } | 523 | cpu_to_virtio16(_vq->vdev, vq->last_used_idx)); |
| 524 | 524 | ||
| 525 | #ifdef DEBUG | 525 | #ifdef DEBUG |
| 526 | vq->last_add_time_valid = false; | 526 | vq->last_add_time_valid = false; |
| @@ -653,8 +653,11 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) | |||
| 653 | } | 653 | } |
| 654 | /* TODO: tune this threshold */ | 654 | /* TODO: tune this threshold */ |
| 655 | bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4; | 655 | bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4; |
| 656 | vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs); | 656 | |
| 657 | virtio_mb(vq->weak_barriers); | 657 | virtio_store_mb(vq->weak_barriers, |
| 658 | &vring_used_event(&vq->vring), | ||
| 659 | cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs)); | ||
| 660 | |||
| 658 | if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) { | 661 | if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) { |
| 659 | END_USE(vq); | 662 | END_USE(vq); |
| 660 | return false; | 663 | return false; |
