net: Make select() not spurious
[akaros.git] / user / vmm / sched.c
index 5b56a99..32c420e 100644 (file)
@@ -297,12 +297,22 @@ static void __attribute__((noreturn)) vmm_sched_entry(void)
 {
        struct vmm_thread *vth;
 
-       if (sched_is_greedy())
+       if (sched_is_greedy()) {
                vth = sched_pick_thread_greedy();
-       else
+               if (!vth) {
+                       /* sys_halt_core will return, but we need to restart the vcore.  We
+                        * might have woke due to an event, and we'll need to handle_events
+                        * and other things dealt with by uthreads. */
+                       if (vcore_id() == 0)
+                               sys_halt_core(0);
+                       /* In greedy mode, yield will abort and we'll just restart */
+                       vcore_yield_or_restart();
+               }
+       } else {
                vth = sched_pick_thread_nice();
-       if (!vth)
-               vcore_yield_or_restart();
+               if (!vth)
+                       vcore_yield_or_restart();
+       }
        stats_run_vth(vth);
        run_uthread((struct uthread*)vth);
 }
@@ -626,7 +636,8 @@ int vmm_init(struct virtual_machine *vm, struct vmm_gpcore_init *gpcis,
                assert(greedy_rnbl_guests);
                vcore_request_total(sched_nr_greedy_cores());
                syscall(SYS_vmm_ctl, VMM_CTL_SET_EXITS,
-                       syscall(SYS_vmm_ctl, VMM_CTL_GET_EXITS) & ~VMM_CTL_EXIT_HALT);
+                       syscall(SYS_vmm_ctl, VMM_CTL_GET_EXITS) &
+                               ~(VMM_CTL_EXIT_HALT | VMM_CTL_EXIT_MWAIT));
        }
        return 0;
 }
@@ -753,6 +764,8 @@ static void enqueue_vmm_thread(struct vmm_thread *vth)
                spin_pdr_lock(&queue_lock);
                TAILQ_INSERT_TAIL(&rnbl_tasks, vth, tq_next);
                spin_pdr_unlock(&queue_lock);
+               if (sched_is_greedy())
+                       vcore_wake(0, false);
                break;
        default:
                panic("Bad vmm_thread type %p\n", vth->type);