diff --git a/07-MemoryManagement/kernel_space/Makefile b/07-MemoryManagement/kernel_space/Makefile new file mode 100644 index 0000000..b4fe5b7 --- /dev/null +++ b/07-MemoryManagement/kernel_space/Makefile @@ -0,0 +1,9 @@ + +obj-m += memory_manag_kernel.o + +BUILD_KERNEL?=/lib/modules/$(shell uname -r)/build/ + +all: + make -C $(BUILD_KERNEL) M=$(PWD) modules +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean diff --git a/07-MemoryManagement/kernel_space/memory_manag_kernel.c b/07-MemoryManagement/kernel_space/memory_manag_kernel.c new file mode 100644 index 0000000..e606949 --- /dev/null +++ b/07-MemoryManagement/kernel_space/memory_manag_kernel.c @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: GPL +#include // Macros used to mark up functions __init __exit +#include // Core header for loading LKMs into the kernel +#include // Contains types, macros, functions for the kernel +#include +#include +#include +#include +#include +#include +#include + +typedef void *(*memory_allocate) (ssize_t size, void *context); +typedef void (*memory_free) (const void *mem, void *context); +typedef size_t (*memory_incr_size)(const size_t cur_size); + +struct cnf_mem_allocate { + memory_allocate mem_allocate; + void *cnt; +}; + +struct cnf_mem_free { + memory_free mem_free; + void *cnt; +}; + +struct mem_config { + struct cnf_mem_allocate cnf_allocate; + struct cnf_mem_free cnf_free; + memory_incr_size incr_size; + size_t start_size; + size_t max_size_mem; +}; + +struct mem_description { + struct mem_config config; + char *buf; + size_t size_buf; +}; + +static long long get_timeout(struct timespec start, struct timespec end) +{ + struct timespec sub = timespec_sub(end, start); + + return timespec_to_ns(&sub); +} + +static void mem_test(struct mem_description *descr) +{ + struct timespec ts_start; + struct timespec ts_end; + + long long time_spent_allocate; + long long time_spent_free; + + size_t size = descr->config.start_size; + int32_t numb_sample = 0; + void *res_allocate; + + sprintf(descr->buf + strlen(descr->buf), + "number addr size alloc(ns) free(ns)\n"); + + while (size < descr->config.max_size_mem) { + numb_sample++; + + getnstimeofday(&ts_start); + res_allocate = descr->config.cnf_allocate.mem_allocate(size, + descr->config.cnf_allocate.cnt); + getnstimeofday(&ts_end); + time_spent_allocate = get_timeout(ts_start, ts_end); + + + if (res_allocate != NULL) { + getnstimeofday(&ts_start); + descr->config.cnf_free.mem_free(res_allocate, + descr->config.cnf_free.cnt); + getnstimeofday(&ts_end); + time_spent_free = get_timeout(ts_start, ts_end); + } else { + time_spent_free = 0; + } + + sprintf(descr->buf + strlen(descr->buf), + " %4u %8p %-10u%10llu %10llu\n", + numb_sample, res_allocate, size, + time_spent_allocate, time_spent_free); + size = descr->config.incr_size(size); + } +} + +static size_t incr_shift_bit(size_t cur_size) +{ + return (cur_size << 1); +} + +struct cnt_kmalloc { + gfp_t flags; +}; + +static void *mem_kmalloc(ssize_t size, struct cnt_kmalloc *cnt) +{ + return kmalloc(size, cnt->flags); +} + +static void mem_kfree(const void *mem, void *context) +{ + kfree(mem); +} + +static ssize_t test_kmalloc_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + + struct mem_description descr; + struct cnt_kmalloc cnt; + + cnt.flags = GFP_KERNEL; + + descr.config.cnf_allocate.mem_allocate = (memory_allocate)mem_kmalloc; + descr.config.cnf_allocate.cnt = (void *)&cnt; + + descr.config.cnf_free.mem_free = mem_kfree; + descr.config.cnf_free.cnt = NULL; + + descr.config.incr_size = incr_shift_bit; + + descr.buf = buf; + descr.config.max_size_mem = 0x9000000; + descr.config.start_size = 1; + + sprintf(descr.buf + strlen(descr.buf), "kmalloc:\n"); + mem_test(&descr); + + + return strlen(buf); +} + + + +static void *mem_kzalloc(ssize_t size, struct cnt_kmalloc *cnt) +{ + return kzalloc(size, cnt->flags); +} + +static void mem_kzfree(const void *mem, void *context) +{ + kzfree(mem); +} + +static ssize_t test_kzalloc_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + + struct mem_description descr; + struct cnt_kmalloc cnt; + + cnt.flags = GFP_KERNEL; + + descr.config.cnf_allocate.mem_allocate = (memory_allocate)mem_kzalloc; + descr.config.cnf_allocate.cnt = (void *)&cnt; + + descr.config.cnf_free.mem_free = mem_kzfree; + descr.config.cnf_free.cnt = NULL; + + descr.config.incr_size = incr_shift_bit; + + descr.buf = buf; + descr.config.max_size_mem = 0x9000000; + descr.config.start_size = 1; + + sprintf(descr.buf + strlen(descr.buf), "kzmalloc:\n"); + mem_test(&descr); + + + return strlen(buf); +} + + +static void *mem_vmalloc(ssize_t size, void *cnt) +{ + return vmalloc(size); +} + +static void mem_vfree(const void *mem, void *context) +{ + vfree(mem); +} + +static ssize_t test_vmalloc_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + struct mem_description descr; + + descr.config.cnf_allocate.mem_allocate = (memory_allocate)mem_vmalloc; + descr.config.cnf_allocate.cnt = NULL; + + descr.config.cnf_free.mem_free = mem_vfree; + descr.config.cnf_free.cnt = NULL; + + descr.config.incr_size = incr_shift_bit; + + descr.buf = buf; + descr.config.max_size_mem = 0x9000000; + descr.config.start_size = 1; + + sprintf(descr.buf + strlen(descr.buf), "vmalloc:\n"); + mem_test(&descr); + + + return strlen(buf); +} + +struct mem_free_page_cnt { + gfp_t flags; + unsigned long page; + unsigned int order; +}; + +static size_t incr_page(size_t cur_size) +{ + return cur_size + PAGE_SIZE; +} + +static void *mem_get_fre_page(ssize_t size, struct mem_free_page_cnt *cnt) +{ + cnt->order = size % PAGE_SIZE == 0 ? + size / PAGE_SIZE : size / PAGE_SIZE + 1; + cnt->page = __get_free_pages(cnt->flags, cnt->order); + return (void *)(cnt->page); +} + +static void mem_free_pages(const void *mem, struct mem_free_page_cnt *cnt) +{ + free_pages(cnt->page, cnt->order); +} + + +static ssize_t test_get_free_page_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + + struct mem_description descr; + struct mem_free_page_cnt cnt; + + cnt.flags = GFP_KERNEL; + + descr.config.cnf_allocate.mem_allocate = + (memory_allocate)mem_get_fre_page; + + descr.config.cnf_allocate.cnt = (void *)&cnt; + + descr.config.cnf_free.mem_free = (memory_free)mem_free_pages; + descr.config.cnf_free.cnt = (void *)&cnt; + + descr.config.incr_size = incr_page; + + descr.buf = buf; + descr.config.max_size_mem = PAGE_SIZE*29; + descr.config.start_size = PAGE_SIZE; + + sprintf(descr.buf + strlen(descr.buf), "get_free_page:\n"); + mem_test(&descr); + + + return strlen(buf); +} + + +struct class_attribute attr_test_kmalloc = { + .attr = { .name = "test_kmalloc", .mode = 0444 }, + .show = test_kmalloc_show, +}; + +struct class_attribute attr_test_kzmalloc = { + .attr = { .name = "test_kzmalloc", .mode = 0444 }, + .show = test_kzalloc_show, +}; + +struct class_attribute attr_test_vmalloc = { + .attr = { .name = "test_vmalloc", .mode = 0444 }, + .show = test_vmalloc_show, +}; + +struct class_attribute attr_test_free_page = { + .attr = { .name = "test_get_free_page", .mode = 0444 }, + .show = test_get_free_page_show, +}; + + +static struct class *mem_class; + +static int __init mem_init(void) +{ +int ret; + +mem_class = class_create(THIS_MODULE, "memory_management"); +if (mem_class == NULL) { + pr_err("MemoryManagement: error creating sysfs class\n"); + return -ENOMEM; +} + +ret = class_create_file(mem_class, &attr_test_kmalloc); +if (ret) { + pr_err("MemoryManagement: error creating sysfs class attribute\n"); + return ret; +} + +ret = class_create_file(mem_class, &attr_test_kzmalloc); +if (ret) { + pr_err("MemoryManagement: error creating sysfs class attribute\n"); + return ret; +} + +ret = class_create_file(mem_class, &attr_test_vmalloc); +if (ret) { + pr_err("MemoryManagement: error creating sysfs class attribute\n"); + return ret; +} + +ret = class_create_file(mem_class, &attr_test_free_page); +if (ret) { + pr_err("MemoryManagement: error creating sysfs class attribute\n"); + return ret; +} + +pr_info("MemoryManagement:loaded\n"); +return 0; +} + +static void __exit mem_exit(void) +{ +class_remove_file(mem_class, &attr_test_kmalloc); +class_remove_file(mem_class, &attr_test_kzmalloc); +class_remove_file(mem_class, &attr_test_vmalloc); +class_remove_file(mem_class, &attr_test_free_page); +class_destroy(mem_class); +pr_info("MemoryManagement: closed"); +} + +module_init(mem_init); +module_exit(mem_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Happybolt "); +MODULE_DESCRIPTION("MemoryManagement"); +MODULE_VERSION("0.1"); diff --git a/07-MemoryManagement/kernel_space/result/kmalloc b/07-MemoryManagement/kernel_space/result/kmalloc new file mode 100644 index 0000000..23aea4c --- /dev/null +++ b/07-MemoryManagement/kernel_space/result/kmalloc @@ -0,0 +1,33 @@ +$ cat /sys/class/memory_management/test_kmalloc +kmalloc: +number addr size alloc(ns) free(ns) + 1 c70a22a8 1 2747 1714 + 2 c70a22a8 2 1005 508 + 3 c70a22a8 4 537 441 + 4 c70a22a8 8 510 398 + 5 c7802320 16 630 464 + 6 c71ec0c0 32 519 439 + 7 c71d3000 64 615 421 + 8 c71de500 128 581 379 + 9 c7babc00 256 715 1436 + 10 c71dd400 512 823 425 + 11 c71f0400 1024 1941 380 + 12 c70cf800 2048 1149 459 + 13 c7919000 4096 1097 445 + 14 c7072000 8192 1645 432 + 15 c7204000 16384 10028 6274 + 16 c7208000 32768 2978 1700 + 17 c7210000 65536 1829 1382 + 18 c7220000 131072 2098 1468 + 19 c7240000 262144 2669 2768 + 20 c7280000 524288 4116 3430 + 21 c7300000 1048576 6888 5726 + 22 c6800000 2097152 14032 9778 + 23 c6800000 4194304 23305 17540 + 24 (null) 8388608 19950 0 + 25 (null) 16777216 8017 0 + 26 (null) 33554432 25207 0 + 27 (null) 67108864 26982 0 + 28 (null) 134217728 37757 0 + + diff --git a/07-MemoryManagement/kernel_space/result/kzmalloc b/07-MemoryManagement/kernel_space/result/kzmalloc new file mode 100644 index 0000000..b420359 --- /dev/null +++ b/07-MemoryManagement/kernel_space/result/kzmalloc @@ -0,0 +1,33 @@ +$ cat /sys/class/memory_management/test_kzmalloc +kzmalloc: +number addr size alloc(ns) free(ns) + 1 c70a22a8 1 3452 4379 + 2 c70a22a8 2 964 807 + 3 c70a22a8 4 608 612 + 4 c70a22a8 8 504 505 + 5 c7802320 16 750 649 + 6 c71ec100 32 728 592 + 7 c71d3400 64 873 772 + 8 c71de500 128 968 993 + 9 c7babc00 256 1462 2464 + 10 c71dd400 512 3367 2751 + 11 c71f0400 1024 6242 4737 + 12 c70cf800 2048 8888 8982 + 13 c7919000 4096 17449 16018 + 14 c7072000 8192 35938 33133 + 15 c7204000 16384 55085 191873 + 16 c7208000 32768 34046 93968 + 17 c7210000 65536 57578 183961 + 18 c7220000 131072 113335 473868 + 19 c7240000 262144 227191 846022 + 20 c7280000 524288 449556 2002365 + 21 c7300000 1048576 1906103 3338440 + 22 c6800000 2097152 1996026 6454756 + 23 c6800000 4194304 3895408 12733721 + 24 (null) 8388608 22107 0 + 25 (null) 16777216 7218 0 + 26 (null) 33554432 6397 0 + 27 (null) 67108864 6155 0 + 28 (null) 134217728 6088 0 + + diff --git a/07-MemoryManagement/kernel_space/result/res_get_free_page b/07-MemoryManagement/kernel_space/result/res_get_free_page new file mode 100644 index 0000000..0a1c3de --- /dev/null +++ b/07-MemoryManagement/kernel_space/result/res_get_free_page @@ -0,0 +1,32 @@ +$ cat /sys/class/memory_management/test_get_free_page +get_free_page: +number addr size alloc(ns) free(ns) + 1 c7202000 4096 10225 6690 + 2 c7204000 8192 2911 1715 + 3 c7208000 12288 1479 1008 + 4 c7210000 16384 1425 1032 + 5 c7220000 20480 1546 1169 + 6 c7240000 24576 1877 2402 + 7 c7280000 28672 2913 2807 + 8 c7300000 32768 4939 4103 + 9 c6800000 36864 11658 7272 + 10 c6800000 40960 15223 12873 + 11 (null) 45056 15073 0 + 12 (null) 49152 6808 0 + 13 (null) 53248 6113 0 + 14 (null) 57344 5970 0 + 15 (null) 61440 5889 0 + 16 (null) 65536 5798 0 + 17 (null) 69632 5861 0 + 18 (null) 73728 5849 0 + 19 (null) 77824 5917 0 + 20 (null) 81920 5810 0 + 21 (null) 86016 17594 0 + 22 (null) 90112 49634 0 + 23 (null) 94208 149272 0 + 24 (null) 98304 10933 0 + 25 (null) 102400 10544 0 + 26 (null) 106496 20260 0 + 27 (null) 110592 12605 0 + 28 (null) 114688 11797 0 + diff --git a/07-MemoryManagement/kernel_space/result/vmalloc b/07-MemoryManagement/kernel_space/result/vmalloc new file mode 100644 index 0000000..79d8af6 --- /dev/null +++ b/07-MemoryManagement/kernel_space/result/vmalloc @@ -0,0 +1,32 @@ +$ cat /sys/class/memory_management/test_vmalloc +vmalloc: +number addr size alloc(ns) free(ns) + 1 c8802000 1 249742 12610 + 2 c880c000 2 225481 4339 + 3 c880e000 4 237313 2512 + 4 c8810000 8 324876 4050 + 5 c8812000 16 222778 2738 + 6 c8814000 32 221144 2410 + 7 c8816000 64 320903 4189 + 8 c8818000 128 223557 2972 + 9 c881a000 256 222191 2349 + 10 c881c000 512 220797 2360 + 11 c881e000 1024 333152 4099 + 12 c8852000 2048 224589 2760 + 13 c8854000 4096 221649 2417 + 14 c8856000 8192 221375 3055 + 15 c8859000 16384 322219 5046 + 16 c885e000 32768 298795 9069 + 17 c8867000 65536 387385 11568 + 18 c8878000 131072 333175 13937 + 19 c8899000 262144 276216 37316 + 20 c88da000 524288 311127 181098 + 21 c8a16000 1048576 393064 133917 + 22 c8b17000 2097152 643924 275044 + 23 c8d18000 4194304 1088527 1168501 + 24 c9119000 8388608 1930873 1799680 + 25 c991a000 16777216 3685648 2431699 + 26 c8a16000 33554432 5565656 5238048 + 27 c8a16000 67108864 11872714 9092939 + 28 (null) 134217728 4572809 0 +