Example: make the block count dynamic sandbox/mbloch/resize-example
authorMichal Bloch <m.bloch@samsung.com>
Wed, 28 Feb 2024 17:18:02 +0000 (18:18 +0100)
committerMichal Bloch <m.bloch@samsung.com>
Wed, 28 Feb 2024 17:53:53 +0000 (18:53 +0100)
Change-Id: If9a6fabcf1fa34a4ec016273cf3ebaebd90a20c6

include/uapi/linux/zlogger.h
kernel/zlogger/zlogger.c

index 7e8b73dba649e649c49e1cc0daf66446930d442a..6251e4bf9ad4de40a447ce683bf9d5beb2394439 100644 (file)
@@ -32,7 +32,7 @@
 #define ZLOGGER_BLOCK_COUNT (ZLOGGER_BUFFER_SIZE / ZLOGGER_BLOCK_SIZE)
 #define ZLOGGER_BITMAP_SIZE (ZLOGGER_BLOCK_COUNT / 8)
 #define ZLOGGER_DATA_MAX (ZLOGGER_BLOCK_SIZE - sizeof(struct zlogger_header))
-#define ZLOGGER_BLOCK_NUMBER 8192
+#define ZLOGGER_INITIAL_BLOCK_NUMBER 8192
 
 #define ZLOGGER_TAG_MAX (32)
 #define ZLOGGER_MSG_MAX (140)
index 9916b4e909ba6eac2d5efe5d41a8f24ef8bd3c19..d755d248ab1f039c64c93958001c2bf9caf34e03 100644 (file)
@@ -119,7 +119,8 @@ static struct miscdevice zlogger_device;
 static struct miscdevice zlogger_dump_device;
 
 static int g_init;
-static char *g_shm_ptr[ZLOGGER_BLOCK_NUMBER];
+static char **g_shm_ptr;
+static uint32_t g_shm_ptr_size;
 static struct thread_table *g_thread_table;
 
 static struct mutex g_block_mutex;
@@ -1063,12 +1064,22 @@ static long zlogger_get_bitmap(struct file *filp, unsigned long arg)
        return 0;
 }
 
+static long zlogger_resize(unsigned long arg)
+{
+       // save blocks if shrinking, avoid ruining everything via realloc if expanding
+       g_shm_ptr_size = arg;
+       return 0;
+}
+
 static long zlogger_dump_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
                case ZLOGGER_IOCTL_COMMAND_CLEAR:
                        return zlogger_clear();
 
+               case ZLOGGER_IOCTL_COMMAND_RESIZE:
+                       return zlogger_resize(arg);
+
                case ZLOGGER_IOCTL_COMMAND_GET_BITMAP:
                        return zlogger_get_bitmap(filp, arg);
 
@@ -1105,14 +1116,8 @@ static int zlogger_init(void)
        int g_shm_ptr_i = 0;
        int r = 0;
 
-       unsigned int target_size = 32 * 1024 * 1024; // 32mb
        unsigned int page_size = 4 * 1024; // 4kb
 
-       unsigned int iterations = target_size / page_size;
-       if (target_size % page_size != 0) {
-               iterations++;
-       }
-
        if (!g_zlog_enable) {
                pr_info("zlog is disable\n");
                return 0;
@@ -1123,7 +1128,15 @@ static int zlogger_init(void)
                return -ENOMEM;
        hash_init(g_thread_table->data);
 
-       for (g_shm_ptr_i = 0; g_shm_ptr_i < iterations; g_shm_ptr_i++) {
+       g_shm_ptr = kzalloc(ZLOGGER_INITIAL_BLOCK_NUMBER * sizeof *g_shm_ptr, GFP_KERNEL);
+       if (g_shm_ptr == NULL) {
+               kfree(g_thread_table);
+               g_thread_table = NULL;
+               return -ENOMEM;
+       }
+       g_shm_ptr_size     = ZLOGGER_INITIAL_BLOCK_NUMBER;
+
+       for (g_shm_ptr_i = 0; g_shm_ptr_i < g_shm_ptr_size; g_shm_ptr_i++) {
                g_shm_ptr[g_shm_ptr_i] = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(page_size));
                if (g_shm_ptr[g_shm_ptr_i] == NULL) {
                        r = -ENOMEM;
@@ -1191,6 +1204,9 @@ out_free_g_thread_table_g_shm_ptr:
                g_shm_ptr[i] = NULL;
        }
 
+       kfree(g_shm_ptr);
+       g_shm_ptr = NULL;
+
        kfree(g_thread_table);
        g_thread_table = NULL;
 
@@ -1217,11 +1233,14 @@ static void zlogger_exit(void)
        kfree(g_thread_table);
        g_thread_table = NULL;
 
-       for (i = 0; i < ZLOGGER_DEVICE_COUNT; i++) {
+       for (i = 0; i < g_shm_ptr_size; i++) {
                free_pages((unsigned long)g_shm_ptr[i], MAP_ORDER);
                g_shm_ptr[i] = NULL;
        }
 
+       kfree(g_shm_ptr);
+       g_shm_ptr = NULL;
+
        g_init = 0;
 }