Index: kernel/generic/include/sysinfo/abi.h
===================================================================
--- kernel/generic/include/sysinfo/abi.h	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ kernel/generic/include/sysinfo/abi.h	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -104,4 +104,5 @@
 	char name[TASK_NAME_BUFLEN];  /**< Task name (in kernel) */
 	size_t virtmem;               /**< Size of VAS (bytes) */
+	size_t resmem;                /**< Size of resident (used) memory (bytes) */
 	size_t threads;               /**< Number of threads */
 	uint64_t ucycles;             /**< Number of CPU cycles in user space */
Index: kernel/generic/include/sysinfo/sysinfo.h
===================================================================
--- kernel/generic/include/sysinfo/sysinfo.h	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ kernel/generic/include/sysinfo/sysinfo.h	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -148,5 +148,5 @@
 extern sysarg_t sys_sysinfo_get_value(void *, size_t, void *);
 extern sysarg_t sys_sysinfo_get_data_size(void *, size_t, void *);
-extern sysarg_t sys_sysinfo_get_data(void *, size_t, void *, size_t);
+extern sysarg_t sys_sysinfo_get_data(void *, size_t, void *, size_t, size_t *);
 
 #endif
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ kernel/generic/src/mm/backend_phys.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -81,6 +81,7 @@
 	page_mapping_insert(AS, addr, base + (addr - area->base),
 	    as_area_get_flags(area));
-        if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
-                panic("Cannot insert used space.");
+	
+	if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
+		panic("Cannot insert used space.");
 
 	return AS_PF_OK;
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ kernel/generic/src/sysinfo/stats.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -170,5 +170,5 @@
 	 * Note that it may be infinitely better to let the address space
 	 * management code compute these statistics as it proceeds instead of
-	 * having them calculated here over and over again here.
+	 * having them calculated over and over again here.
 	 */
 
@@ -199,4 +199,64 @@
 }
 
+/** Get the resident (used) size of a virtual address space
+ *
+ * @param as Address space.
+ *
+ * @return Size of the resident (used) virtual address space (bytes).
+ *
+ */
+static size_t get_task_resmem(as_t *as)
+{
+	size_t result = 0;
+	
+	/*
+	 * We are holding some spinlocks here and therefore are not allowed to
+	 * block. Only attempt to lock the address space and address space area
+	 * mutexes conditionally. If it is not possible to lock either object,
+	 * allow the statistics to be inexact by skipping the respective object.
+	 *
+	 * Note that it may be infinitely better to let the address space
+	 * management code compute these statistics as it proceeds instead of
+	 * having them calculated over and over again here.
+	 */
+	
+	if (SYNCH_FAILED(mutex_trylock(&as->lock)))
+		return result * PAGE_SIZE;
+	
+	/* Walk the B+ tree of AS areas */
+	link_t *cur;
+	for (cur = as->as_area_btree.leaf_head.next;
+	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
+		
+		unsigned int i;
+		for (i = 0; i < node->keys; i++) {
+			as_area_t *area = node->value[i];
+			
+			if (SYNCH_FAILED(mutex_trylock(&area->lock)))
+				continue;
+			
+			/* Walk the B+ tree of resident pages */
+			link_t *rcur;
+			for (rcur = area->used_space.leaf_head.next;
+			    rcur != &area->used_space.leaf_head; rcur = rcur->next) {
+				btree_node_t *rnode =
+				    list_get_instance(rcur, btree_node_t, leaf_link);
+				
+				unsigned int j;
+				for (j = 0; j < rnode->keys; j++)
+					result += (size_t) rnode->value[i];
+			}
+			
+			mutex_unlock(&area->lock);
+		}
+	}
+	
+	mutex_unlock(&as->lock);
+	
+	return result * PAGE_SIZE;
+}
+
 /* Produce task statistics
  *
@@ -215,4 +275,5 @@
 	str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
 	stats_task->virtmem = get_task_virtmem(task->as);
+	stats_task->resmem = get_task_resmem(task->as);
 	stats_task->threads = atomic_get(&task->refcount);
 	task_get_accounting(task, &(stats_task->ucycles),
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -40,4 +40,5 @@
 #include <arch/asm.h>
 #include <errno.h>
+#include <macros.h>
 
 /** Maximal sysinfo path length */
@@ -761,7 +762,13 @@
  * character must be null).
  *
- * The user space buffer must be sized exactly according
- * to the size of the binary data, otherwise the request
- * fails.
+ * If the user space buffer size does not equal
+ * the actual size of the returned data, the data
+ * is truncated. Whether this is actually a fatal
+ * error or the data can be still interpreted as valid
+ * depends on the nature of the data and has to be
+ * decided by the user space.
+ *
+ * The actual size of data returned is stored to
+ * size_ptr.
  *
  * @param path_ptr    Sysinfo path in the user address space.
@@ -770,4 +777,6 @@
  *                    to store the binary data.
  * @param buffer_size User space buffer size.
+ * @param size_ptr    User space pointer where to store the
+ *                    binary data size.
  *
  * @return Error code (EOK in case of no error).
@@ -775,19 +784,19 @@
  */
 sysarg_t sys_sysinfo_get_data(void *path_ptr, size_t path_size,
-    void *buffer_ptr, size_t buffer_size)
+    void *buffer_ptr, size_t buffer_size, size_t *size_ptr)
 {
 	int rc;
 	
 	/* Get the item */
-	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, false);
-
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size,
+	    false);
+	
 	/* Only constant or generated binary data is considered */
-	if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
-		/* Check destination buffer size */
-		if (ret.data.size == buffer_size)
-			rc = copy_to_uspace(buffer_ptr, ret.data.data,
-			    ret.data.size);
-		else
-			rc = ENOMEM;
+	if ((ret.tag == SYSINFO_VAL_DATA) ||
+	    (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
+		size_t size = min(ret.data.size, buffer_size);
+		rc = copy_to_uspace(buffer_ptr, ret.data.data, size);
+		if (rc == EOK)
+			rc = copy_to_uspace(size_ptr, &size, sizeof(size));
 	} else
 		rc = EINVAL;
Index: uspace/app/tasks/tasks.c
===================================================================
--- uspace/app/tasks/tasks.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/app/tasks/tasks.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -66,5 +66,5 @@
 	}
 	
-	printf("      ID  Threads      Mem       uCycles       kCycles   Name\n");
+	printf(" Task ID  Threads      Mem       uCycles       kCycles   Name\n");
 	
 	size_t i;
@@ -96,5 +96,5 @@
 	}
 	
-	printf("    ID    State  CPU   Prio    [k]uCycles    [k]kcycles   Cycle fault\n");
+	printf(" ThrID    State  CPU   Prio    [k]uCycles    [k]kcycles   Cycle fault\n");
 	size_t i;
 	for (i = 0; i < count; i++) {
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/app/top/screen.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -274,6 +274,6 @@
 {
 	screen_style_inverted();
-	printf("[taskid] [threads] [virtual] [%%virt] [%%user]"
-	    " [%%kernel] [name");
+	printf("[taskid] [threads] [resident] [%%resi] [virtual] [%%virt]"
+	    " [%%user] [%%kern] [name");
 	screen_newline();
 	screen_style_normal();
@@ -295,14 +295,20 @@
 		perc_task_t *perc = data->tasks_perc + data->tasks_map[i];
 		
+		uint64_t resmem;
+		char resmem_suffix;
+		order_suffix(task->resmem, &resmem, &resmem_suffix);
+		
 		uint64_t virtmem;
 		char virtmem_suffix;
 		order_suffix(task->virtmem, &virtmem, &virtmem_suffix);
 		
-		printf("%-8" PRIu64 " %9zu %8" PRIu64 "%c ", task->task_id,
-		    task->threads, virtmem, virtmem_suffix);
+		printf("%-8" PRIu64 " %9zu %9" PRIu64 "%c ",
+		    task->task_id, task->threads, resmem, resmem_suffix);
+		print_percent(perc->resmem, 2);
+		printf(" %8" PRIu64 "%c ", virtmem, virtmem_suffix);
 		print_percent(perc->virtmem, 2);
 		puts(" ");
 		print_percent(perc->ucycles, 2);
-		puts("   ");
+		puts(" ");
 		print_percent(perc->kcycles, 2);
 		puts(" ");
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/app/top/top.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -195,4 +195,5 @@
 	
 	uint64_t virtmem_total = 0;
+	uint64_t resmem_total = 0;
 	uint64_t ucycles_total = 0;
 	uint64_t kcycles_total = 0;
@@ -223,4 +224,5 @@
 		
 		virtmem_total += new_data->tasks[i].virtmem;
+		resmem_total += new_data->tasks[i].resmem;
 		ucycles_total += new_data->ucycles_diff[i];
 		kcycles_total += new_data->kcycles_diff[i];
@@ -232,4 +234,6 @@
 		FRACTION_TO_FLOAT(new_data->tasks_perc[i].virtmem,
 		    new_data->tasks[i].virtmem * 100, virtmem_total);
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].resmem,
+		    new_data->tasks[i].resmem * 100, resmem_total);
 		FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
 		    new_data->ucycles_diff[i] * 100, ucycles_total);
Index: uspace/app/top/top.h
===================================================================
--- uspace/app/top/top.h	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/app/top/top.h	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -77,4 +77,5 @@
 typedef struct {
 	fixed_float virtmem;
+	fixed_float resmem;
 	fixed_float ucycles;
 	fixed_float kcycles;
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/app/trace/syscalls.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -77,5 +77,5 @@
     [SYS_SYSINFO_GET_VALUE] = { "sysinfo_get_value",		3,	V_ERRNO },
     [SYS_SYSINFO_GET_DATA_SIZE] = { "sysinfo_get_data_size",	3,	V_ERRNO },
-    [SYS_SYSINFO_GET_DATA] = { "sysinfo_get_data",		4,	V_ERRNO },
+    [SYS_SYSINFO_GET_DATA] = { "sysinfo_get_data",		5,	V_ERRNO },
 
     [SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0,	V_ERRNO },
Index: uspace/lib/c/generic/stats.c
===================================================================
--- uspace/lib/c/generic/stats.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/lib/c/generic/stats.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -36,8 +36,8 @@
 #include <stats.h>
 #include <sysinfo.h>
-#include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 #include <inttypes.h>
+#include <malloc.h>
 
 #define SYSINFO_STATS_MAX_PATH  64
@@ -71,5 +71,10 @@
 	    (stats_cpu_t *) sysinfo_get_data("system.cpus", &size);
 	
-	assert((size % sizeof(stats_cpu_t)) == 0);
+	if ((size % sizeof(stats_cpu_t)) != 0) {
+		if (stats_cpus != NULL)
+			free(stats_cpus);
+		*count = 0;
+		return NULL;
+	}
 	
 	*count = size / sizeof(stats_cpu_t);
@@ -91,5 +96,9 @@
 	    (stats_physmem_t *) sysinfo_get_data("system.physmem", &size);
 	
-	assert((size == sizeof(stats_physmem_t)) || (size == 0));
+	if (size != sizeof(stats_physmem_t)) {
+		if (stats_physmem != NULL)
+			free(stats_physmem);
+		return NULL;
+	}
 	
 	return stats_physmem;
@@ -111,5 +120,10 @@
 	    (stats_task_t *) sysinfo_get_data("system.tasks", &size);
 	
-	assert((size % sizeof(stats_task_t)) == 0);
+	if ((size % sizeof(stats_task_t)) != 0) {
+		if (stats_tasks != NULL)
+			free(stats_tasks);
+		*count = 0;
+		return NULL;
+	}
 	
 	*count = size / sizeof(stats_task_t);
@@ -135,5 +149,9 @@
 	    (stats_task_t *) sysinfo_get_data(name, &size);
 	
-	assert((size == sizeof(stats_task_t)) || (size == 0));
+	if (size != sizeof(stats_task_t)) {
+		if (stats_task != NULL)
+			free(stats_task);
+		return NULL;
+	}
 	
 	return stats_task;
@@ -155,5 +173,10 @@
 	    (stats_thread_t *) sysinfo_get_data("system.threads", &size);
 	
-	assert((size % sizeof(stats_thread_t)) == 0);
+	if ((size % sizeof(stats_thread_t)) != 0) {
+		if (stats_threads != NULL)
+			free(stats_threads);
+		*count = 0;
+		return NULL;
+	}
 	
 	*count = size / sizeof(stats_thread_t);
@@ -179,5 +202,9 @@
 	    (stats_thread_t *) sysinfo_get_data(name, &size);
 	
-	assert((size == sizeof(stats_thread_t)) || (size == 0));
+	if (size != sizeof(stats_thread_t)) {
+		if (stats_thread != NULL)
+			free(stats_thread);
+		return NULL;
+	}
 	
 	return stats_thread;
@@ -199,5 +226,10 @@
 	    (stats_exc_t *) sysinfo_get_data("system.exceptions", &size);
 	
-	assert((size % sizeof(stats_exc_t)) == 0);
+	if ((size % sizeof(stats_exc_t)) != 0) {
+		if (stats_exceptions != NULL)
+			free(stats_exceptions);
+		*count = 0;
+		return NULL;
+	}
 	
 	*count = size / sizeof(stats_exc_t);
@@ -217,5 +249,5 @@
 {
 	char name[SYSINFO_STATS_MAX_PATH];
-	snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptionss.%u", excn);
+	snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptions.%u", excn);
 	
 	size_t size = 0;
@@ -223,5 +255,9 @@
 	    (stats_exc_t *) sysinfo_get_data(name, &size);
 	
-	assert((size == sizeof(stats_exc_t)) || (size == 0));
+	if (size != sizeof(stats_exc_t)) {
+		if (stats_exception != NULL)
+			free(stats_exception);
+		return NULL;
+	}
 	
 	return stats_exception;
@@ -243,5 +279,10 @@
 	    (load_t *) sysinfo_get_data("system.load", &size);
 	
-	assert((size % sizeof(load_t)) == 0);
+	if ((size % sizeof(load_t)) != 0) {
+		if (load != NULL)
+			free(load);
+		*count = 0;
+		return NULL;
+	}
 	
 	*count = size / sizeof(load_t);
Index: uspace/lib/c/generic/sysinfo.c
===================================================================
--- uspace/lib/c/generic/sysinfo.c	(revision 192a0063ea6b8b9ff643fa0049ca8886e11e8a37)
+++ uspace/lib/c/generic/sysinfo.c	(revision 6265a2b2cf4693bc7c801083a14366ba3ee2fb15)
@@ -96,42 +96,38 @@
 void *sysinfo_get_data(const char *path, size_t *size)
 {
-	/* The binary data size might change during time.
-	   Unfortunatelly we cannot allocate the buffer
-	   and transfer the data as a single atomic operation.
+	/*
+	 * The binary data size might change during time.
+	 * Unfortunatelly we cannot allocate the buffer
+	 * and transfer the data as a single atomic operation.
+	 */
 	
-	   Let's hope that the number of iterations is bounded
-	   in common cases. */
-	
-	void *data = NULL;
-	
-	while (true) {
-		/* Get the binary data size */
-		int ret = sysinfo_get_data_size(path, size);
-		if ((ret != EOK) || (size == 0)) {
-			/* Not a binary data item
-			   or an empty item */
-			break;
-		}
-		
-		data = realloc(data, *size);
-		if (data == NULL)
-			break;
-		
-		/* Get the data */
-		ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
-		    (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size);
-		if (ret == EOK)
-			return data;
-		
-		if (ret != ENOMEM) {
-			/* The failure to get the data was not caused
-			   by wrong buffer size */
-			break;
-		}
+	/* Get the binary data size */
+	int ret = sysinfo_get_data_size(path, size);
+	if ((ret != EOK) || (size == 0)) {
+		/*
+		 * Not a binary data item
+		 * or an empty item.
+		 */
+		*size = 0;
+		return NULL;
 	}
 	
-	if (data != NULL)
-		free(data);
+	void *data = malloc(*size);
+	if (data == NULL) {
+		*size = 0;
+		return NULL;
+	}
 	
+	/* Get the data */
+	size_t sz;
+	ret = __SYSCALL5(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
+	    (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size,
+	    (sysarg_t) &sz);
+	if (ret == EOK) {
+		*size = sz;
+		return data;
+	}
+	
+	free(data);
 	*size = 0;
 	return NULL;
