Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 07d4271f2d0447f764d751ed8f95104f720791d2)
+++ kernel/generic/src/sysinfo/stats.c	(revision fe7bcf13e7bb4dccf0289632006b2e240a751683)
@@ -119,10 +119,13 @@
 	size_t i;
 	for (i = 0; i < config.cpu_count; i++) {
+		irq_spinlock_lock(&cpus[i].lock, true);
+
 		stats_cpus[i].id = cpus[i].id;
 		stats_cpus[i].active = cpus[i].active;
 		stats_cpus[i].frequency_mhz = cpus[i].frequency_mhz;
-
-		stats_cpus[i].busy_cycles = atomic_time_read(&cpus[i].busy_cycles);
-		stats_cpus[i].idle_cycles = atomic_time_read(&cpus[i].idle_cycles);
+		stats_cpus[i].busy_cycles = cpus[i].busy_cycles;
+		stats_cpus[i].idle_cycles = cpus[i].idle_cycles;
+
+		irq_spinlock_unlock(&cpus[i].lock, true);
 	}
 
@@ -221,5 +224,5 @@
 	stats_task->virtmem = get_task_virtmem(task->as);
 	stats_task->resmem = get_task_resmem(task->as);
-	stats_task->threads = atomic_load(&task->lifecount);
+	stats_task->threads = atomic_load(&task->refcount);
 	task_get_accounting(task, &(stats_task->ucycles),
 	    &(stats_task->kcycles));
@@ -299,17 +302,16 @@
 {
 	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&thread->lock));
 
 	stats_thread->thread_id = thread->tid;
 	stats_thread->task_id = thread->task->taskid;
-	stats_thread->state = atomic_get_unordered(&thread->state);
-	stats_thread->priority = atomic_get_unordered(&thread->priority);
-	stats_thread->ucycles = atomic_time_read(&thread->ucycles);
-	stats_thread->kcycles = atomic_time_read(&thread->kcycles);
-
-	cpu_t *cpu = atomic_get_unordered(&thread->cpu);
-
-	if (cpu != NULL) {
+	stats_thread->state = thread->state;
+	stats_thread->priority = thread->priority;
+	stats_thread->ucycles = thread->ucycles;
+	stats_thread->kcycles = thread->kcycles;
+
+	if (thread->cpu != NULL) {
 		stats_thread->on_cpu = true;
-		stats_thread->cpu = cpu->id;
+		stats_thread->cpu = thread->cpu->id;
 	} else
 		stats_thread->on_cpu = false;
@@ -330,5 +332,5 @@
     bool dry_run, void *data)
 {
-	/* Messing with threads structures */
+	/* Messing with threads structures, avoid deadlock */
 	irq_spinlock_lock(&threads_lock, true);
 
@@ -362,7 +364,12 @@
 	thread_t *thread = thread_first();
 	while (thread != NULL) {
+		/* Interrupts are already disabled */
+		irq_spinlock_lock(&thread->lock, false);
+
 		/* Record the statistics and increment the index */
 		produce_stats_thread(thread, &stats_threads[i]);
 		i++;
+
+		irq_spinlock_unlock(&thread->lock, false);
 
 		thread = thread_next(thread);
@@ -511,7 +518,6 @@
 {
 	/* Initially no return value */
-	sysinfo_return_t ret = {
-		.tag = SYSINFO_VAL_UNDEFINED,
-	};
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
 
 	/* Parse the task ID */
@@ -520,7 +526,13 @@
 		return ret;
 
+	/* Messing with task structures, avoid deadlock */
+	irq_spinlock_lock(&tasks_lock, true);
+
 	task_t *task = task_find_by_id(task_id);
-	if (!task)
+	if (task == NULL) {
+		/* No task with this ID */
+		irq_spinlock_unlock(&tasks_lock, true);
 		return ret;
+	}
 
 	if (dry_run) {
@@ -528,21 +540,28 @@
 		ret.data.data = NULL;
 		ret.data.size = sizeof(stats_task_t);
+
+		irq_spinlock_unlock(&tasks_lock, true);
 	} else {
 		/* Allocate stats_task_t structure */
-		stats_task_t *stats_task = malloc(sizeof(stats_task_t));
-
-		if (stats_task != NULL) {
-			/* Correct return value */
-			ret.tag = SYSINFO_VAL_FUNCTION_DATA;
-			ret.data.data = stats_task;
-			ret.data.size = sizeof(stats_task_t);
-
-			irq_spinlock_lock(&task->lock, true);
-			produce_stats_task(task, stats_task);
-			irq_spinlock_unlock(&task->lock, true);
+		stats_task_t *stats_task =
+		    (stats_task_t *) malloc(sizeof(stats_task_t));
+		if (stats_task == NULL) {
+			irq_spinlock_unlock(&tasks_lock, true);
+			return ret;
 		}
-	}
-
-	task_release(task);
+
+		/* Correct return value */
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = (void *) stats_task;
+		ret.data.size = sizeof(stats_task_t);
+
+		/* Hand-over-hand locking */
+		irq_spinlock_exchange(&tasks_lock, &task->lock);
+
+		produce_stats_task(task, stats_task);
+
+		irq_spinlock_unlock(&task->lock, true);
+	}
+
 	return ret;
 }
@@ -578,5 +597,5 @@
 		return ret;
 
-	/* Messing with threads structures */
+	/* Messing with threads structures, avoid deadlock */
 	irq_spinlock_lock(&threads_lock, true);
 
@@ -608,7 +627,10 @@
 		ret.data.size = sizeof(stats_thread_t);
 
+		/* Hand-over-hand locking */
+		irq_spinlock_exchange(&threads_lock, &thread->lock);
+
 		produce_stats_thread(thread, stats_thread);
 
-		irq_spinlock_unlock(&threads_lock, true);
+		irq_spinlock_unlock(&thread->lock, true);
 	}
 
@@ -825,4 +847,6 @@
 void kload(void *arg)
 {
+	thread_detach(THREAD);
+
 	while (true) {
 		size_t ready = atomic_load(&nrdy);
