Allows IRQs to be disabled while proc_destroy()ing
[akaros.git] / kern / src / schedule.c
index 054c878..0bc5bf0 100644 (file)
@@ -28,17 +28,12 @@ struct proc_list all_mcps_2 = TAILQ_HEAD_INITIALIZER(all_mcps_2);
 struct proc_list *primary_mcps = &all_mcps_1;
 struct proc_list *secondary_mcps = &all_mcps_2;
 
-/* TAILQ of all unallocated, idle (CG) cores.
- * Pulled from corealloc.c at the moment */
-extern struct sched_pcore_tailq idlecores;
-
 /* Helper, defined below */
 static void __core_request(struct proc *p, uint32_t amt_needed);
 static void add_to_list(struct proc *p, struct proc_list *list);
 static void remove_from_list(struct proc *p, struct proc_list *list);
 static void switch_lists(struct proc *p, struct proc_list *old,
                          struct proc_list *new);
-static bool is_ll_core(uint32_t pcoreid);
 static void __run_mcp_ksched(void *arg);       /* don't call directly */
 static uint32_t get_cores_needed(struct proc *p);
 
@@ -63,12 +58,10 @@ struct poke_tracker ksched_poker = POKE_INITIALIZER(__run_mcp_ksched);
  * of a proc on those lists.  proc lifetime within the ksched but outside this
  * lock is protected by the proc kref. */
 //spinlock_t proclist_lock = SPINLOCK_INITIALIZER; /* subsumed by bksl */
-/* - protects the provisioning assignment, membership of sched_pcores in
- * provision lists, and the integrity of all prov lists (the lists of each
- * proc).  does NOT protect spc->alloc_proc. */
+/* - protects the provisioning assignment, and the integrity of all prov
+ * lists (the lists of each proc). */
 //spinlock_t prov_lock = SPINLOCK_INITIALIZER;
-/* - protects allocation structures: spc->alloc_proc, the integrity and
- * membership of the idelcores tailq. */
+/* - protects allocation structures */
 //spinlock_t alloc_lock = SPINLOCK_INITIALIZER;
 spinlock_t sched_lock = SPINLOCK_INITIALIZER;
 
@@ -170,7 +163,7 @@ void __sched_proc_register(struct proc *p)
        /* one ref for the proc's existence, cradle-to-grave */
        proc_incref(p, 1);      /* need at least this OR the 'one for existing' */
        spin_lock(&sched_lock);
-       coreprov_proc_init(p);
+       corealloc_proc_init(p);
        add_to_list(p, &unrunnable_scps);
        spin_unlock(&sched_lock);
 }
@@ -274,7 +267,6 @@ void __sched_scp_wakeup(struct proc *p)
  * a scheduling decision (or at least plan to). */
 void __sched_put_idle_core(struct proc *p, uint32_t coreid)
 {
-       struct sched_pcore *spc = pcoreid2spc(coreid);
        spin_lock(&sched_lock);
        __track_core_dealloc(p, coreid);
        spin_unlock(&sched_lock);
@@ -298,13 +290,9 @@ static bool __schedule_scp(void)
        struct proc *p;
        uint32_t pcoreid = core_id();
        struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
-       int8_t state = 0;
        /* if there are any runnables, run them here and put any currently running
         * SCP on the tail of the runnable queue. */
        if ((p = TAILQ_FIRST(&runnable_scps))) {
-               /* protect owning proc, cur_ctx, etc.  note this nests with the
-                * calls in proc_yield_s */
-               disable_irqsave(&state);
                /* someone is currently running, dequeue them */
                if (pcpui->owning_proc) {
                        spin_lock(&pcpui->owning_proc->proc_lock);
@@ -314,7 +302,6 @@ static bool __schedule_scp(void)
                                send_kernel_message(core_id(), __just_sched, 0, 0, 0,
                                                    KMSG_ROUTINE);
                                spin_unlock(&pcpui->owning_proc->proc_lock);
-                               enable_irqsave(&state);
                                return FALSE;
                        }
                        printd("Descheduled %d in favor of %d\n", pcpui->owning_proc->pid,
@@ -323,7 +310,7 @@ static bool __schedule_scp(void)
                        /* Saving FP state aggressively.  Odds are, the SCP was hit by an
                         * IRQ and has a HW ctx, in which case we must save. */
                        __proc_save_fpu_s(pcpui->owning_proc);
-                       __proc_save_context_s(pcpui->owning_proc, pcpui->cur_ctx);
+                       __proc_save_context_s(pcpui->owning_proc);
                        vcore_account_offline(pcpui->owning_proc, 0);
                        __seq_start_write(&p->procinfo->coremap_seqctr);
                        __unmap_vcore(p, 0);
@@ -343,7 +330,6 @@ static bool __schedule_scp(void)
                switch_lists(p, &runnable_scps, &unrunnable_scps);
                printd("PID of the SCP i'm running: %d\n", p->pid);
                proc_run_s(p);  /* gives it core we're running on */
-               enable_irqsave(&state);
                return TRUE;
        }
        return FALSE;
@@ -535,17 +521,6 @@ void put_idle_core(int coreid)
        spin_unlock(&sched_lock);
 }
 
-/* Normally it'll be the max number of CG cores ever */
-uint32_t max_vcores(struct proc *p)
-{
-/* TODO: (CG/LL) */
-#ifdef CONFIG_DISABLE_SMT
-       return num_cores >> 1;
-#else
-       return num_cores - 1;   /* reserving core 0 */
-#endif /* CONFIG_DISABLE_SMT */
-}
-
 /* This deals with a request for more cores.  The amt of new cores needed is
  * passed in.  The ksched lock is held, but we are free to unlock if we want
  * (and we must, if calling out of the ksched to anything high-level).
@@ -559,7 +534,7 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
 {
        uint32_t nr_to_grant = 0;
        uint32_t corelist[num_cores];
-       struct sched_pcore *spc_i, *temp;
+       uint32_t pcoreid;
        struct proc *proc_to_preempt;
        bool success;
        /* we come in holding the ksched lock, and we hold it here to protect
@@ -570,24 +545,24 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
        while (nr_to_grant != amt_needed) {
                /* Find the next best core to allocate to p. It may be a core
                 * provisioned to p, and it might not be. */
-               spc_i = __find_best_core_to_alloc(p);
+               pcoreid = __find_best_core_to_alloc(p);
                /* If no core is returned, we know that there are no more cores to give
                 * out, so we exit the loop. */
-               if (spc_i == NULL)
+               if (pcoreid == -1)
                        break;
                /* If the pcore chosen currently has a proc allocated to it, we know
                 * it must be provisioned to p, but not allocated to it. We need to try
                 * to preempt. After this block, the core will be track_dealloc'd and
                 * on the idle list (regardless of whether we had to preempt or not) */
-               if (get_alloc_proc(spc_i)) {
-                       proc_to_preempt = get_alloc_proc(spc_i);
+               if (get_alloc_proc(pcoreid)) {
+                       proc_to_preempt = get_alloc_proc(pcoreid);
                        /* would break both preemption and maybe the later decref */
                        assert(proc_to_preempt != p);
                        /* need to keep a valid, external ref when we unlock */
                        proc_incref(proc_to_preempt, 1);
                        spin_unlock(&sched_lock);
                        /* sending no warning time for now - just an immediate preempt. */
-                       success = proc_preempt_core(proc_to_preempt, spc2pcoreid(spc_i), 0);
+                       success = proc_preempt_core(proc_to_preempt, pcoreid, 0);
                        /* reaquire locks to protect provisioning and idle lists */
                        spin_lock(&sched_lock);
                        if (success) {
@@ -596,11 +571,11 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
                                 * idle CBs).  the core is not on the idle core list.  (if we
                                 * ever have proc alloc lists, it'll still be on the old proc's
                                 * list). */
-                               assert(get_alloc_proc(spc_i));
+                               assert(get_alloc_proc(pcoreid));
                                /* regardless of whether or not it is still prov to p, we need
                                 * to note its dealloc.  we are doing some excessive checking of
                                 * p == prov_proc, but using this helper is a lot clearer. */
-                               __track_core_dealloc(proc_to_preempt, spc2pcoreid(spc_i));
+                               __track_core_dealloc(proc_to_preempt, pcoreid);
                        } else {
                                /* the preempt failed, which should only happen if the pcore was
                                 * unmapped (could be dying, could be yielding, but NOT
@@ -618,7 +593,7 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
                                 * allocator, the pcore could have been put on the idle list and
                                 * then quickly removed/allocated. */
                                cmb();
-                               while (get_alloc_proc(spc_i)) {
+                               while (get_alloc_proc(pcoreid)) {
                                        /* this loop should be very rare */
                                        spin_unlock(&sched_lock);
                                        udelay(1);
@@ -627,9 +602,9 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
                        }
                        /* no longer need to keep p_to_pre alive */
                        proc_decref(proc_to_preempt);
-                       /* might not be prov to p anymore (rare race).  spc_i is idle - we
+                       /* might not be prov to p anymore (rare race). pcoreid is idle - we
                         * might get it later, or maybe we'll give it to its rightful proc*/
-                       if (get_prov_proc(spc_i) != p)
+                       if (get_prov_proc(pcoreid) != p)
                                continue;
                }
                /* At this point, the pcore is idle, regardless of how we got here
@@ -637,13 +612,13 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
                 * place).  We also know the core is still provisioned to us.  Lets add
                 * it to the corelist for p (so we can give it to p in bulk later), and
                 * track its allocation with p (so our internal data structures stay in
-                * sync). We rely on the fact that we are the only allocator (spc_i is
+                * sync). We rely on the fact that we are the only allocator (pcoreid is
                 * still idle, despite (potentially) unlocking during the preempt
                 * attempt above).  It is guaranteed to be track_dealloc'd()
                 * (regardless of how we got here). */
-               corelist[nr_to_grant] = spc2pcoreid(spc_i);
+               corelist[nr_to_grant] = pcoreid;
                nr_to_grant++;
-               __track_core_alloc(p, spc2pcoreid(spc_i));
+               __track_core_alloc(p, pcoreid);
        }
        /* Now, actually give them out */
        if (nr_to_grant) {
@@ -680,22 +655,10 @@ static void __core_request(struct proc *p, uint32_t amt_needed)
        /* note the ksched lock is still held */
 }
 
-/* TODO: need more thorough CG/LL management.  For now, core0 is the only LL
- * core.  This won't play well with the ghetto shit in schedule_init() if you do
- * anything like 'DEDICATED_MONITOR' or the ARSC server.  All that needs an
- * overhaul. */
-static bool is_ll_core(uint32_t pcoreid)
-{
-       if (pcoreid == 0)
-               return TRUE;
-       return FALSE;
-}
-
 /* Provision a core to a process. This function wraps the primary logic
  * implemented in __provision_core, with a lock, error checking, etc. */
 int provision_core(struct proc *p, uint32_t pcoreid)
 {
-       struct sched_pcore *spc;
        /* Make sure we aren't asking for something that doesn't exist (bounds check
         * on the pcore array) */
        if (!(pcoreid < num_cores)) {
@@ -707,12 +670,11 @@ int provision_core(struct proc *p, uint32_t pcoreid)
                set_errno(EBUSY);
                return -1;
        }
-       spc = pcoreid2spc(pcoreid);
-       /* Note the sched lock protects the spc tailqs for all procs in this code.
+       /* Note the sched lock protects the tailqs for all procs in this code.
         * If we need a finer grained sched lock, this is one place where we could
         * have a different lock */
        spin_lock(&sched_lock);
-       __provision_core(p, spc);
+       __provision_core(p, pcoreid);
        spin_unlock(&sched_lock);
        return 0;
 }