From 11b8990d195e1356eb0f046e83e8f1ea708e1a53 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 28 Feb 2012 09:01:26 +0200 Subject: tools/virtio: add linux/module.h stub Make the tool build again after virtio changes broke it. Signed-off-by: Michael S. Tsirkin diff --git a/tools/virtio/linux/module.h b/tools/virtio/linux/module.h new file mode 100644 index 0000000..e69de29 -- cgit v0.10.2 From b0820a50a0439764411b779208f0e6a67b937e72 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 28 Feb 2012 09:02:53 +0200 Subject: tools/virtio: add linux/hrtimer.h stub Make tool build after virtio changes broke it. Signed-off-by: Michael S. Tsirkin diff --git a/tools/virtio/linux/hrtimer.h b/tools/virtio/linux/hrtimer.h new file mode 100644 index 0000000..e69de29 -- cgit v0.10.2 From b17d5c6e190f3d328aae0444f8b93d58d0015714 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 28 Feb 2012 09:07:58 +0200 Subject: tools/virtio: stub out strong barriers The tool should never use them, abort if it does. Signed-off-by: Michael S. Tsirkin diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index b4fbc91..7579f19 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -181,6 +181,9 @@ struct virtqueue { #define smp_mb() mb() # define smp_rmb() barrier() # define smp_wmb() barrier() +/* Weak barriers should be used. If not - it's a bug */ +# define rmb() abort() +# define wmb() abort() #else #error Please fill in barrier macros #endif -- cgit v0.10.2 From d550dda192c1bd039afb774b99485e88b70d7cb8 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Mon, 27 Feb 2012 15:07:29 +0200 Subject: vhost: don't forget to schedule() This is a tiny, but important, patch to vhost. Vhost's worker thread only called schedule() when it had no work to do, and it wanted to go to sleep. But if there's always work to do, e.g., the guest is running a network-intensive program like netperf with small message sizes, schedule() was *never* called. This had several negative implications (on non-preemptive kernels): 1. Passing time was not properly accounted to the "vhost" process (ps and top would wrongly show it using zero CPU time). 2. Sometimes error messages about RCU timeouts would be printed, if the core running the vhost thread didn't schedule() for a very long time. 3. Worst of all, a vhost thread would "hog" the core. If several vhost threads need to share the same core, typically one would get most of the CPU time (and its associated guest most of the performance), while the others hardly get any work done. The trivial solution is to add if (need_resched()) schedule(); After doing every piece of work. This will not do the heavy schedule() all the time, just when the timer interrupt decided a reschedule is warranted (so need_resched returns true). Thanks to Abel Gordon for this patch. Signed-off-by: Nadav Har'El Signed-off-by: Michael S. Tsirkin diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c14c42b..ae66278 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -222,6 +222,8 @@ static int vhost_worker(void *data) if (work) { __set_current_state(TASK_RUNNING); work->fn(work); + if (need_resched()) + schedule(); } else schedule(); -- cgit v0.10.2 From ea5d404655ba3b356d0c06d6a3c4f24112124522 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 27 Nov 2011 19:05:58 +0200 Subject: vhost: fix release path lockdep checks We shouldn't hold any locks on release path. Pass a flag to vhost_dev_cleanup to use the lockdep info correctly. Signed-off-by: Michael S. Tsirkin Tested-by: Sasha Levin diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 9dab1f5..f0da2c3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -588,7 +588,7 @@ static int vhost_net_release(struct inode *inode, struct file *f) vhost_net_stop(n, &tx_sock, &rx_sock); vhost_net_flush(n); - vhost_dev_cleanup(&n->dev); + vhost_dev_cleanup(&n->dev, false); if (tx_sock) fput(tx_sock->file); if (rx_sock) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ae66278..385d8ee 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -405,7 +405,7 @@ long vhost_dev_reset_owner(struct vhost_dev *dev) if (!memory) return -ENOMEM; - vhost_dev_cleanup(dev); + vhost_dev_cleanup(dev, true); memory->nregions = 0; RCU_INIT_POINTER(dev->memory, memory); @@ -436,8 +436,8 @@ int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq) return j; } -/* Caller should have device mutex */ -void vhost_dev_cleanup(struct vhost_dev *dev) +/* Caller should have device mutex if and only if locked is set */ +void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) { int i; @@ -474,7 +474,8 @@ void vhost_dev_cleanup(struct vhost_dev *dev) dev->log_file = NULL; /* No one will access memory at this point */ kfree(rcu_dereference_protected(dev->memory, - lockdep_is_held(&dev->mutex))); + locked == + lockdep_is_held(&dev->mutex))); RCU_INIT_POINTER(dev->memory, NULL); WARN_ON(!list_empty(&dev->work_list)); if (dev->worker) { diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index a801e28..8dcf4cc 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -163,7 +163,7 @@ struct vhost_dev { long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs); long vhost_dev_check_owner(struct vhost_dev *); long vhost_dev_reset_owner(struct vhost_dev *); -void vhost_dev_cleanup(struct vhost_dev *); +void vhost_dev_cleanup(struct vhost_dev *, bool locked); long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg); int vhost_vq_access_ok(struct vhost_virtqueue *vq); int vhost_log_access_ok(struct vhost_dev *); -- cgit v0.10.2