Index: generic/include/cpu.h
===================================================================
--- generic/include/cpu.h	(revision e22f561ccf4fd2d78271eadc31f7b700e9256a2a)
+++ generic/include/cpu.h	(revision 248fc1a1ef6f72435b9060ec67dc80bfe4a24fdc)
@@ -51,5 +51,5 @@
 	context_t saved_context;
 
-	volatile count_t nrdy;
+	atomic_t nrdy;
 	runq_t rq[RQ_COUNT];
 	volatile count_t needs_relink;
Index: generic/src/mm/slab.c
===================================================================
--- generic/src/mm/slab.c	(revision e22f561ccf4fd2d78271eadc31f7b700e9256a2a)
+++ generic/src/mm/slab.c	(revision 248fc1a1ef6f72435b9060ec67dc80bfe4a24fdc)
@@ -253,6 +253,6 @@
 		list_remove(&slab->link);
 		list_prepend(&slab->link, &cache->partial_slabs);
-		spinlock_unlock(&cache->slablock);
-	}
+	}
+	spinlock_unlock(&cache->slablock);
 	return 0;
 }
@@ -537,4 +537,5 @@
 	int i;
 	int pages;
+	ipl_t ipl;
 
 	memsetb((__address)cache, sizeof(*cache), 0);
@@ -581,4 +582,6 @@
 		cache->flags |= SLAB_CACHE_SLINSIDE;
 
+	/* Add cache to cache list */
+	ipl = interrupts_disable();
 	spinlock_lock(&slab_cache_lock);
 
@@ -586,4 +589,5 @@
 
 	spinlock_unlock(&slab_cache_lock);
+	interrupts_restore(ipl);
 }
 
@@ -759,5 +763,7 @@
 	slab_cache_t *cache;
 	link_t *cur;
-
+	ipl_t ipl;
+	
+	ipl = interrupts_disable();
 	spinlock_lock(&slab_cache_lock);
 	printf("SLAB name\tOsize\tPages\tObj/pg\tSlabs\tCached\tAllocobjs\tCtl\n");
@@ -772,4 +778,5 @@
 	}
 	spinlock_unlock(&slab_cache_lock);
+	interrupts_restore(ipl);
 }
 
Index: generic/src/proc/scheduler.c
===================================================================
--- generic/src/proc/scheduler.c	(revision e22f561ccf4fd2d78271eadc31f7b700e9256a2a)
+++ generic/src/proc/scheduler.c	(revision 248fc1a1ef6f72435b9060ec67dc80bfe4a24fdc)
@@ -120,18 +120,12 @@
 	thread_t *t;
 	runq_t *r;
-	int i, n;
+	int i;
 
 	ASSERT(CPU != NULL);
 
 loop:
-	interrupts_disable();
-
-	spinlock_lock(&CPU->lock);
-	n = CPU->nrdy;
-	spinlock_unlock(&CPU->lock);
-
 	interrupts_enable();
 	
-	if (n == 0) {
+	if (atomic_get(&CPU->nrdy) == 0) {
 		/*
 		 * For there was nothing to run, the CPU goes to sleep
@@ -146,5 +140,4 @@
 	
 	i = 0;
-retry:
 	for (; i<RQ_COUNT; i++) {
 		r = &CPU->rq[i];
@@ -158,15 +151,5 @@
 		}
 
-		/* avoid deadlock with relink_rq() */
-		if (!spinlock_trylock(&CPU->lock)) {
-			/*
-			 * Unlock r and try again.
-			 */
-			spinlock_unlock(&r->lock);
-			goto retry;
-		}
-		CPU->nrdy--;
-		spinlock_unlock(&CPU->lock);
-
+		atomic_dec(&CPU->nrdy);
 		atomic_dec(&nrdy);
 		r->n--;
@@ -465,5 +448,5 @@
 {
 	thread_t *t;
-	int count, i, j, k = 0;
+	int count, average, i, j, k = 0;
 	ipl_t ipl;
 
@@ -480,13 +463,14 @@
 	 * passes. Each time get the most up to date counts.
 	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&CPU->lock);
-	count = atomic_get(&nrdy) / config.cpu_active;
-	count -= CPU->nrdy;
-	spinlock_unlock(&CPU->lock);
-	interrupts_restore(ipl);
-
-	if (count <= 0)
+	average = atomic_get(&nrdy) / config.cpu_active;
+	count = average - atomic_get(&CPU->nrdy);
+
+	if (count < 0)
 		goto satisfied;
+
+	if (!count) { /* Try to steal threads from CPU's that have more then average count */
+		count = 1;
+		average += 1;
+	}
 
 	/*
@@ -506,5 +490,7 @@
 			 */
 			if (CPU == cpu)
-				continue;				
+				continue;
+			if (atomic_get(&cpu->nrdy) <= average)
+				continue;
 
 restart:		ipl = interrupts_disable();
@@ -545,5 +531,5 @@
 						goto restart;
 					}
-					cpu->nrdy--;
+					atomic_dec(&cpu->nrdy);
 					spinlock_unlock(&cpu->lock);
 
@@ -567,5 +553,5 @@
 				spinlock_lock(&t->lock);
 				#ifdef KCPULB_VERBOSE
-				printf("kcpulb%d: TID %d -> cpu%d, nrdy=%d, avg=%d\n", CPU->id, t->tid, CPU->id, CPU->nrdy, atomic_get(&nrdy) / config.cpu_active);
+				printf("kcpulb%d: TID %d -> cpu%d, nrdy=%d, avg=%d\n", CPU->id, t->tid, CPU->id, atomic_get(&CPU->nrdy), atomic_get(&nrdy) / config.cpu_active);
 				#endif
 				t->flags |= X_STOLEN;
@@ -590,5 +576,5 @@
 	}
 
-	if (CPU->nrdy) {
+	if (atomic_get(&CPU->nrdy)) {
 		/*
 		 * Be a little bit light-weight and let migrated threads run.
@@ -630,5 +616,5 @@
 		spinlock_lock(&cpus[cpu].lock);
 		printf("cpu%d: nrdy: %d needs_relink: %d\n",
-		       cpus[cpu].id, cpus[cpu].nrdy, cpus[cpu].needs_relink);
+		       cpus[cpu].id, atomic_get(&cpus[cpu].nrdy), cpus[cpu].needs_relink);
 		
 		for (i=0; i<RQ_COUNT; i++) {
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision e22f561ccf4fd2d78271eadc31f7b700e9256a2a)
+++ generic/src/proc/thread.c	(revision 248fc1a1ef6f72435b9060ec67dc80bfe4a24fdc)
@@ -138,13 +138,5 @@
 	atomic_inc(&nrdy);
 	avg = atomic_get(&nrdy) / config.cpu_active;
-
-	spinlock_lock(&cpu->lock);
-	if ((++cpu->nrdy) > avg) {
-		/*
-		 * If there are idle halted CPU's, this will wake them up.
-		 */
-		ipi_broadcast(VECTOR_WAKEUP_IPI);
-	}	
-	spinlock_unlock(&cpu->lock);
+	atomic_inc(&cpu->nrdy);
 
 	interrupts_restore(ipl);
