Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 80bfb601d828951693b11892603e3161b6736ea0)
+++ kernel/generic/src/sysinfo/stats.c	(revision 3d482e0db605833dc52a95bc096cd2d1afeaec9a)
@@ -85,6 +85,7 @@
 /** Get statistics of all CPUs
  *
- * @param item Sysinfo item (unused).
- * @param size Size of the returned data.
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
  *
  * @return Data containing several stats_cpu_t structures.
@@ -92,10 +93,13 @@
  *         in the context of the sysinfo request.
  */
-static void *get_stats_cpus(struct sysinfo_item *item, size_t *size)
-{
+static void *get_stats_cpus(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(stats_cpu_t) * config.cpu_count;
+	if (dry_run)
+		return NULL;
+	
 	/* Assumption: config.cpu_count is constant */
-	stats_cpu_t *stats_cpus =
-	    (stats_cpu_t *) malloc(sizeof(stats_cpu_t) * config.cpu_count,
-	    FRAME_ATOMIC);
+	stats_cpu_t *stats_cpus = (stats_cpu_t *) malloc(*size, FRAME_ATOMIC);
 	if (stats_cpus == NULL) {
 		*size = 0;
@@ -120,5 +124,4 @@
 	interrupts_restore(ipl);
 	
-	*size = sizeof(stats_cpu_t) * config.cpu_count;
 	return ((void *) stats_cpus);
 }
@@ -172,6 +175,7 @@
 /** Get task IDs
  *
- * @param item Sysinfo item (unused).
- * @param size Size of the returned data.
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
  *
  * @return Data containing task IDs of all tasks.
@@ -179,5 +183,6 @@
  *         in the context of the sysinfo request.
  */
-static void *get_stats_tasks(struct sysinfo_item *item, size_t *size)
+static void *get_stats_tasks(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
 {
 	/* Messing with task structures, avoid deadlock */
@@ -198,6 +203,12 @@
 	}
 	
-	task_id_t *task_ids =
-	    (task_id_t *) malloc(sizeof(task_id_t) * count, FRAME_ATOMIC);
+	*size = sizeof(task_id_t) * count;
+	if (dry_run) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return NULL;
+	}
+	
+	task_id_t *task_ids = (task_id_t *) malloc(*size, FRAME_ATOMIC);
 	if (task_ids == NULL) {
 		/* No free space for allocation */
@@ -216,5 +227,4 @@
 	interrupts_restore(ipl);
 	
-	*size = sizeof(task_id_t) * count;
 	return ((void *) task_ids);
 }
@@ -326,6 +336,7 @@
 /** Get physical memory statistics
  *
- * @param item Sysinfo item (unused).
- * @param size Size of the returned data.
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
  *
  * @return Data containing stats_physmem_t.
@@ -333,8 +344,13 @@
  *         in the context of the sysinfo request.
  */
-static void *get_stats_physmem(struct sysinfo_item *item, size_t *size)
-{
+static void *get_stats_physmem(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(stats_physmem_t);
+	if (dry_run)
+		return NULL;
+	
 	stats_physmem_t *stats_physmem =
-	    (stats_physmem_t *) malloc(sizeof(stats_physmem_t), FRAME_ATOMIC);
+	    (stats_physmem_t *) malloc(*size, FRAME_ATOMIC);
 	if (stats_physmem == NULL) {
 		*size = 0;
@@ -345,5 +361,4 @@
 	    &(stats_physmem->used), &(stats_physmem->free));
 	
-	*size = sizeof(stats_physmem_t);
 	return ((void *) stats_physmem);
 }
@@ -351,6 +366,7 @@
 /** Get system load
  *
- * @param item Sysinfo item (unused).
- * @param size Size of the returned data.
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
  *
  * @return Data several load_t values.
@@ -358,8 +374,12 @@
  *         in the context of the sysinfo request.
  */
-static void *get_stats_load(struct sysinfo_item *item, size_t *size)
-{
-	load_t *stats_load =
-	    (load_t *) malloc(sizeof(load_t) * LOAD_STEPS, FRAME_ATOMIC);
+static void *get_stats_load(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(load_t) * LOAD_STEPS;
+	if (dry_run)
+		return NULL;
+	
+	load_t *stats_load = (load_t *) malloc(*size, FRAME_ATOMIC);
 	if (stats_load == NULL) {
 		*size = 0;
@@ -378,5 +398,4 @@
 	interrupts_restore(ipl);
 	
-	*size = sizeof(load_t) * LOAD_STEPS;
 	return ((void *) stats_load);
 }
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 80bfb601d828951693b11892603e3161b6736ea0)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 3d482e0db605833dc52a95bc096cd2d1afeaec9a)
@@ -496,5 +496,4 @@
 		
 		unative_t val;
-		void *data;
 		size_t size;
 		
@@ -518,10 +517,6 @@
 			break;
 		case SYSINFO_VAL_FUNCTION_DATA:
-			data = cur->val.fn_data(cur, &size);
-			
-			/* N.B.: The generated binary data should be freed */
-			if (data != NULL)
-				free(data);
-			
+			/* N.B.: No data was actually returned (only a dry run) */
+			(void) cur->val.fn_data(cur, &size, true);
 			printf("+ %s (%" PRIs" bytes) [generated]\n", cur->name,
 			    size);
@@ -579,13 +574,16 @@
  * and sysinfo_lock held.
  *
- * @param name Sysinfo path.
- * @param root Root item of the sysinfo (sub)tree.
- *             If it is NULL then consider the global
- *             sysinfo tree.
+ * @param name    Sysinfo path.
+ * @param root    Root item of the sysinfo (sub)tree.
+ *                If it is NULL then consider the global
+ *                sysinfo tree.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
  *
  * @return Item value (constant or generated).
  *
  */
-static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root)
+static sysinfo_return_t sysinfo_get_item(const char *name,
+    sysinfo_item_t **root, bool dry_run)
 {
 	if (root == NULL)
@@ -614,5 +612,6 @@
 			break;
 		case SYSINFO_VAL_FUNCTION_DATA:
-			ret.data.data = item->val.fn_data(item, &ret.data.size);
+			ret.data.data = item->val.fn_data(item, &ret.data.size,
+			    dry_run);
 			break;
 		}
@@ -635,9 +634,12 @@
  * (the last passed character must be null).
  *
- * @param ptr  Sysinfo path in the user address space.
- * @param size Size of the path string.
- *
- */
-static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size)
+ * @param ptr     Sysinfo path in the user address space.
+ * @param size    Size of the path string.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ */
+static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
+    bool dry_run)
 {
 	sysinfo_return_t ret;
@@ -652,5 +654,5 @@
 	if ((copy_from_uspace(path, ptr, size + 1) == 0)
 	    && (path[size] == 0))
-		ret = sysinfo_get_item(path, NULL);
+		ret = sysinfo_get_item(path, NULL, dry_run);
 	
 	free(path);
@@ -677,10 +679,9 @@
 	spinlock_lock(&sysinfo_lock);
 	
-	/* Get the item */
-	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
-	
-	/* N.B.: The generated binary data should be freed */
-	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
-		free(ret.data.data);
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
 	
 	/* Map generated value types to constant types
@@ -720,6 +721,9 @@
 	spinlock_lock(&sysinfo_lock);
 	
-	/* Get the item */
-	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
 	int rc;
 	
@@ -730,8 +734,4 @@
 		rc = EINVAL;
 	
-	/* N.B.: The generated binary data should be freed */
-	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
-		free(ret.data.data);
-	
 	spinlock_unlock(&sysinfo_lock);
 	interrupts_restore(ipl);
@@ -762,6 +762,9 @@
 	spinlock_lock(&sysinfo_lock);
 	
-	/* Get the item */
-	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
 	int rc;
 	
@@ -773,8 +776,4 @@
 		rc = EINVAL;
 	
-	/* N.B.: The generated binary data should be freed */
-	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
-		free(ret.data.data);
-	
 	spinlock_unlock(&sysinfo_lock);
 	interrupts_restore(ipl);
@@ -811,5 +810,5 @@
 	
 	/* Get the item */
-	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, false);
 	int rc;
 	
