Skip to content

Commit

Permalink
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/mst/vhost

Pull virtio updates from Michael Tsirkin:
 "Tests, fixes and cleanups.

  Just minor tweaks, there's nothing major in this cycle"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  virtio_ring: mark vring_dma_dev inline
  virtio/vhost: add Jason to list of maintainers
  virtio_blk: Delete an unnecessary initialisation in init_vq()
  virtio_blk: Use kmalloc_array() in init_vq()
  virtio: remove config.c
  virtio: console: Unlock vqs while freeing buffers
  ringtest: poll for new buffers once before updating event index
  ringtest: commonize implementation of poll_avail/poll_used
  ringtest: use link-time optimization
  virtio: update balloon size in balloon "probe"
  virtio_ring: Make interrupt suppression spec compliant
  virtio_pci: Limit DMA mask to 44 bits for legacy virtio devices
  • Loading branch information
Linus Torvalds committed Nov 1, 2016
2 parents a75e003 + 75bfa81 commit 04659fe
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 122 deletions.
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -12783,6 +12783,7 @@ F: include/uapi/linux/virtio_console.h

VIRTIO CORE, NET AND BLOCK DRIVERS
M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowang@redhat.com>
L: virtualization@lists.linux-foundation.org
S: Maintained
F: Documentation/devicetree/bindings/virtio/
Expand Down Expand Up @@ -12813,6 +12814,7 @@ F: include/uapi/linux/virtio_gpu.h

VIRTIO HOST (VHOST)
M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowang@redhat.com>
L: kvm@vger.kernel.org
L: virtualization@lists.linux-foundation.org
L: netdev@vger.kernel.org
Expand Down
10 changes: 5 additions & 5 deletions drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ static void virtblk_config_changed(struct virtio_device *vdev)

static int init_vq(struct virtio_blk *vblk)
{
int err = 0;
int err;
int i;
vq_callback_t **callbacks;
const char **names;
Expand All @@ -390,13 +390,13 @@ static int init_vq(struct virtio_blk *vblk)
if (err)
num_vqs = 1;

vblk->vqs = kmalloc(sizeof(*vblk->vqs) * num_vqs, GFP_KERNEL);
vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL);
if (!vblk->vqs)
return -ENOMEM;

names = kmalloc(sizeof(*names) * num_vqs, GFP_KERNEL);
callbacks = kmalloc(sizeof(*callbacks) * num_vqs, GFP_KERNEL);
vqs = kmalloc(sizeof(*vqs) * num_vqs, GFP_KERNEL);
names = kmalloc_array(num_vqs, sizeof(*names), GFP_KERNEL);
callbacks = kmalloc_array(num_vqs, sizeof(*callbacks), GFP_KERNEL);
vqs = kmalloc_array(num_vqs, sizeof(*vqs), GFP_KERNEL);
if (!names || !callbacks || !vqs) {
err = -ENOMEM;
goto out;
Expand Down
22 changes: 16 additions & 6 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,19 +1539,29 @@ static void remove_port_data(struct port *port)
spin_lock_irq(&port->inbuf_lock);
/* Remove unused data this port might have received. */
discard_port_data(port);
spin_unlock_irq(&port->inbuf_lock);

/* Remove buffers we queued up for the Host to send us data in. */
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
free_buf(buf, true);
spin_unlock_irq(&port->inbuf_lock);
do {
spin_lock_irq(&port->inbuf_lock);
buf = virtqueue_detach_unused_buf(port->in_vq);
spin_unlock_irq(&port->inbuf_lock);
if (buf)
free_buf(buf, true);
} while (buf);

spin_lock_irq(&port->outvq_lock);
reclaim_consumed_buffers(port);
spin_unlock_irq(&port->outvq_lock);

/* Free pending buffers from the out-queue. */
while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
free_buf(buf, true);
spin_unlock_irq(&port->outvq_lock);
do {
spin_lock_irq(&port->outvq_lock);
buf = virtqueue_detach_unused_buf(port->out_vq);
spin_unlock_irq(&port->outvq_lock);
if (buf)
free_buf(buf, true);
} while (buf);
}

/*
Expand Down
12 changes: 0 additions & 12 deletions drivers/virtio/config.c

This file was deleted.

2 changes: 2 additions & 0 deletions drivers/virtio/virtio_balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,8 @@ static int virtballoon_probe(struct virtio_device *vdev)

virtio_device_ready(vdev);

if (towards_target(vb))
virtballoon_changed(vdev);
return 0;

out_del_vqs:
Expand Down
16 changes: 12 additions & 4 deletions drivers/virtio/virtio_pci_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,18 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
return -ENODEV;
}

rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
if (rc)
rc = dma_set_mask_and_coherent(&pci_dev->dev,
DMA_BIT_MASK(32));
rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
} else {
/*
* The virtio ring base address is expressed as a 32-bit PFN,
* with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT.
*/
dma_set_coherent_mask(&pci_dev->dev,
DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT));
}

if (rc)
dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");

Expand Down
16 changes: 10 additions & 6 deletions drivers/virtio/virtio_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
* making all of the arch DMA ops work on the vring device itself
* is a mess. For now, we use the parent device for DMA ops.
*/
static struct device *vring_dma_dev(const struct vring_virtqueue *vq)
static inline struct device *vring_dma_dev(const struct vring_virtqueue *vq)
{
return vq->vq.vdev->dev.parent;
}
Expand Down Expand Up @@ -732,7 +732,8 @@ void virtqueue_disable_cb(struct virtqueue *_vq)

if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
if (!vq->event)
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
}

}
Expand Down Expand Up @@ -764,7 +765,8 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
* entry. Always do both to keep code simple. */
if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
if (!vq->event)
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
}
vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
END_USE(vq);
Expand Down Expand Up @@ -832,10 +834,11 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
* more to do. */
/* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
* either clear the flags bit or point the event index at the next
* entry. Always do both to keep code simple. */
* entry. Always update the event index to keep code simple. */
if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
if (!vq->event)
vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
}
/* TODO: tune this threshold */
bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
Expand Down Expand Up @@ -953,7 +956,8 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
/* No callback? Tell other side not to bother us. */
if (!callback) {
vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
if (!vq->event)
vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
}

/* Put everything in free lists. */
Expand Down
4 changes: 2 additions & 2 deletions tools/virtio/ringtest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ all:
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring

CFLAGS += -Wall
CFLAGS += -pthread -O2 -ggdb
LDFLAGS += -pthread -O2 -ggdb
CFLAGS += -pthread -O2 -ggdb -flto -fwhole-program
LDFLAGS += -pthread -O2 -ggdb -flto -fwhole-program

main.o: main.c main.h
ring.o: ring.c main.h
Expand Down
20 changes: 16 additions & 4 deletions tools/virtio/ringtest/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ void set_affinity(const char *arg)
assert(!ret);
}

static void run_guest(void)
void poll_used(void)
{
while (used_empty())
busy_wait();
}

static void __attribute__((__flatten__)) run_guest(void)
{
int completed_before;
int completed = 0;
Expand Down Expand Up @@ -141,15 +147,21 @@ static void run_guest(void)
assert(completed <= bufs);
assert(started <= bufs);
if (do_sleep) {
if (enable_call())
if (used_empty() && enable_call())
wait_for_call();
} else {
poll_used();
}
}
}

static void run_host(void)
void poll_avail(void)
{
while (avail_empty())
busy_wait();
}

static void __attribute__((__flatten__)) run_host(void)
{
int completed_before;
int completed = 0;
Expand All @@ -160,7 +172,7 @@ static void run_host(void)

for (;;) {
if (do_sleep) {
if (enable_kick())
if (avail_empty() && enable_kick())
wait_for_kick();
} else {
poll_avail();
Expand Down
4 changes: 2 additions & 2 deletions tools/virtio/ringtest/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ void alloc_ring(void);
int add_inbuf(unsigned, void *, void *);
void *get_buf(unsigned *, void **);
void disable_call();
bool used_empty();
bool enable_call();
void kick_available();
void poll_used();
/* host side */
void disable_kick();
bool avail_empty();
bool enable_kick();
bool use_buf(unsigned *, void **);
void call_used();
void poll_avail();

/* implemented by main */
extern bool do_sleep;
Expand Down
6 changes: 4 additions & 2 deletions tools/virtio/ringtest/noring.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return "Buffer";
}

void poll_used(void)
bool used_empty()
{
return false;
}

void disable_call()
Expand Down Expand Up @@ -54,8 +55,9 @@ bool enable_kick()
assert(0);
}

void poll_avail(void)
bool avail_empty()
{
return false;
}

bool use_buf(unsigned *lenp, void **bufp)
Expand Down
22 changes: 4 additions & 18 deletions tools/virtio/ringtest/ptr_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap;
}

void poll_used(void)
bool used_empty()
{
void *b;

do {
if (tailcnt == headcnt || __ptr_ring_full(&array)) {
b = NULL;
barrier();
} else {
b = "Buffer\n";
}
} while (!b);
return (tailcnt == headcnt || __ptr_ring_full(&array));
}

void disable_call()
Expand Down Expand Up @@ -173,14 +164,9 @@ bool enable_kick()
assert(0);
}

void poll_avail(void)
bool avail_empty()
{
void *b;

do {
barrier();
b = __ptr_ring_peek(&array);
} while (!b);
return !__ptr_ring_peek(&array);
}

bool use_buf(unsigned *lenp, void **bufp)
Expand Down
18 changes: 6 additions & 12 deletions tools/virtio/ringtest/ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap;
}

void poll_used(void)
bool used_empty()
{
unsigned head = (ring_size - 1) & guest.last_used_idx;

while (ring[head].flags & DESC_HW)
busy_wait();
return (ring[head].flags & DESC_HW);
}

void disable_call()
Expand All @@ -180,13 +179,11 @@ void disable_call()

bool enable_call()
{
unsigned head = (ring_size - 1) & guest.last_used_idx;

event->call_index = guest.last_used_idx;
/* Flush call index write */
/* Barrier D (for pairing) */
smp_mb();
return ring[head].flags & DESC_HW;
return used_empty();
}

void kick_available(void)
Expand All @@ -213,20 +210,17 @@ void disable_kick()

bool enable_kick()
{
unsigned head = (ring_size - 1) & host.used_idx;

event->kick_index = host.used_idx;
/* Barrier C (for pairing) */
smp_mb();
return !(ring[head].flags & DESC_HW);
return avail_empty();
}

void poll_avail(void)
bool avail_empty()
{
unsigned head = (ring_size - 1) & host.used_idx;

while (!(ring[head].flags & DESC_HW))
busy_wait();
return !(ring[head].flags & DESC_HW);
}

bool use_buf(unsigned *lenp, void **bufp)
Expand Down
Loading

0 comments on commit 04659fe

Please sign in to comment.