From a0dc00578f7a7be740641e12102af53778730eca Mon Sep 17 00:00:00 2001 From: Ivan Priest Date: Fri, 22 Mar 2019 15:48:29 +0000 Subject: [PATCH] [NEUS7920-133]wlbt: track shared DRAM allocations Add instrumentation to track shared DRAM allocators in procfs Change-Id: I90c9da7c10f54dadf9c6968bcf047e16de5c83fc SCSC-Bug-Id: SSB-50917 Signed-off-by: Ivan Priest --- drivers/misc/samsung/scsc/cpacket_buffer.c | 6 +- drivers/misc/samsung/scsc/mifproc.c | 26 ++++--- drivers/misc/samsung/scsc/mifproc.h | 2 +- drivers/misc/samsung/scsc/miframman.c | 90 +++++++++++++++++++--- drivers/misc/samsung/scsc/miframman.h | 13 +++- drivers/misc/samsung/scsc/mxlogger.c | 4 +- drivers/misc/samsung/scsc/mxman.c | 2 +- drivers/misc/samsung/scsc/scsc_service.c | 2 +- 8 files changed, 115 insertions(+), 30 deletions(-) diff --git a/drivers/misc/samsung/scsc/cpacket_buffer.c b/drivers/misc/samsung/scsc/cpacket_buffer.c index e5533fce694e..ba555c8b362b 100644 --- a/drivers/misc/samsung/scsc/cpacket_buffer.c +++ b/drivers/misc/samsung/scsc/cpacket_buffer.c @@ -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); diff --git a/drivers/misc/samsung/scsc/mifproc.c b/drivers/misc/samsung/scsc/mifproc.c index c46b1f340ae1..c162accc18d3 100644 --- a/drivers/misc/samsung/scsc/mifproc.c +++ b/drivers/misc/samsung/scsc/mifproc.c @@ -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; diff --git a/drivers/misc/samsung/scsc/mifproc.h b/drivers/misc/samsung/scsc/mifproc.h index ef1bd166c61c..ea92c5bf264d 100644 --- a/drivers/misc/samsung/scsc/mifproc.h +++ b/drivers/misc/samsung/scsc/mifproc.h @@ -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) diff --git a/drivers/misc/samsung/scsc/miframman.c b/drivers/misc/samsung/scsc/miframman.c index 0dd6daade843..d2f16b135014 100644 --- a/drivers/misc/samsung/scsc/miframman.c +++ b/drivers/misc/samsung/scsc/miframman.c @@ -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)); + } + } +} diff --git a/drivers/misc/samsung/scsc/miframman.h b/drivers/misc/samsung/scsc/miframman.h index d7fb1142d132..acce9dac4daf 100644 --- a/drivers/misc/samsung/scsc/miframman.h +++ b/drivers/misc/samsung/scsc/miframman.h @@ -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 { diff --git a/drivers/misc/samsung/scsc/mxlogger.c b/drivers/misc/samsung/scsc/mxlogger.c index e98030be13ea..8d37d634eaf1 100644 --- a/drivers/misc/samsung/scsc/mxlogger.c +++ b/drivers/misc/samsung/scsc/mxlogger.c @@ -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; diff --git a/drivers/misc/samsung/scsc/mxman.c b/drivers/misc/samsung/scsc/mxman.c index b38178e4fa9a..525b20847bc5 100755 --- a/drivers/misc/samsung/scsc/mxman.c +++ b/drivers/misc/samsung/scsc/mxman.c @@ -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)); diff --git a/drivers/misc/samsung/scsc/scsc_service.c b/drivers/misc/samsung/scsc/scsc_service.c index b610ae52f5c8..7aee37cd4df2 100755 --- a/drivers/misc/samsung/scsc/scsc_service.c +++ b/drivers/misc/samsung/scsc/scsc_service.c @@ -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; -- 2.20.1