diff options
| -rw-r--r-- | MAINTAINERS | 2 | ||||
| -rw-r--r-- | drivers/block/virtio_blk.c | 10 | ||||
| -rw-r--r-- | drivers/char/virtio_console.c | 22 | ||||
| -rw-r--r-- | drivers/virtio/config.c | 12 | ||||
| -rw-r--r-- | drivers/virtio/virtio_balloon.c | 2 | ||||
| -rw-r--r-- | drivers/virtio/virtio_pci_legacy.c | 16 | ||||
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 16 | ||||
| -rw-r--r-- | tools/virtio/ringtest/Makefile | 4 | ||||
| -rw-r--r-- | tools/virtio/ringtest/main.c | 20 | ||||
| -rw-r--r-- | tools/virtio/ringtest/main.h | 4 | ||||
| -rw-r--r-- | tools/virtio/ringtest/noring.c | 6 | ||||
| -rw-r--r-- | tools/virtio/ringtest/ptr_ring.c | 22 | ||||
| -rw-r--r-- | tools/virtio/ringtest/ring.c | 18 | ||||
| -rw-r--r-- | tools/virtio/ringtest/virtio_ring_0_9.c | 64 |
14 files changed, 96 insertions, 122 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 4012c2f98617..ccae35bb3904 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -12783,6 +12783,7 @@ F: include/uapi/linux/virtio_console.h | |||
| 12783 | 12783 | ||
| 12784 | VIRTIO CORE, NET AND BLOCK DRIVERS | 12784 | VIRTIO CORE, NET AND BLOCK DRIVERS |
| 12785 | M: "Michael S. Tsirkin" <mst@redhat.com> | 12785 | M: "Michael S. Tsirkin" <mst@redhat.com> |
| 12786 | M: Jason Wang <jasowang@redhat.com> | ||
| 12786 | L: virtualization@lists.linux-foundation.org | 12787 | L: virtualization@lists.linux-foundation.org |
| 12787 | S: Maintained | 12788 | S: Maintained |
| 12788 | F: Documentation/devicetree/bindings/virtio/ | 12789 | F: Documentation/devicetree/bindings/virtio/ |
| @@ -12813,6 +12814,7 @@ F: include/uapi/linux/virtio_gpu.h | |||
| 12813 | 12814 | ||
| 12814 | VIRTIO HOST (VHOST) | 12815 | VIRTIO HOST (VHOST) |
| 12815 | M: "Michael S. Tsirkin" <mst@redhat.com> | 12816 | M: "Michael S. Tsirkin" <mst@redhat.com> |
| 12817 | M: Jason Wang <jasowang@redhat.com> | ||
| 12816 | L: kvm@vger.kernel.org | 12818 | L: kvm@vger.kernel.org |
| 12817 | L: virtualization@lists.linux-foundation.org | 12819 | L: virtualization@lists.linux-foundation.org |
| 12818 | L: netdev@vger.kernel.org | 12820 | L: netdev@vger.kernel.org |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 2dc5c96c186a..5545a679abd8 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -376,7 +376,7 @@ static void virtblk_config_changed(struct virtio_device *vdev) | |||
| 376 | 376 | ||
| 377 | static int init_vq(struct virtio_blk *vblk) | 377 | static int init_vq(struct virtio_blk *vblk) |
| 378 | { | 378 | { |
| 379 | int err = 0; | 379 | int err; |
| 380 | int i; | 380 | int i; |
| 381 | vq_callback_t **callbacks; | 381 | vq_callback_t **callbacks; |
| 382 | const char **names; | 382 | const char **names; |
| @@ -390,13 +390,13 @@ static int init_vq(struct virtio_blk *vblk) | |||
| 390 | if (err) | 390 | if (err) |
| 391 | num_vqs = 1; | 391 | num_vqs = 1; |
| 392 | 392 | ||
| 393 | vblk->vqs = kmalloc(sizeof(*vblk->vqs) * num_vqs, GFP_KERNEL); | 393 | vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); |
| 394 | if (!vblk->vqs) | 394 | if (!vblk->vqs) |
| 395 | return -ENOMEM; | 395 | return -ENOMEM; |
| 396 | 396 | ||
| 397 | names = kmalloc(sizeof(*names) * num_vqs, GFP_KERNEL); | 397 | names = kmalloc_array(num_vqs, sizeof(*names), GFP_KERNEL); |
| 398 | callbacks = kmalloc(sizeof(*callbacks) * num_vqs, GFP_KERNEL); | 398 | callbacks = kmalloc_array(num_vqs, sizeof(*callbacks), GFP_KERNEL); |
| 399 | vqs = kmalloc(sizeof(*vqs) * num_vqs, GFP_KERNEL); | 399 | vqs = kmalloc_array(num_vqs, sizeof(*vqs), GFP_KERNEL); |
| 400 | if (!names || !callbacks || !vqs) { | 400 | if (!names || !callbacks || !vqs) { |
| 401 | err = -ENOMEM; | 401 | err = -ENOMEM; |
| 402 | goto out; | 402 | goto out; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d433b1db1fdd..5649234b7316 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
| @@ -1539,19 +1539,29 @@ static void remove_port_data(struct port *port) | |||
| 1539 | spin_lock_irq(&port->inbuf_lock); | 1539 | spin_lock_irq(&port->inbuf_lock); |
| 1540 | /* Remove unused data this port might have received. */ | 1540 | /* Remove unused data this port might have received. */ |
| 1541 | discard_port_data(port); | 1541 | discard_port_data(port); |
| 1542 | spin_unlock_irq(&port->inbuf_lock); | ||
| 1542 | 1543 | ||
| 1543 | /* Remove buffers we queued up for the Host to send us data in. */ | 1544 | /* Remove buffers we queued up for the Host to send us data in. */ |
| 1544 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) | 1545 | do { |
| 1545 | free_buf(buf, true); | 1546 | spin_lock_irq(&port->inbuf_lock); |
| 1546 | spin_unlock_irq(&port->inbuf_lock); | 1547 | buf = virtqueue_detach_unused_buf(port->in_vq); |
| 1548 | spin_unlock_irq(&port->inbuf_lock); | ||
| 1549 | if (buf) | ||
| 1550 | free_buf(buf, true); | ||
| 1551 | } while (buf); | ||
| 1547 | 1552 | ||
| 1548 | spin_lock_irq(&port->outvq_lock); | 1553 | spin_lock_irq(&port->outvq_lock); |
| 1549 | reclaim_consumed_buffers(port); | 1554 | reclaim_consumed_buffers(port); |
| 1555 | spin_unlock_irq(&port->outvq_lock); | ||
| 1550 | 1556 | ||
| 1551 | /* Free pending buffers from the out-queue. */ | 1557 | /* Free pending buffers from the out-queue. */ |
| 1552 | while ((buf = virtqueue_detach_unused_buf(port->out_vq))) | 1558 | do { |
| 1553 | free_buf(buf, true); | 1559 | spin_lock_irq(&port->outvq_lock); |
| 1554 | spin_unlock_irq(&port->outvq_lock); | 1560 | buf = virtqueue_detach_unused_buf(port->out_vq); |
| 1561 | spin_unlock_irq(&port->outvq_lock); | ||
| 1562 | if (buf) | ||
| 1563 | free_buf(buf, true); | ||
| 1564 | } while (buf); | ||
| 1555 | } | 1565 | } |
| 1556 | 1566 | ||
| 1557 | /* | 1567 | /* |
diff --git a/drivers/virtio/config.c b/drivers/virtio/config.c deleted file mode 100644 index f70bcd2ff98f..000000000000 --- a/drivers/virtio/config.c +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | /* Configuration space parsing helpers for virtio. | ||
| 2 | * | ||
| 3 | * The configuration is [type][len][... len bytes ...] fields. | ||
| 4 | * | ||
| 5 | * Copyright 2007 Rusty Russell, IBM Corporation. | ||
| 6 | * GPL v2 or later. | ||
| 7 | */ | ||
| 8 | #include <linux/err.h> | ||
| 9 | #include <linux/virtio.h> | ||
| 10 | #include <linux/virtio_config.h> | ||
| 11 | #include <linux/bug.h> | ||
| 12 | |||
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 4e7003db12c4..181793f07852 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
| @@ -577,6 +577,8 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
| 577 | 577 | ||
| 578 | virtio_device_ready(vdev); | 578 | virtio_device_ready(vdev); |
| 579 | 579 | ||
| 580 | if (towards_target(vb)) | ||
| 581 | virtballoon_changed(vdev); | ||
| 580 | return 0; | 582 | return 0; |
| 581 | 583 | ||
| 582 | out_del_vqs: | 584 | out_del_vqs: |
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 8c4e61783441..6d9e5173d5fa 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c | |||
| @@ -212,10 +212,18 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) | |||
| 212 | return -ENODEV; | 212 | return -ENODEV; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64)); | 215 | rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); |
| 216 | if (rc) | 216 | if (rc) { |
| 217 | rc = dma_set_mask_and_coherent(&pci_dev->dev, | 217 | rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); |
| 218 | DMA_BIT_MASK(32)); | 218 | } else { |
| 219 | /* | ||
| 220 | * The virtio ring base address is expressed as a 32-bit PFN, | ||
| 221 | * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT. | ||
| 222 | */ | ||
| 223 | dma_set_coherent_mask(&pci_dev->dev, | ||
| 224 | DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT)); | ||
| 225 | } | ||
| 226 | |||
| 219 | if (rc) | 227 | if (rc) |
| 220 | dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n"); | 228 | dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n"); |
| 221 | 229 | ||
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index ed9c9eeedfe5..489bfc61cf30 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
| @@ -167,7 +167,7 @@ static bool vring_use_dma_api(struct virtio_device *vdev) | |||
| 167 | * making all of the arch DMA ops work on the vring device itself | 167 | * making all of the arch DMA ops work on the vring device itself |
| 168 | * is a mess. For now, we use the parent device for DMA ops. | 168 | * is a mess. For now, we use the parent device for DMA ops. |
| 169 | */ | 169 | */ |
| 170 | static struct device *vring_dma_dev(const struct vring_virtqueue *vq) | 170 | static inline struct device *vring_dma_dev(const struct vring_virtqueue *vq) |
| 171 | { | 171 | { |
| 172 | return vq->vq.vdev->dev.parent; | 172 | return vq->vq.vdev->dev.parent; |
| 173 | } | 173 | } |
| @@ -732,7 +732,8 @@ void virtqueue_disable_cb(struct virtqueue *_vq) | |||
| 732 | 732 | ||
| 733 | if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) { | 733 | if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) { |
| 734 | vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; | 734 | vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; |
| 735 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | 735 | if (!vq->event) |
| 736 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | ||
| 736 | } | 737 | } |
| 737 | 738 | ||
| 738 | } | 739 | } |
| @@ -764,7 +765,8 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq) | |||
| 764 | * entry. Always do both to keep code simple. */ | 765 | * entry. Always do both to keep code simple. */ |
| 765 | if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) { | 766 | if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) { |
| 766 | vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT; | 767 | vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT; |
| 767 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | 768 | if (!vq->event) |
| 769 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | ||
| 768 | } | 770 | } |
| 769 | vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx); | 771 | vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx); |
| 770 | END_USE(vq); | 772 | END_USE(vq); |
| @@ -832,10 +834,11 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) | |||
| 832 | * more to do. */ | 834 | * more to do. */ |
| 833 | /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to | 835 | /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to |
| 834 | * either clear the flags bit or point the event index at the next | 836 | * either clear the flags bit or point the event index at the next |
| 835 | * entry. Always do both to keep code simple. */ | 837 | * entry. Always update the event index to keep code simple. */ |
| 836 | if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) { | 838 | if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) { |
| 837 | vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT; | 839 | vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT; |
| 838 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | 840 | if (!vq->event) |
| 841 | vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow); | ||
| 839 | } | 842 | } |
| 840 | /* TODO: tune this threshold */ | 843 | /* TODO: tune this threshold */ |
| 841 | bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4; | 844 | bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4; |
| @@ -953,7 +956,8 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, | |||
| 953 | /* No callback? Tell other side not to bother us. */ | 956 | /* No callback? Tell other side not to bother us. */ |
| 954 | if (!callback) { | 957 | if (!callback) { |
| 955 | vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; | 958 | vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; |
| 956 | vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow); | 959 | if (!vq->event) |
| 960 | vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow); | ||
| 957 | } | 961 | } |
| 958 | 962 | ||
| 959 | /* Put everything in free lists. */ | 963 | /* Put everything in free lists. */ |
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile index 877a8a4721b6..c012edbdb13b 100644 --- a/tools/virtio/ringtest/Makefile +++ b/tools/virtio/ringtest/Makefile | |||
| @@ -3,8 +3,8 @@ all: | |||
| 3 | all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring | 3 | all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring |
| 4 | 4 | ||
| 5 | CFLAGS += -Wall | 5 | CFLAGS += -Wall |
| 6 | CFLAGS += -pthread -O2 -ggdb | 6 | CFLAGS += -pthread -O2 -ggdb -flto -fwhole-program |
| 7 | LDFLAGS += -pthread -O2 -ggdb | 7 | LDFLAGS += -pthread -O2 -ggdb -flto -fwhole-program |
| 8 | 8 | ||
| 9 | main.o: main.c main.h | 9 | main.o: main.c main.h |
| 10 | ring.o: ring.c main.h | 10 | ring.o: ring.c main.h |
diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c index 147abb452a6c..f31353fac541 100644 --- a/tools/virtio/ringtest/main.c +++ b/tools/virtio/ringtest/main.c | |||
| @@ -96,7 +96,13 @@ void set_affinity(const char *arg) | |||
| 96 | assert(!ret); | 96 | assert(!ret); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void run_guest(void) | 99 | void poll_used(void) |
| 100 | { | ||
| 101 | while (used_empty()) | ||
| 102 | busy_wait(); | ||
| 103 | } | ||
| 104 | |||
| 105 | static void __attribute__((__flatten__)) run_guest(void) | ||
| 100 | { | 106 | { |
| 101 | int completed_before; | 107 | int completed_before; |
| 102 | int completed = 0; | 108 | int completed = 0; |
| @@ -141,7 +147,7 @@ static void run_guest(void) | |||
| 141 | assert(completed <= bufs); | 147 | assert(completed <= bufs); |
| 142 | assert(started <= bufs); | 148 | assert(started <= bufs); |
| 143 | if (do_sleep) { | 149 | if (do_sleep) { |
| 144 | if (enable_call()) | 150 | if (used_empty() && enable_call()) |
| 145 | wait_for_call(); | 151 | wait_for_call(); |
| 146 | } else { | 152 | } else { |
| 147 | poll_used(); | 153 | poll_used(); |
| @@ -149,7 +155,13 @@ static void run_guest(void) | |||
| 149 | } | 155 | } |
| 150 | } | 156 | } |
| 151 | 157 | ||
| 152 | static void run_host(void) | 158 | void poll_avail(void) |
| 159 | { | ||
| 160 | while (avail_empty()) | ||
| 161 | busy_wait(); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void __attribute__((__flatten__)) run_host(void) | ||
| 153 | { | 165 | { |
| 154 | int completed_before; | 166 | int completed_before; |
| 155 | int completed = 0; | 167 | int completed = 0; |
| @@ -160,7 +172,7 @@ static void run_host(void) | |||
| 160 | 172 | ||
| 161 | for (;;) { | 173 | for (;;) { |
| 162 | if (do_sleep) { | 174 | if (do_sleep) { |
| 163 | if (enable_kick()) | 175 | if (avail_empty() && enable_kick()) |
| 164 | wait_for_kick(); | 176 | wait_for_kick(); |
| 165 | } else { | 177 | } else { |
| 166 | poll_avail(); | 178 | poll_avail(); |
diff --git a/tools/virtio/ringtest/main.h b/tools/virtio/ringtest/main.h index 16917acb0ade..34e63cc4c572 100644 --- a/tools/virtio/ringtest/main.h +++ b/tools/virtio/ringtest/main.h | |||
| @@ -56,15 +56,15 @@ void alloc_ring(void); | |||
| 56 | int add_inbuf(unsigned, void *, void *); | 56 | int add_inbuf(unsigned, void *, void *); |
| 57 | void *get_buf(unsigned *, void **); | 57 | void *get_buf(unsigned *, void **); |
| 58 | void disable_call(); | 58 | void disable_call(); |
| 59 | bool used_empty(); | ||
| 59 | bool enable_call(); | 60 | bool enable_call(); |
| 60 | void kick_available(); | 61 | void kick_available(); |
| 61 | void poll_used(); | ||
| 62 | /* host side */ | 62 | /* host side */ |
| 63 | void disable_kick(); | 63 | void disable_kick(); |
| 64 | bool avail_empty(); | ||
| 64 | bool enable_kick(); | 65 | bool enable_kick(); |
| 65 | bool use_buf(unsigned *, void **); | 66 | bool use_buf(unsigned *, void **); |
| 66 | void call_used(); | 67 | void call_used(); |
| 67 | void poll_avail(); | ||
| 68 | 68 | ||
| 69 | /* implemented by main */ | 69 | /* implemented by main */ |
| 70 | extern bool do_sleep; | 70 | extern bool do_sleep; |
diff --git a/tools/virtio/ringtest/noring.c b/tools/virtio/ringtest/noring.c index eda2f4824130..b8d1c1daac7c 100644 --- a/tools/virtio/ringtest/noring.c +++ b/tools/virtio/ringtest/noring.c | |||
| @@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp) | |||
| 24 | return "Buffer"; | 24 | return "Buffer"; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void poll_used(void) | 27 | bool used_empty() |
| 28 | { | 28 | { |
| 29 | return false; | ||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | void disable_call() | 32 | void disable_call() |
| @@ -54,8 +55,9 @@ bool enable_kick() | |||
| 54 | assert(0); | 55 | assert(0); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | void poll_avail(void) | 58 | bool avail_empty() |
| 58 | { | 59 | { |
| 60 | return false; | ||
| 59 | } | 61 | } |
| 60 | 62 | ||
| 61 | bool use_buf(unsigned *lenp, void **bufp) | 63 | bool use_buf(unsigned *lenp, void **bufp) |
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c index bd2ad1d3b7a9..635b07b4fdd3 100644 --- a/tools/virtio/ringtest/ptr_ring.c +++ b/tools/virtio/ringtest/ptr_ring.c | |||
| @@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp) | |||
| 133 | return datap; | 133 | return datap; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | void poll_used(void) | 136 | bool used_empty() |
| 137 | { | 137 | { |
| 138 | void *b; | 138 | return (tailcnt == headcnt || __ptr_ring_full(&array)); |
| 139 | |||
| 140 | do { | ||
| 141 | if (tailcnt == headcnt || __ptr_ring_full(&array)) { | ||
| 142 | b = NULL; | ||
| 143 | barrier(); | ||
| 144 | } else { | ||
| 145 | b = "Buffer\n"; | ||
| 146 | } | ||
| 147 | } while (!b); | ||
| 148 | } | 139 | } |
| 149 | 140 | ||
| 150 | void disable_call() | 141 | void disable_call() |
| @@ -173,14 +164,9 @@ bool enable_kick() | |||
| 173 | assert(0); | 164 | assert(0); |
| 174 | } | 165 | } |
| 175 | 166 | ||
| 176 | void poll_avail(void) | 167 | bool avail_empty() |
| 177 | { | 168 | { |
| 178 | void *b; | 169 | return !__ptr_ring_peek(&array); |
| 179 | |||
| 180 | do { | ||
| 181 | barrier(); | ||
| 182 | b = __ptr_ring_peek(&array); | ||
| 183 | } while (!b); | ||
| 184 | } | 170 | } |
| 185 | 171 | ||
| 186 | bool use_buf(unsigned *lenp, void **bufp) | 172 | bool use_buf(unsigned *lenp, void **bufp) |
diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c index c25c8d248b6b..747c5dd47be8 100644 --- a/tools/virtio/ringtest/ring.c +++ b/tools/virtio/ringtest/ring.c | |||
| @@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp) | |||
| 163 | return datap; | 163 | return datap; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void poll_used(void) | 166 | bool used_empty() |
| 167 | { | 167 | { |
| 168 | unsigned head = (ring_size - 1) & guest.last_used_idx; | 168 | unsigned head = (ring_size - 1) & guest.last_used_idx; |
| 169 | 169 | ||
| 170 | while (ring[head].flags & DESC_HW) | 170 | return (ring[head].flags & DESC_HW); |
| 171 | busy_wait(); | ||
| 172 | } | 171 | } |
| 173 | 172 | ||
| 174 | void disable_call() | 173 | void disable_call() |
| @@ -180,13 +179,11 @@ void disable_call() | |||
| 180 | 179 | ||
| 181 | bool enable_call() | 180 | bool enable_call() |
| 182 | { | 181 | { |
| 183 | unsigned head = (ring_size - 1) & guest.last_used_idx; | ||
| 184 | |||
| 185 | event->call_index = guest.last_used_idx; | 182 | event->call_index = guest.last_used_idx; |
| 186 | /* Flush call index write */ | 183 | /* Flush call index write */ |
| 187 | /* Barrier D (for pairing) */ | 184 | /* Barrier D (for pairing) */ |
| 188 | smp_mb(); | 185 | smp_mb(); |
| 189 | return ring[head].flags & DESC_HW; | 186 | return used_empty(); |
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | void kick_available(void) | 189 | void kick_available(void) |
| @@ -213,20 +210,17 @@ void disable_kick() | |||
| 213 | 210 | ||
| 214 | bool enable_kick() | 211 | bool enable_kick() |
| 215 | { | 212 | { |
| 216 | unsigned head = (ring_size - 1) & host.used_idx; | ||
| 217 | |||
| 218 | event->kick_index = host.used_idx; | 213 | event->kick_index = host.used_idx; |
| 219 | /* Barrier C (for pairing) */ | 214 | /* Barrier C (for pairing) */ |
| 220 | smp_mb(); | 215 | smp_mb(); |
| 221 | return !(ring[head].flags & DESC_HW); | 216 | return avail_empty(); |
| 222 | } | 217 | } |
| 223 | 218 | ||
| 224 | void poll_avail(void) | 219 | bool avail_empty() |
| 225 | { | 220 | { |
| 226 | unsigned head = (ring_size - 1) & host.used_idx; | 221 | unsigned head = (ring_size - 1) & host.used_idx; |
| 227 | 222 | ||
| 228 | while (!(ring[head].flags & DESC_HW)) | 223 | return !(ring[head].flags & DESC_HW); |
| 229 | busy_wait(); | ||
| 230 | } | 224 | } |
| 231 | 225 | ||
| 232 | bool use_buf(unsigned *lenp, void **bufp) | 226 | bool use_buf(unsigned *lenp, void **bufp) |
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c index 761866212aac..bbc3043b2fb1 100644 --- a/tools/virtio/ringtest/virtio_ring_0_9.c +++ b/tools/virtio/ringtest/virtio_ring_0_9.c | |||
| @@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp) | |||
| 194 | return datap; | 194 | return datap; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | void poll_used(void) | 197 | bool used_empty() |
| 198 | { | 198 | { |
| 199 | unsigned short last_used_idx = guest.last_used_idx; | ||
| 199 | #ifdef RING_POLL | 200 | #ifdef RING_POLL |
| 200 | unsigned head = (ring_size - 1) & guest.last_used_idx; | 201 | unsigned short head = last_used_idx & (ring_size - 1); |
| 202 | unsigned index = ring.used->ring[head].id; | ||
| 201 | 203 | ||
| 202 | for (;;) { | 204 | return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1); |
| 203 | unsigned index = ring.used->ring[head].id; | ||
| 204 | |||
| 205 | if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1)) | ||
| 206 | busy_wait(); | ||
| 207 | else | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | #else | 205 | #else |
| 211 | unsigned head = guest.last_used_idx; | 206 | return ring.used->idx == last_used_idx; |
| 212 | |||
| 213 | while (ring.used->idx == head) | ||
| 214 | busy_wait(); | ||
| 215 | #endif | 207 | #endif |
| 216 | } | 208 | } |
| 217 | 209 | ||
| @@ -224,22 +216,11 @@ void disable_call() | |||
| 224 | 216 | ||
| 225 | bool enable_call() | 217 | bool enable_call() |
| 226 | { | 218 | { |
| 227 | unsigned short last_used_idx; | 219 | vring_used_event(&ring) = guest.last_used_idx; |
| 228 | |||
| 229 | vring_used_event(&ring) = (last_used_idx = guest.last_used_idx); | ||
| 230 | /* Flush call index write */ | 220 | /* Flush call index write */ |
| 231 | /* Barrier D (for pairing) */ | 221 | /* Barrier D (for pairing) */ |
| 232 | smp_mb(); | 222 | smp_mb(); |
| 233 | #ifdef RING_POLL | 223 | return used_empty(); |
| 234 | { | ||
| 235 | unsigned short head = last_used_idx & (ring_size - 1); | ||
| 236 | unsigned index = ring.used->ring[head].id; | ||
| 237 | |||
| 238 | return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1); | ||
| 239 | } | ||
| 240 | #else | ||
| 241 | return ring.used->idx == last_used_idx; | ||
| 242 | #endif | ||
| 243 | } | 224 | } |
| 244 | 225 | ||
| 245 | void kick_available(void) | 226 | void kick_available(void) |
| @@ -266,36 +247,21 @@ void disable_kick() | |||
| 266 | 247 | ||
| 267 | bool enable_kick() | 248 | bool enable_kick() |
| 268 | { | 249 | { |
| 269 | unsigned head = host.used_idx; | 250 | vring_avail_event(&ring) = host.used_idx; |
| 270 | |||
| 271 | vring_avail_event(&ring) = head; | ||
| 272 | /* Barrier C (for pairing) */ | 251 | /* Barrier C (for pairing) */ |
| 273 | smp_mb(); | 252 | smp_mb(); |
| 274 | #ifdef RING_POLL | 253 | return avail_empty(); |
| 275 | { | ||
| 276 | unsigned index = ring.avail->ring[head & (ring_size - 1)]; | ||
| 277 | |||
| 278 | return (index ^ head ^ 0x8000) & ~(ring_size - 1); | ||
| 279 | } | ||
| 280 | #else | ||
| 281 | return head == ring.avail->idx; | ||
| 282 | #endif | ||
| 283 | } | 254 | } |
| 284 | 255 | ||
| 285 | void poll_avail(void) | 256 | bool avail_empty() |
| 286 | { | 257 | { |
| 287 | unsigned head = host.used_idx; | 258 | unsigned head = host.used_idx; |
| 288 | #ifdef RING_POLL | 259 | #ifdef RING_POLL |
| 289 | for (;;) { | 260 | unsigned index = ring.avail->ring[head & (ring_size - 1)]; |
| 290 | unsigned index = ring.avail->ring[head & (ring_size - 1)]; | 261 | |
| 291 | if ((index ^ head ^ 0x8000) & ~(ring_size - 1)) | 262 | return ((index ^ head ^ 0x8000) & ~(ring_size - 1)); |
| 292 | busy_wait(); | ||
| 293 | else | ||
| 294 | break; | ||
| 295 | } | ||
| 296 | #else | 263 | #else |
| 297 | while (ring.avail->idx == head) | 264 | return head == ring.avail->idx; |
| 298 | busy_wait(); | ||
| 299 | #endif | 265 | #endif |
| 300 | } | 266 | } |
| 301 | 267 | ||
