From 3528f88fc36df6964c0efed784ae223cfe93544e Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 6 Jul 2024 22:08:50 +0300 Subject: add RAM usage counting + Slightly more overhead but will help track down possible memory leaks in the future. Could also add in a flag for turning off/on but I don't think the difference in performance is that significant. --- src/pmem.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/uapi/conf.c | 22 ++++++++++------- 2 files changed, 76 insertions(+), 19 deletions(-) (limited to 'src') 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); -- cgit v1.3