aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarch/riscv64/conf/initbin3688 -> 4008 bytes
-rw-r--r--arch/riscv64/conf/init.c30
-rw-r--r--arch/riscv64/conf/initrdbin4096 -> 4608 bytes
-rw-r--r--include/kmi/pmem.h3
-rw-r--r--include/kmi/syscalls.h29
-rw-r--r--src/pmem.c73
-rw-r--r--src/uapi/conf.c22
7 files changed, 138 insertions, 19 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init
index e1a5de7..567ff43 100755
--- a/arch/riscv64/conf/init
+++ b/arch/riscv64/conf/init
Binary files differ
diff --git a/arch/riscv64/conf/init.c b/arch/riscv64/conf/init.c
index 7029dbd..6b1ce46 100644
--- a/arch/riscv64/conf/init.c
+++ b/arch/riscv64/conf/init.c
@@ -220,6 +220,28 @@ static void *sys_req_mem(size_t count)
return (void *)r.ar0;
}
+static size_t get_ram_usage()
+{
+ struct sys_ret r = ecall2(SYS_CONF_GET, CONF_RAM_USAGE);
+ if (r.s) {
+ print_value("getting RAM usage failed with error ", r.s);
+ return 0;
+ }
+
+ return r.ar0;
+}
+
+static size_t get_ram_size()
+{
+ struct sys_ret r = ecall2(SYS_CONF_GET, CONF_RAM_SIZE);
+ if (r.s) {
+ print_value("getting RAM size failed with error ", r.s);
+ return 0;
+ }
+
+ return r.ar0;
+}
+
static void sys_free_mem(void *p)
{
struct sys_ret r = ecall2(SYS_FREE_MEM, (long)p);
@@ -336,12 +358,20 @@ void _start()
print_value("IPC requests per second", n);
puts("Doing memory allocations...\n");
+
+ size_t ram = get_ram_usage();
+ size_t size = get_ram_size();
+ print_value("Memory usage before allocations: ", ram);
+ print_value("Memory size in total: ", size);
for (i = 0; i < 1000000; ++i) {
char *p = sys_req_mem(10);
*p = 'c';
sys_free_mem(p);
}
+ ram = get_ram_usage();
+ print_value("Memory usage after allocations: ", ram);
+
puts("Checking shared memory\n");
struct sys_ret r = sys_ipc_req(1, 1, 0, 0, 0);
rw_buf = (char *)r.ar1;
diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd
index 6c101bc..e331c21 100644
--- a/arch/riscv64/conf/initrd
+++ b/arch/riscv64/conf/initrd
Binary files differ
diff --git a/include/kmi/pmem.h b/include/kmi/pmem.h
index 966f269..0c7a4a2 100644
--- a/include/kmi/pmem.h
+++ b/include/kmi/pmem.h
@@ -39,6 +39,9 @@ void mark_used(enum mm_order order, pm_t addr);
*/
pm_t alloc_page(enum mm_order order);
+/** @return How many bytes of memory are currently in use. */
+size_t query_used();
+
/**
* Populate physical RAM usage map.
* In theory we could easily implement NUMA nodes by just using different orders
diff --git a/include/kmi/syscalls.h b/include/kmi/syscalls.h
index 0801f50..a94cdf1 100644
--- a/include/kmi/syscalls.h
+++ b/include/kmi/syscalls.h
@@ -204,6 +204,35 @@ enum notify_flag {
*/
typedef long sys_arg_t;
+/** IDs for configuration parameters. */
+enum conf_param {
+ /**
+ * How large a regular thread stack is.
+ * \c R/W
+ */
+ CONF_THREAD_STACK,
+
+ /**
+ * How large an RPC stack element is. R/W. Note that this is not how
+ * large the RPC stack is in total, as that is hardcoded by the
+ * architecture, but how much of that stack one RPC call can take.
+ * \c R/W
+ */
+ CONF_RPC_STACK,
+
+ /**
+ * Current RAM usage.
+ * \c R
+ */
+ CONF_RAM_USAGE,
+
+ /**
+ * Total RAM size.
+ * \c R.
+ */
+ CONF_RAM_SIZE,
+};
+
/**
* Return structure of syscall.
* \note Field names are generic, and can be used for whatever,
diff --git a/src/pmem.c b/src/pmem.c
index 91aff5a..cf70c3f 100644
--- a/src/pmem.c
+++ b/src/pmem.c
@@ -208,11 +208,21 @@ static void __get_bit(struct mm_bucket *bucket, pm_t a, size_t *s, size_t *b)
*b = p % bucket->bits;
}
-void free_page(enum mm_order order, pm_t addr)
+/** Counter for how many bytes are currently in use. */
+static size_t used = 0;
+
+/**
+ * Non-usage counting worker for \ref free_page().
+ *
+ * @param order Order of page to free.
+ * @param addr Address of page to free.
+ * @return \ref true if usage count should be updated, \ref false otherwise.
+ */
+static bool __free_page(enum mm_order order, pm_t addr)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
- return;
+ return false;
size_t set = 0, bit = 0;
__get_bit(bucket, addr, &set, &bit);
@@ -227,11 +237,25 @@ void free_page(enum mm_order order, pm_t addr)
__detach_set(bucket, bmap);
if (bmap->size == order_width(order + 1))
- free_page(order + 1, __page_addr(bucket, set, bit));
+ __free_page(order + 1, __page_addr(bucket, set, bit));
}
+
+ return true;
}
-pm_t alloc_page(enum mm_order order)
+void free_page(enum mm_order order, pm_t addr)
+{
+ if (__free_page(order, addr))
+ used -= order_size(order);
+}
+
+/**
+ * Non-usage counting worker for \ref alloc_page().
+ *
+ * @param order Order of page to allocate.
+ * @return Address of allocated page, NULL of no page available.
+ */
+static pm_t __alloc_page(enum mm_order order)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
@@ -239,7 +263,7 @@ pm_t alloc_page(enum mm_order order)
struct mm_bmap *bmap = bucket->head;
if (!bmap) {
- pm_t a = alloc_page(order + 1);
+ pm_t a = __alloc_page(order + 1);
if (!a)
return 0;
@@ -250,7 +274,7 @@ pm_t alloc_page(enum mm_order order)
bmap->used = 0;
bitmap_clear_all(bmap->bits, bmap->size);
__attach_set(bucket, bmap);
- return alloc_page(order);
+ return __alloc_page(order);
}
bmap->used++;
@@ -265,11 +289,27 @@ pm_t alloc_page(enum mm_order order)
return __page_addr(bucket, set, bit);
}
-void mark_used(enum mm_order order, pm_t addr)
+pm_t alloc_page(enum mm_order order)
+{
+ pm_t page = __alloc_page(order);
+ if (page)
+ used += order_size(order);
+
+ return page;
+}
+
+/**
+ * Non-usage counting worker for \ref __mark_used().
+ *
+ * @param order Order of page to mark used.
+ * @param addr Address of page to mark used.
+ * @return \ref true if usage count should be updated, \ref false otherwise.
+ */
+static bool __mark_used(enum mm_order order, pm_t addr)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
- return;
+ return false;
size_t set = 0, bit = 0;
__get_bit(bucket, addr, &set, &bit);
@@ -278,7 +318,7 @@ void mark_used(enum mm_order order, pm_t addr)
if (bmap->used == 0) {
bitmap_clear_all(bmap->bits, bmap->size);
__attach_set(bucket, bmap);
- mark_used(order + 1, addr);
+ __mark_used(order + 1, addr);
}
/* a page already in use can just be left alone. This MIGHT hide some
@@ -286,13 +326,26 @@ void mark_used(enum mm_order order, pm_t addr)
* initialization, but that scenario should probably be handled outside
* of this function anyway. */
if (bitmap_is_set(bmap->bits, bit))
- return;
+ return false;
bmap->used++;
bitmap_set(bmap->bits, bit);
if (bmap->used == bmap->size)
__detach_set(bucket, bmap);
+
+ return true;
+}
+
+void mark_used(enum mm_order order, pm_t addr)
+{
+ if (__mark_used(order, addr))
+ used += order_size(order);
+}
+
+size_t query_used()
+{
+ return used;
}
/**
diff --git a/src/uapi/conf.c b/src/uapi/conf.c
index 685d294..be9abfc 100644
--- a/src/uapi/conf.c
+++ b/src/uapi/conf.c
@@ -21,12 +21,6 @@
size_t __thread_stack_size = SZ_2M;
size_t __rpc_stack_size = SZ_512K;
-/** IDs for configuration parameters. */
-/** @todo should probably be moved somewhere so it can be shared with userspace */
-enum conf_param {
- CONF_THREAD_STACK = 0,
- CONF_RPC_STACK,
-};
/**
* Configuration parameter read syscall handler.
@@ -39,9 +33,8 @@ enum conf_param {
*/
SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
{
- if (!has_cap(t->caps, CAP_CONF))
- return_args1(t, ERR_PERM);
-
+ /* anyone can read any current parameter, I don't think they should be
+ * hidden. */
long val = 0;
switch (param) {
case CONF_THREAD_STACK:
@@ -52,6 +45,14 @@ SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
val = __rpc_stack_size;
break;
+ case CONF_RAM_USAGE:
+ val = query_used();
+ break;
+
+ case CONF_RAM_SIZE:
+ val = get_ram_size();
+ break;
+
default:
return_args1(t, ERR_NF);
}
@@ -87,6 +88,9 @@ SYSCALL_DEFINE2(conf_set)(struct tcb *t, sys_arg_t param, sys_arg_t val)
__rpc_stack_size = size;
break;
+
+ default:
+ return_args1(t, ERR_INVAL);
}
return_args1(t, OK);