sched: Touch up the packed scheduler

These are from my code review from the initial posting of the packed
scheduler.

The biggest fix was the TAILQ bug, since alloc_next is used for two lists.
The other stuff is mostly for clarity.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/corealloc_packed.c b/kern/src/corealloc_packed.c
index bd1957d..64b8000 100644
--- a/kern/src/corealloc_packed.c
+++ b/kern/src/corealloc_packed.c
@@ -11,7 +11,14 @@
 #include <kmalloc.h>
 
 enum pnode_type { CORE, CPU, SOCKET, NUMA, MACHINE, NUM_NODE_TYPES };
-static char pnode_label[5][8] = { "CORE", "CPU", "SOCKET", "NUMA", "MACHINE" };
+
+static const char * const pnode_label[] = {
+	[CORE] = "CORE",
+	[CPU] = "CPU",
+	[SOCKET] = "SOCKET",
+	[NUMA] = "NUMA",
+	[MACHINE] = "MACHINE"
+};
 
 /* Internal representation of a node in the hierarchy of elements in the cpu
  * topology of the machine (i.e. numa domain, socket, cpu, core, etc.). */
@@ -84,7 +91,12 @@
 }
 
 /* Create a node and initialize it. This code assumes that child are created
- * before parent nodes. */
+ * before parent nodes.
+ *
+ * all_nodes is laid out such that all of the nodes are: CORES, then the CPUS,
+ * then the SOCKETS, then NUMA, then one for MACHINE.  The nodes at any given
+ * layer are later broken up into chunks of n and assigned to their parents
+ * (down below). */
 static void init_nodes(int type, int num, int nchildren)
 {
 	/* Initialize the lookup table for this node type. */
@@ -123,24 +135,26 @@
 	}
 }
 
+/* Helper: Two cores have the same level id (and thus are at distance k, below)
+ * if their IDs divided by the number of cores per level are the same, due to
+ * how we number our cores. */
+static int get_level_id(int coreid, int level)
+{
+	return coreid / num_descendants[level][CORE];
+}
+
 /* Allocate a table of distances from one core to an other. Cores on the same
  * cpu have a distance of 1; same socket have a distance of 2; same numa -> 3;
  * same machine -> 4; */
 static void init_core_distances(void)
 {
-	core_distance = kzmalloc(num_cores * sizeof(int*), 0);
-	if (core_distance == NULL)
-		panic("Out of memory!\n");
-	for (int i = 0; i < num_cores; i++) {
-		core_distance[i] = kzmalloc(num_cores * sizeof(int), 0);
-		if (core_distance[i] == NULL)
-			panic("Out of memory!\n");
-	}
+	core_distance = kzmalloc(num_cores * sizeof(int*), MEM_WAIT);
+	for (int i = 0; i < num_cores; i++)
+		core_distance[i] = kzmalloc(num_cores * sizeof(int), MEM_WAIT);
 	for (int i = 0; i < num_cores; i++) {
 		for (int j = 0; j < num_cores; j++) {
 			for (int k = CPU; k <= MACHINE; k++) {
-				if (i/num_descendants[k][CORE] ==
-					j/num_descendants[k][CORE]) {
+				if (get_level_id(i, k) == get_level_id(j, k)) {
 					core_distance[i][j] = k;
 					break;
 				}
@@ -157,7 +171,8 @@
 	/* Allocate a flat array of nodes. */
 	total_nodes = num_cores + num_cpus + num_sockets + num_numa + 1;
 	nodes_and_cores = kmalloc(total_nodes * sizeof(struct sched_pnode) +
-	                          num_cores * sizeof(struct sched_pcore), 0);
+	                          num_cores * sizeof(struct sched_pcore),
+	                          MEM_WAIT);
 	all_nodes = nodes_and_cores;
 	all_pcores = nodes_and_cores + total_nodes * sizeof(struct sched_pnode);
 
@@ -209,7 +224,10 @@
 	TAILQ_INIT(&p->ksched_data.crd.prov_not_alloc_me);
 }
 
-/* Returns the sum of the distances from one core to all cores in a list. */
+/* Returns the sum of the distances from one core to all cores in a list.
+ *
+ * This assumes cl is the allocated list, or possibly the idlecores, since it
+ * uses alloc_next. */
 static int cumulative_core_distance(struct sched_pcore *c,
                                     struct sched_pcore_tailq cl)
 {
@@ -378,8 +396,8 @@
 		TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc, prov_next);
 	}
 	/* Actually allocate the core, removing it from the idle core list. */
-	TAILQ_INSERT_TAIL(&p->ksched_data.crd.alloc_me, spc, alloc_next);
 	TAILQ_REMOVE(&idlecores, spc, alloc_next);
+	TAILQ_INSERT_TAIL(&p->ksched_data.crd.alloc_me, spc, alloc_next);
 	incref_nodes(spc->sched_pnode);
 }