diff options
Diffstat (limited to 'kern/kmem.c')
-rw-r--r-- | kern/kmem.c | 140 |
1 files changed, 107 insertions, 33 deletions
diff --git a/kern/kmem.c b/kern/kmem.c index 5cce5589..d98be0d6 100644 --- a/kern/kmem.c +++ b/kern/kmem.c @@ -41,15 +41,15 @@ * TODO Rework the CPU pool layer to use the SLQB algorithm by Nick Piggin. */ +#include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <string.h> -#include <kern/assert.h> #include <kern/init.h> -#include <kern/limits.h> #include <kern/list.h> #include <kern/log2.h> #include <kern/kmem.h> @@ -57,9 +57,10 @@ #include <kern/macros.h> #include <kern/mutex.h> #include <kern/panic.h> -#include <kern/param.h> +#include <kern/shell.h> #include <kern/thread.h> #include <machine/cpu.h> +#include <machine/page.h> #include <machine/pmap.h> #include <vm/vm_kmem.h> #include <vm/vm_page.h> @@ -1092,41 +1093,28 @@ kmem_cache_info(struct kmem_cache *cache) { char flags_str[64]; - if (cache == NULL) { - mutex_lock(&kmem_cache_list_lock); - - list_for_each_entry(&kmem_cache_list, cache, node) { - kmem_cache_info(cache); - } - - mutex_unlock(&kmem_cache_list_lock); - - return; - } - snprintf(flags_str, sizeof(flags_str), "%s%s", (cache->flags & KMEM_CF_SLAB_EXTERNAL) ? " SLAB_EXTERNAL" : "", (cache->flags & KMEM_CF_VERIFY) ? " VERIFY" : ""); mutex_lock(&cache->lock); - printf("kmem: name: %s\n" - "kmem: flags: 0x%x%s\n" - "kmem: obj_size: %zu\n" - "kmem: align: %zu\n" - "kmem: buf_size: %zu\n" - "kmem: bufctl_dist: %zu\n" - "kmem: slab_size: %zu\n" - "kmem: color_max: %zu\n" + printf("kmem: flags: 0x%x%s\n" + "kmem: obj_size: %zu\n" + "kmem: align: %zu\n" + "kmem: buf_size: %zu\n" + "kmem: bufctl_dist: %zu\n" + "kmem: slab_size: %zu\n" + "kmem: color_max: %zu\n" "kmem: bufs_per_slab: %lu\n" - "kmem: nr_objs: %lu\n" - "kmem: nr_bufs: %lu\n" - "kmem: nr_slabs: %lu\n" + "kmem: nr_objs: %lu\n" + "kmem: nr_bufs: %lu\n" + "kmem: nr_slabs: %lu\n" "kmem: nr_free_slabs: %lu\n" - "kmem: buftag_dist: %zu\n" - "kmem: redzone_pad: %zu\n" - "kmem: cpu_pool_size: %d\n", cache->name, cache->flags, flags_str, - cache->obj_size, cache->align, cache->buf_size, cache->bufctl_dist, + "kmem: buftag_dist: %zu\n" + "kmem: redzone_pad: %zu\n" + "kmem: cpu_pool_size: %d\n", cache->flags, flags_str, cache->obj_size, + cache->align, cache->buf_size, cache->bufctl_dist, cache->slab_size, cache->color_max, cache->bufs_per_slab, cache->nr_objs, cache->nr_bufs, cache->nr_slabs, cache->nr_free_slabs, cache->buftag_dist, cache->redzone_pad, @@ -1135,8 +1123,71 @@ kmem_cache_info(struct kmem_cache *cache) mutex_unlock(&cache->lock); } -void __init -kmem_setup(void) +#ifdef X15_SHELL + +static struct kmem_cache * +kmem_lookup_cache(const char *name) +{ + struct kmem_cache *cache; + + mutex_lock(&kmem_cache_list_lock); + + list_for_each_entry(&kmem_cache_list, cache, node) { + if (strcmp(cache->name, name) == 0) { + goto out; + } + } + + cache = NULL; + +out: + mutex_unlock(&kmem_cache_list_lock); + + return cache; +} + +static void +kmem_shell_info(int argc, char **argv) +{ + struct kmem_cache *cache; + + if (argc < 2) { + kmem_info(); + } else { + cache = kmem_lookup_cache(argv[1]); + + if (cache == NULL) { + printf("kmem: info: invalid argument\n"); + return; + } + + kmem_cache_info(cache); + } +} + +static struct shell_cmd kmem_shell_cmds[] = { + SHELL_CMD_INITIALIZER("kmem_info", kmem_shell_info, + "kmem_info [<cache_name>]", + "display information about kernel memory and caches"), +}; + +static int __init +kmem_setup_shell(void) +{ + SHELL_REGISTER_CMDS(kmem_shell_cmds); + return 0; +} + +INIT_OP_DEFINE(kmem_setup_shell, + INIT_OP_DEP(kmem_setup, true), + INIT_OP_DEP(printf_setup, true), + INIT_OP_DEP(shell_setup, true), + INIT_OP_DEP(thread_setup, true)); + +#endif /* X15_SHELL */ + +static int __init +kmem_bootstrap(void) { struct kmem_cpu_pool_type *cpu_pool_type; char name[KMEM_NAME_SIZE]; @@ -1170,8 +1221,24 @@ kmem_setup(void) kmem_cache_init(&kmem_caches[i], name, size, 0, NULL, 0); size <<= 1; } + + return 0; +} + +INIT_OP_DEFINE(kmem_bootstrap, + INIT_OP_DEP(thread_bootstrap, true), + INIT_OP_DEP(vm_page_setup, true)); + +static int __init +kmem_setup(void) +{ + return 0; } +INIT_OP_DEFINE(kmem_setup, + INIT_OP_DEP(kmem_bootstrap, true), + INIT_OP_DEP(vm_kmem_setup, true)); + static inline size_t kmem_get_index(unsigned long size) { @@ -1282,8 +1349,11 @@ kmem_free(void *ptr, size_t size) void kmem_info(void) { + size_t mem_usage, mem_reclaimable, total, total_reclaimable; struct kmem_cache *cache; - size_t mem_usage, mem_reclaimable; + + total = 0; + total_reclaimable = 0; printf("kmem: cache obj slab bufs objs bufs " " total reclaimable\n" @@ -1297,6 +1367,8 @@ kmem_info(void) mem_usage = (cache->nr_slabs * cache->slab_size) >> 10; mem_reclaimable = (cache->nr_free_slabs * cache->slab_size) >> 10; + total += mem_usage; + total_reclaimable += mem_reclaimable; printf("kmem: %-19s %6zu %3zuk %4lu %6lu %6lu %7zuk %10zuk\n", cache->name, cache->obj_size, cache->slab_size >> 10, @@ -1307,4 +1379,6 @@ kmem_info(void) } mutex_unlock(&kmem_cache_list_lock); + + printf("total: %zuk reclaimable: %zuk\n", total, total_reclaimable); } |