aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost
diff options
context:
space:
mode:
authorNadav Har'El <nyh@math.technion.ac.il>2012-02-27 15:07:29 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 08:47:51 -0700
commitdf5d64692d422f7df2e3221a95408b4ccf520fd0 (patch)
tree97e28227ec4f858742d254e3f8edc0397a38089c /drivers/vhost
parentf437e75ac267fa886bcbe7ab40d8f1ba1de1c865 (diff)
downloadkernel_samsung_smdk4412-df5d64692d422f7df2e3221a95408b4ccf520fd0.zip
kernel_samsung_smdk4412-df5d64692d422f7df2e3221a95408b4ccf520fd0.tar.gz
kernel_samsung_smdk4412-df5d64692d422f7df2e3221a95408b4ccf520fd0.tar.bz2
vhost: don't forget to schedule()
commit d550dda192c1bd039afb774b99485e88b70d7cb8 upstream. 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 <nyh@il.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Cc: Jean Delvare <jdelvare@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/vhost')
-rw-r--r--drivers/vhost/vhost.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index ea966b3..61047fe 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -217,6 +217,8 @@ static int vhost_worker(void *data)
if (work) {
__set_current_state(TASK_RUNNING);
work->fn(work);
+ if (need_resched())
+ schedule();
} else
schedule();