vmm: Prioritize task threads over guest threads
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 14 Aug 2017 16:01:09 +0000 (12:01 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 14 Aug 2017 21:02:20 +0000 (17:02 -0400)
Originally, we had some task threads that would busy wait, so we had to
alternate between tasks and guests.  Otherwise, the task threads would
starve the guests.

However, with Gan's "thread per timer tick per core" change, multicore VMs
running on an SCP VMMs ran into problems.  The guest cores would starve out
the task threads.  Specifically, every guest LAPIC timer tick we'd create N
task threads.  We'd run one of them, then the next *vcore* tick we'd run a
guest thread - which would spin in Linux in smp_call_function().  The N-1
other alarms would wait.  By the time those threads got their chance to run
(vcore tick), we'd also have N more LAPIC timer threads created.  So we'd
grow the number of threads by N-1 every tick (1 msec).

Anyway, this turned out to be an easy fix: prioritize task threads, like I
originally wanted to.  The old task thread that was busy waiting was
replaced a while ago.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/vmm/sched.c

index b44c44f..dd93702 100644 (file)
@@ -164,26 +164,12 @@ static struct vmm_thread *__pop_first(struct vmm_thread_tq *tq)
 
 static struct vmm_thread *pick_a_thread_degraded(void)
 {
-       struct vmm_thread *vth = 0;
-       static int next_class = VMM_THREAD_GUEST;
+       struct vmm_thread *vth;
 
-       /* We don't have a lot of cores (maybe 0), so we'll alternate which type of
-        * thread we look at first.  Basically, we're RR within a class of threads,
-        * and we'll toggle between those two classes. */
        spin_pdr_lock(&queue_lock);
-       if (next_class == VMM_THREAD_GUEST) {
-               if (!vth)
-                       vth = __pop_first(&rnbl_guests);
-               if (!vth)
-                       vth = __pop_first(&rnbl_tasks);
-               next_class = VMM_THREAD_TASK;
-       } else {
-               if (!vth)
-                       vth = __pop_first(&rnbl_tasks);
-               if (!vth)
-                       vth = __pop_first(&rnbl_guests);
-               next_class = VMM_THREAD_GUEST;
-       };
+       vth = __pop_first(&rnbl_tasks);
+       if (!vth)
+               vth = __pop_first(&rnbl_guests);
        spin_pdr_unlock(&queue_lock);
        return vth;
 }