[NEUS7920-133]wlbt: track shared DRAM allocations
authorIvan Priest <i.priest@samsung.com>
Fri, 22 Mar 2019 15:48:29 +0000 (15:48 +0000)
committerYoungmin Nam <youngmin.nam@samsung.com>
Tue, 21 May 2019 10:45:22 +0000 (19:45 +0900)
Add instrumentation to track shared DRAM allocators
in procfs

Change-Id: I90c9da7c10f54dadf9c6968bcf047e16de5c83fc
SCSC-Bug-Id: SSB-50917
Signed-off-by: Ivan Priest <i.priest@samsung.com>
drivers/misc/samsung/scsc/cpacket_buffer.c
drivers/misc/samsung/scsc/mifproc.c
drivers/misc/samsung/scsc/mifproc.h
drivers/misc/samsung/scsc/miframman.c
drivers/misc/samsung/scsc/miframman.h
drivers/misc/samsung/scsc/mxlogger.c
drivers/misc/samsung/scsc/mxman.c
drivers/misc/samsung/scsc/scsc_service.c

index e5533fce694e5572ef1f2a413244ebdafb68aa91..ba555c8b362bec05b046239e40fd601269279961 100644 (file)
@@ -126,17 +126,17 @@ int cpacketbuffer_init(struct cpacketbuffer *buffer, uint32_t num_packets, uint3
        buffer->mx = mx;
 
        miframman = scsc_mx_get_ramman(mx);
-       mem = miframman_alloc(miframman, num_packets * packet_size, 4);
+       mem = miframman_alloc(miframman, num_packets * packet_size, 4, MIFRAMMAN_OWNER_COMMON);
        if (!mem)
                return -ENOMEM;
 
-       ridx = miframman_alloc(miframman, sizeof(uint32_t), 4);
+       ridx = miframman_alloc(miframman, sizeof(uint32_t), 4, MIFRAMMAN_OWNER_COMMON);
        if (!ridx) {
                miframman_free(miframman, mem);
                return -ENOMEM;
        }
 
-       widx = miframman_alloc(miframman, sizeof(uint32_t), 4);
+       widx = miframman_alloc(miframman, sizeof(uint32_t), 4, MIFRAMMAN_OWNER_COMMON);
        if (!widx) {
                miframman_free(miframman, ridx);
                miframman_free(miframman, mem);
index c46b1f340ae18d406dee03d6ddd2a6a8a590879f..c162accc18d355894f188e2dddffff78d2cb2d3f 100644 (file)
@@ -29,9 +29,6 @@ static int mifprocfs_open_file_generic(struct inode *inode, struct file *file)
 MIF_PROCFS_RW_FILE_OPS(mif_dump);
 MIF_PROCFS_RW_FILE_OPS(mif_writemem);
 MIF_PROCFS_RW_FILE_OPS(mif_reg);
-/*
-MIF_PROCFS_SEQ_FILE_OPS(mif_dbg);
-*/
 
 /* miframman ops */
 MIF_PROCFS_RO_FILE_OPS(ramman_total);
@@ -41,6 +38,8 @@ MIF_PROCFS_RO_FILE_OPS(ramman_free);
 MIF_PROCFS_RO_FILE_OPS(ramman_used);
 MIF_PROCFS_RO_FILE_OPS(ramman_size);
 
+MIF_PROCFS_SEQ_FILE_OPS(ramman_list);
+
 static ssize_t mifprocfs_mif_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
 {
        char         buf[128];
@@ -352,6 +351,17 @@ static ssize_t mifprocfs_ramman_used_read(struct file *file, char __user *user_b
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+/* List allocations per ramman */
+static int mifprocfs_ramman_list_show(struct seq_file *m, void *v)
+{
+       struct miframman *ramman = (struct miframman *)m->private;
+       (void)v;
+
+       miframman_log(ramman, m);
+
+       return 0;
+}
+
 static const char *procdir = "driver/mif_ctrl";
 static int refcount;
 
@@ -399,9 +409,6 @@ int mifproc_create_proc_dir(struct scsc_mif_abs *mif)
                MIF_PROCFS_ADD_FILE(NULL, mif_writemem, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
                MIF_PROCFS_ADD_FILE(NULL, mif_dump, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
                MIF_PROCFS_ADD_FILE(NULL, mif_reg, parent, S_IRUSR | S_IRGRP);
-               /*
-               MIF_PROCFS_SEQ_ADD_FILE(NULL, mif_dbg, parent, S_IRUSR | S_IRGRP | S_IROTH);
-               */
        } else {
                SCSC_TAG_INFO(MIF, "failed to create /proc dir\n");
                return -EINVAL;
@@ -422,9 +429,6 @@ void mifproc_remove_proc_dir(void)
                MIF_PROCFS_REMOVE_FILE(mif_writemem, procfs_dir);
                MIF_PROCFS_REMOVE_FILE(mif_dump, procfs_dir);
                MIF_PROCFS_REMOVE_FILE(mif_reg, procfs_dir);
-               /*
-               MIF_PROCFS_REMOVE_FILE(mif_dbg, procfs_dir);
-               */
 
                /* De-ref the root dir */
                destroy_procfs_dir();
@@ -465,6 +469,8 @@ int mifproc_create_ramman_proc_dir(struct miframman *ramman)
                MIF_PROCFS_ADD_FILE(ramman, ramman_free, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
                MIF_PROCFS_ADD_FILE(ramman, ramman_used, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 
+               MIF_PROCFS_SEQ_ADD_FILE(ramman, ramman_list, parent, S_IRUSR | S_IRGRP | S_IROTH);
+
                procfs_dir_ramman[ramman_instance] = parent;
                proc_miframman[ramman_instance] = ramman;
 
@@ -500,6 +506,8 @@ void mifproc_remove_ramman_proc_dir(struct miframman *ramman)
                MIF_PROCFS_REMOVE_FILE(ramman_free, procfs_dir_ramman[ramman_instance]);
                MIF_PROCFS_REMOVE_FILE(ramman_used, procfs_dir_ramman[ramman_instance]);
 
+               MIF_PROCFS_REMOVE_FILE(ramman_list, procfs_dir_ramman[ramman_instance]);
+
                (void)snprintf(dir, sizeof(dir), "%s%d", ramman_procdir, ramman_instance);
                remove_proc_entry(dir, procfs_dir);
                procfs_dir_ramman[ramman_instance] = NULL;
index ef1bd166c61c07dcc6e7c7d6488aecdfd0438af7..ea92c5bf264dc7b3c3b8d4460456f1c3037f0a44 100644 (file)
@@ -42,7 +42,7 @@
                struct proc_dir_entry *entry;               \
                entry = proc_create_data(# name, mode, parent, &mifprocfs_ ## name ## _fops, _sdev); \
                if (!entry) {                               \
-                       goto err;                           \
+                       break;                              \
                }                                           \
                MIF_PROCFS_SET_UID_GID(entry);                            \
        } while (0)
index 0dd6daade8432b7b808250fc3dc53010aea1c90e..d2f16b135014616797fb2066ceb7681632c675f0 100644 (file)
@@ -48,7 +48,7 @@ void miframabox_init(struct mifabox *mifabox, void *start_aboxram)
        mifabox->aboxram = (struct scsc_bt_audio_abox *)start_aboxram;
 }
 
-void *__miframman_alloc(struct miframman *ram, size_t nbytes)
+void *__miframman_alloc(struct miframman *ram, size_t nbytes, int tag)
 {
        unsigned int index = 0;
        unsigned int available;
@@ -79,10 +79,17 @@ void *__miframman_alloc(struct miframman *ram, size_t nbytes)
                        free_mem = ram->start_dram +
                                   MIFRAMMAN_BLOCK_SIZE * index;
 
-                       /* Mark the blocks as used */
-                       ram->bitmap[index++] = BLOCK_BOUND;
-                       for (i = 1; i < num_blocks; i++)
-                               ram->bitmap[index++] = BLOCK_INUSE;
+                       /* Mark the block boundary as used */
+                       ram->bitmap[index] = BLOCK_BOUND;
+                       ram->bitmap[index] |= (u8)(tag <<  MIFRAMMAN_BLOCK_OWNER_SHIFT); /* Add owner tack for tracking */
+                       index++;
+
+                       /* Additional blocks in this allocation */
+                       for (i = 1; i < num_blocks; i++) {
+                               ram->bitmap[index] = BLOCK_INUSE;
+                               ram->bitmap[index] |= (u8)(tag <<  MIFRAMMAN_BLOCK_OWNER_SHIFT); /* Add owner tack for tracking */
+                               index++;
+                       }
 
                        ram->free_mem -= num_blocks * MIFRAMMAN_BLOCK_SIZE;
                        goto exit;
@@ -106,7 +113,19 @@ exit:
        (*(((void **)((uintptr_t)(mem) & \
                      (~(uintptr_t)(sizeof(void *) - 1)))) - 1))
 
-void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align)
+/*
+ * Allocate shared DRAM block
+ *
+ * Parameters:
+ *  ram                - pool identifier
+ *  nbytes     - allocation size
+ *  align      - allocation alignment
+ *  tag                - owner identifier (typically service ID), 4 bits.
+ *
+ * Returns
+ *  Pointer to allocated area, or NULL
+ */
+void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align, int tag)
 {
        void *mem, *align_mem = NULL;
 
@@ -119,7 +138,7 @@ void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align)
        if (align < sizeof(void *))
                align = sizeof(void *);
 
-       mem = __miframman_alloc(ram, nbytes + align + sizeof(void *));
+       mem = __miframman_alloc(ram, nbytes + align + sizeof(void *), tag);
        if (!mem)
                goto end;
 
@@ -132,6 +151,13 @@ end:
        return align_mem;
 }
 
+/*
+ * Free shared DRAM block
+ *
+ * Parameters:
+ *  ram                - pool identifier
+ *  mem                - buffer to free
+ */
 void __miframman_free(struct miframman *ram, void *mem)
 {
        unsigned int index, num_blocks = 0;
@@ -152,14 +178,15 @@ void __miframman_free(struct miframman *ram, void *mem)
        }
 
        /* Check it is a Boundary block */
-       if (ram->bitmap[index] != BLOCK_BOUND) {
+       if ((ram->bitmap[index] & MIFRAMMAN_BLOCK_STATUS_MASK) != BLOCK_BOUND) {
                SCSC_TAG_ERR(MIF, "Incorrect Block descriptor\n");
                return;
        }
-
        ram->bitmap[index++] = BLOCK_FREE;
+
+       /* Free remaining blocks */
        num_blocks++;
-       while (index < ram->num_blocks && ram->bitmap[index] == BLOCK_INUSE) {
+       while (index < ram->num_blocks && (ram->bitmap[index] & MIFRAMMAN_BLOCK_STATUS_MASK) == BLOCK_INUSE) {
                ram->bitmap[index++] = BLOCK_FREE;
                num_blocks++;
        }
@@ -179,7 +206,7 @@ void miframman_free(struct miframman *ram, void *mem)
 /* Caller should provide locking */
 void miframman_deinit(struct miframman *ram)
 {
-       /* Mark all the blocks as INUSE to prevent new allocations */
+       /* Mark all the blocks as INUSE (by Common) to prevent new allocations */
        memset(ram->bitmap, BLOCK_INUSE, sizeof(ram->bitmap));
 
        ram->num_blocks = 0;
@@ -197,3 +224,44 @@ void miframabox_deinit(struct mifabox *mifabox)
        mifabox->aboxram = NULL;
 }
 
+/* Log current allocations in a ramman in proc */
+void miframman_log(struct miframman *ram, struct seq_file *fd)
+{
+       unsigned int b;
+       unsigned int i;
+       int tag;
+       size_t num_blocks = 0;
+
+       if (!ram)
+               return;
+
+       seq_printf(fd, "ramman: start_dram %p, size %zd, free_mem %u\n\n",
+               ram->start_region, ram->size_pool, ram->free_mem);
+
+       for (b = 0; b < ram->num_blocks; b++) {
+               if ((ram->bitmap[b] & MIFRAMMAN_BLOCK_STATUS_MASK) == BLOCK_BOUND) {
+                       /* Found a boundary allocation */
+                       num_blocks++;
+                       tag = (ram->bitmap[b] & MIFRAMMAN_BLOCK_OWNER_MASK) >> MIFRAMMAN_BLOCK_OWNER_SHIFT;
+
+                       /* Count subsequent blocks in this group */
+                       for (i = 1;
+                            i < ram->num_blocks && (ram->bitmap[b + i] & MIFRAMMAN_BLOCK_STATUS_MASK) == BLOCK_INUSE;
+                            i++) {
+                               /* Check owner matches boundary block */
+                               int newtag = (ram->bitmap[b + i] & MIFRAMMAN_BLOCK_OWNER_MASK) >> MIFRAMMAN_BLOCK_OWNER_SHIFT;
+                               if (newtag != tag) {
+                                       seq_printf(fd, "Allocated block tag %d doesn't match boundary tag %d, index %d, %p\n",
+                                               newtag, tag, b + i,
+                                               ram->start_dram + (b + i) * MIFRAMMAN_BLOCK_SIZE);
+                               }
+                               num_blocks++;
+                       }
+                       seq_printf(fd, "index %8d, svc %d, bytes %12d, blocks %10d, %p\n",
+                               b, tag,
+                               (i * MIFRAMMAN_BLOCK_SIZE),
+                               i,
+                               ram->start_dram + (b  * MIFRAMMAN_BLOCK_SIZE));
+               }
+       }
+}
index d7fb1142d132ec9e1343af56f7f255778a937539..acce9dac4daf2df14352813b1cf0a4f4ffc0c33b 100644 (file)
@@ -18,19 +18,28 @@ struct mifabox;
 
 void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool, void *start_region);
 void miframabox_init(struct mifabox *mifabox, void *start_aboxram);
-void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align);
+void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align, int tag);
 void miframman_free(struct miframman *ram, void *mem);
 void miframman_deinit(struct miframman *ram);
 void miframabox_deinit(struct mifabox *mifabox);
+void miframman_log(struct miframman *ram, struct seq_file *fd);
 
 #define MIFRAMMAN_MAXMEM        (16 * 1024 * 1024)
 #define MIFRAMMAN_BLOCK_SIZE    (64)
 
 #define MIFRAMMAN_NUM_BLOCKS    ((MIFRAMMAN_MAXMEM) / (MIFRAMMAN_BLOCK_SIZE))
 
+/* Block status in lower nibble */
+#define MIFRAMMAN_BLOCK_STATUS_MASK    0x0f
 #define BLOCK_FREE      0
 #define BLOCK_INUSE     1
-#define BLOCK_BOUND     2
+#define BLOCK_BOUND     2      /* Block allocation boundary */
+
+/* Block owner in upper nibble */
+#define MIFRAMMAN_BLOCK_OWNER_MASK     0xf0
+#define MIFRAMMAN_BLOCK_OWNER_SHIFT    4
+
+#define MIFRAMMAN_OWNER_COMMON 0       /* Owner tag for Common driver */
 
 /* Inclusion in core.c treat it as opaque */
 struct miframman {
index e98030be13ea323f96c78a991d12eb0e35b50854..8d37d634eaf1ab414b5cb286d994bc3e6e369e4a 100644 (file)
@@ -546,7 +546,7 @@ void mxlogger_print_mapping(struct mxlogger_config_area *cfg)
 
 }
 
-/* Lock should be adquired by caller */
+/* Lock should be acquired by caller */
 int mxlogger_init(struct scsc_mx *mx, struct mxlogger *mxlogger, uint32_t mem_sz)
 {
        struct miframman *miframman;
@@ -569,7 +569,7 @@ int mxlogger_init(struct scsc_mx *mx, struct mxlogger *mxlogger, uint32_t mem_sz
        miframman = scsc_mx_get_ramman2(mx);
        if (!miframman)
                return -ENOMEM;
-       mxlogger->mem = miframman_alloc(miframman, mem_sz, 32);
+       mxlogger->mem = miframman_alloc(miframman, mem_sz, 32, MIFRAMMAN_OWNER_COMMON);
        if (!mxlogger->mem) {
                SCSC_TAG_ERR(MXMAN, "Error allocating memory for MXLOGGER\n");
                return -ENOMEM;
index b38178e4fa9ada874bb65949c8b24c31c89fa39a..525b20847bc5d03fe00faa0df2c76a0d1324422a 100755 (executable)
@@ -789,7 +789,7 @@ static int transports_init(struct mxman *mxman)
         * Allocate & Initialise Infrastructre Config Structure
         * including the mx management stack config information.
         */
-       mxconf = miframman_alloc(scsc_mx_get_ramman(mx), sizeof(struct mxconf), 4);
+       mxconf = miframman_alloc(scsc_mx_get_ramman(mx), sizeof(struct mxconf), 4, MIFRAMMAN_OWNER_COMMON);
        if (!mxconf) {
                SCSC_TAG_ERR(MXMAN, "miframman_alloc() failed\n");
                gdb_transport_release(scsc_mx_get_gdb_transport_m4(mx));
index b610ae52f5c8140a544623d183426c1c33a5b716..7aee37cd4df2330f9403aff51f5b001d714bb645 100755 (executable)
@@ -703,7 +703,7 @@ int scsc_mx_service_mifram_alloc_extended(struct scsc_service *service, size_t n
                return -ENOMEM;
        }
 
-       mem = miframman_alloc(ramman, nbytes, align);
+       mem = miframman_alloc(ramman, nbytes, align, service->id);
        if (!mem) {
                SCSC_TAG_ERR(MXMAN, "miframman_alloc() failed\n");
                *ref = SCSC_MIFRAM_INVALID_REF;