sched: Remove the idle core interface
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 13 Dec 2017 17:48:58 +0000 (12:48 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 13 Dec 2017 20:22:08 +0000 (15:22 -0500)
It's only used by ARSC code, which no one uses and probably needs a better
approach.

The code for the packed scheduler is buggy as hell:
- __get_any_idle_core doesn't return once it finds an item
- __get_any_idle_core uses uninitialized *spc
- There's no refcounting or interaction with the idle list.
- The UNNAMED_PROC is a problem too (prov -s crashes)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/corerequest.h
kern/include/schedule.h
kern/src/corealloc_fcfs.c
kern/src/corealloc_packed.c
kern/src/schedule.c

index 4ee0ea4..c637f90 100644 (file)
@@ -40,15 +40,6 @@ void __track_core_dealloc(struct proc *p, uint32_t pcoreid);
 void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
                                uint32_t nr_cores);
 
-/* Get/Put an idle core from our pcore list and return its core_id. Don't
- * consider the chosen core in the future when handing out cores to a
- * process. This code assumes that the scheduler that uses it holds a lock
- * for the duration of the call. This will not give out provisioned cores.
- * The gets return the coreid on success, -1 or -error on failure. */
-int __get_any_idle_core(void);
-int __get_specific_idle_core(int coreid);
-void __put_idle_core(int coreid);
-
 /* One off functions to make 'pcoreid' the next core chosen by the core
  * allocation algorithm (so long as no provisioned cores are still idle), and
  * to sort the idle core list for debugging. This code assumes that the
index 39b938f..eddcf8b 100644 (file)
@@ -66,16 +66,6 @@ void cpu_bored(void);
  * inappropriate, since we need to know which specific core is now free. */
 void avail_res_changed(int res_type, long change);
 
-/* Get and put idle CG cores.  Getting a core removes it from the idle list, and
- * the kernel can do whatever it wants with it.  All this means is that the
- * ksched won't hand out that core to a process.  This will not give out
- * provisioned cores.
- *
- * The gets return the coreid on success, -1 or -error on failure. */
-int get_any_idle_core(void);
-int get_specific_idle_core(int coreid);
-void put_idle_core(int coreid);
-
 /************** Provisioning / Allocating *************/
 /* This section is specific to a provisioning ksched.  Careful calling any of
  * this from generic kernel code, since it might not be present in all kernel
index 8df3f02..af4ab7c 100644 (file)
@@ -112,68 +112,6 @@ void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
                __track_core_dealloc(p, pc_arr[i]);
 }
 
-/* Get an idle core from our pcore list and return its core_id. Don't
- * consider the chosen core in the future when handing out cores to a
- * process. This code assumes that the scheduler that uses it holds a lock
- * for the duration of the call. This will not give out provisioned cores. */
-int __get_any_idle_core(void)
-{
-       struct sched_pcore *spc;
-       int ret = -1;
-
-       while ((spc = TAILQ_FIRST(&idlecores))) {
-               /* Don't take cores that are provisioned to a process */
-               if (spc->prov_proc)
-                       continue;
-               assert(!spc->alloc_proc);
-               TAILQ_REMOVE(&idlecores, spc, alloc_next);
-               ret = spc2pcoreid(spc);
-               break;
-       }
-       return ret;
-}
-
-/* Detect if a pcore is idle or not. */
-/* TODO: if we end up using this a lot, track CG-idleness as a property of
- * the SPC instead of doing a linear search. */
-static bool __spc_is_idle(struct sched_pcore *spc)
-{
-       struct sched_pcore *i;
-
-       TAILQ_FOREACH(i, &idlecores, alloc_next) {
-               if (spc == i)
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-/* Same as __get_any_idle_core() except for a specific core id. */
-int __get_specific_idle_core(int coreid)
-{
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-       int ret = -1;
-
-       assert((coreid >= 0) && (coreid < num_cores));
-       if (__spc_is_idle(pcoreid2spc(coreid)) && !spc->prov_proc) {
-               assert(!spc->alloc_proc);
-               TAILQ_REMOVE(&idlecores, spc, alloc_next);
-               ret = coreid;
-       }
-       return ret;
-}
-
-/* Reinsert a core obtained via __get_any_idle_core() or
- * __get_specific_idle_core() back into the idlecore map. This code assumes
- * that the scheduler that uses it holds a lock for the duration of the call.
- * This will not give out provisioned cores. */
-void __put_idle_core(int coreid)
-{
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-
-       assert((coreid >= 0) && (coreid < num_cores));
-       TAILQ_INSERT_TAIL(&idlecores, spc, alloc_next);
-}
-
 /* One off function to make 'pcoreid' the next core chosen by the core
  * allocation algorithm (so long as no provisioned cores are still idle).
  * This code assumes that the scheduler that uses it holds a lock for the
index 249c89b..9490257 100644 (file)
@@ -422,59 +422,6 @@ void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
                __track_core_dealloc(p, pc_arr[i]);
 }
 
-/* Get an idle core from our pcore list and return its core_id. Don't
- * consider the chosen core in the future when handing out cores to a
- * process. This code assumes that the scheduler that uses it holds a lock
- * for the duration of the call. This will not give out provisioned cores. */
-int __get_any_idle_core(void)
-{
-       struct sched_pcore *spc;
-       int ret = -1;
-
-       for (int i = 0; i < num_cores; i++) {
-               struct sched_pcore *c = &all_pcores[i];
-
-               if (spc->alloc_proc == NULL) {
-                       spc->alloc_proc = UNNAMED_PROC;
-                       ret = spc->core_info->core_id;
-               }
-       }
-       return ret;
-}
-
-/* Detect if a pcore is idle or not. */
-static bool __spc_is_idle(struct sched_pcore *spc)
-{
-       return (spc->alloc_proc == NULL);
-}
-
-/* Same as __get_any_idle_core() except for a specific core id. */
-int __get_specific_idle_core(int coreid)
-{
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-       int ret = -1;
-
-       assert((coreid >= 0) && (coreid < num_cores));
-       if (__spc_is_idle(pcoreid2spc(coreid)) && !spc->prov_proc) {
-               assert(!spc->alloc_proc);
-               spc->alloc_proc = UNNAMED_PROC;
-               ret = coreid;
-       }
-       return ret;
-}
-
-/* Reinsert a core obtained via __get_any_idle_core() or
- * __get_specific_idle_core() back into the idlecore map. This code assumes
- * that the scheduler that uses it holds a lock for the duration of the call.
- * This will not give out provisioned cores. */
-void __put_idle_core(int coreid)
-{
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-
-       assert((coreid >= 0) && (coreid < num_cores));
-       spc->alloc_proc = NULL;
-}
-
 /* One off function to make 'pcoreid' the next core chosen by the core
  * allocation algorithm (so long as no provisioned cores are still idle).
  * This code assumes that the scheduler that uses it holds a lock for the
index 7f4087d..d76055d 100644 (file)
@@ -111,6 +111,9 @@ void schedule_init(void)
        spin_unlock(&sched_lock);
 
 #ifdef CONFIG_ARSC_SERVER
+       /* Most likely we'll have a syscall and a process that dedicates itself to
+        * running this.  Or if it's a kthread, we don't need a core. */
+       #error "Find a way to get a core.  Probably a syscall to run a server."
        int arsc_coreid = get_any_idle_core();
        assert(arsc_coreid >= 0);
        send_kernel_message(arsc_coreid, arsc_server, 0, 0, 0, KMSG_ROUTINE);
@@ -495,30 +498,6 @@ void avail_res_changed(int res_type, long change)
        printk("[kernel] ksched doesn't track any resources yet!\n");
 }
 
-int get_any_idle_core(void)
-{
-       spin_lock(&sched_lock);
-       int ret = __get_any_idle_core();
-       spin_unlock(&sched_lock);
-       return ret;
-}
-
-int get_specific_idle_core(int coreid)
-{
-       spin_lock(&sched_lock);
-       int ret = __get_specific_idle_core(coreid);
-       spin_unlock(&sched_lock);
-       return ret;
-}
-
-/* similar to __sched_put_idle_core, but without the prov tracking */
-void put_idle_core(int coreid)
-{
-       spin_lock(&sched_lock);
-       __put_idle_core(coreid);
-       spin_unlock(&sched_lock);
-}
-
 /* 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).