summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Fekete <robert.fekete@stericsson.com>2011-09-22 15:10:28 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:43 +0200
commit40d7e9cefcea5041282c974dd05cc8cc1d390217 (patch)
tree83eafd03efdde0ed072b6c3eeac4d76736357f0d
parentbb319a37f5e7177243c94aa0d6573276cc4ec43b (diff)
hwmem: Add peak memory usage in debugfs prints
When doing cat debugfs/cona/hwmem_allocs you will now see current memory usage, Max amount of hwmem memory used after boot, and size of biggest free block. ST-Ericsson ID: 359308 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I287b711c8e950cc3370a2cc47672f8aefdd873e4 Signed-off-by: Robert Fekete <robert.fekete@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31835 Reviewed-by: Maciej SOCHA <maciej.socha@stericsson.com> Reviewed-by: Jimmy RUBIN <jimmy.rubin@stericsson.com> Reviewed-by: Anders BAUER <anders.bauer@stericsson.com> Reviewed-by: Linus WALLEIJ <linus.walleij@stericsson.com>
-rw-r--r--drivers/misc/hwmem/contig_alloc.c125
1 files changed, 114 insertions, 11 deletions
diff --git a/drivers/misc/hwmem/contig_alloc.c b/drivers/misc/hwmem/contig_alloc.c
index bc71ca08f0f..31533ed5988 100644
--- a/drivers/misc/hwmem/contig_alloc.c
+++ b/drivers/misc/hwmem/contig_alloc.c
@@ -43,6 +43,12 @@ struct instance {
#ifdef CONFIG_DEBUG_FS
struct inode *debugfs_inode;
+ int cona_status_free;
+ int cona_status_used;
+ int cona_status_max_cont;
+ int cona_status_max_check;
+ int cona_status_biggest_free;
+ int cona_status_printed;
#endif /* #ifdef CONFIG_DEBUG_FS */
};
@@ -140,6 +146,12 @@ void *cona_alloc(void *instance, size_t size)
} else {
alloc->in_use = true;
}
+#ifdef CONFIG_DEBUG_FS
+ instance_l->cona_status_max_cont += alloc->size;
+ instance_l->cona_status_max_check =
+ max(instance_l->cona_status_max_check,
+ instance_l->cona_status_max_cont);
+#endif /* #ifdef CONFIG_DEBUG_FS */
out:
mutex_unlock(&lock);
@@ -157,6 +169,10 @@ void cona_free(void *instance, void *alloc)
alloc_l->in_use = false;
+#ifdef CONFIG_DEBUG_FS
+ instance_l->cona_status_max_cont -= alloc_l->size;
+#endif /* #ifdef CONFIG_DEBUG_FS */
+
other = list_entry(alloc_l->list.prev, struct alloc, list);
if ((alloc_l->list.prev != &instance_l->alloc_list) &&
!other->in_use) {
@@ -237,6 +253,10 @@ static int init_alloc_list(struct instance *instance)
list_add_tail(&alloc->list, &instance->alloc_list);
curr_pos = alloc->paddr + alloc->size;
+#ifdef CONFIG_DEBUG_FS
+ instance->cona_status_max_cont += alloc->size;
+#endif /* #ifdef CONFIG_DEBUG_FS */
+
next_64mib_boundary += SZ_64M;
}
@@ -319,7 +339,10 @@ static phys_addr_t get_alloc_offset(struct instance *instance,
#ifdef CONFIG_DEBUG_FS
-static int print_alloc(struct alloc *alloc, char **buf, size_t buf_size);
+static int print_alloc(struct instance *instance, struct alloc *alloc,
+ char **buf, size_t buf_size);
+static int print_alloc_status(struct instance *instance, char **buf,
+ size_t buf_size);
static struct instance *get_instance_from_file(struct file *file);
static int debugfs_allocs_read(struct file *filp, char __user *buf,
size_t count, loff_t *f_pos);
@@ -329,7 +352,8 @@ static const struct file_operations debugfs_allocs_fops = {
.read = debugfs_allocs_read,
};
-static int print_alloc(struct alloc *alloc, char **buf, size_t buf_size)
+static int print_alloc(struct instance *instance, struct alloc *alloc,
+ char **buf, size_t buf_size)
{
int ret;
int i;
@@ -341,9 +365,64 @@ static int print_alloc(struct alloc *alloc, char **buf, size_t buf_size)
else
buf_size_l = buf_size;
+ if (i == 1) {
+ if (alloc->in_use)
+ instance->cona_status_used += alloc->size;
+ else
+ instance->cona_status_free += alloc->size;
+ }
+
+ if (!alloc->in_use) {
+ instance->cona_status_biggest_free =
+ max((size_t)alloc->size,
+ (size_t)instance->cona_status_biggest_free);
+ }
+
ret = snprintf(*buf, buf_size_l, "paddr: %10x\tsize: %10u\t"
- "in use: %1u\n", alloc->paddr, alloc->size,
- alloc->in_use);
+ "in use: %1u\t used: %10u (%dMB)"
+ " \t free: %10u (%dMB)\n",
+ alloc->paddr,
+ alloc->size,
+ alloc->in_use,
+ instance->cona_status_used,
+ instance->cona_status_used/1024/1024,
+ instance->cona_status_free,
+ instance->cona_status_free/1024/1024);
+
+ if (ret < 0)
+ return -ENOMSG;
+ else if (ret + 1 > buf_size)
+ return -EINVAL;
+ }
+
+ *buf += ret;
+
+ return 0;
+}
+
+static int print_alloc_status(struct instance *instance, char **buf,
+ size_t buf_size)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ size_t buf_size_l;
+ if (i == 0)
+ buf_size_l = 0;
+ else
+ buf_size_l = buf_size;
+
+ ret = snprintf(*buf, buf_size_l, "Overall peak usage:\t%10u "
+ "(%dMB)\nCurrent max usage:\t%10u (%dMB)\n"
+ "Current biggest free:\t%10d (%dMB)\n",
+ instance->cona_status_max_check,
+ instance->cona_status_max_check/1024/1024,
+ instance->cona_status_max_cont,
+ instance->cona_status_max_cont/1024/1024,
+ instance->cona_status_biggest_free,
+ instance->cona_status_biggest_free/1024/1024);
+
if (ret < 0)
return -ENOMSG;
else if (ret + 1 > buf_size)
@@ -385,12 +464,12 @@ static int debugfs_allocs_read(struct file *file, char __user *buf,
/* private_data is intialized to NULL in open which I assume is 0. */
void **curr_pos = &file->private_data;
size_t bytes_read;
+ bool readout_aborted = false;
if (local_buf == NULL)
return -ENOMEM;
mutex_lock(&lock);
-
instance = get_instance_from_file(file);
if (IS_ERR(instance)) {
ret = PTR_ERR(instance);
@@ -403,13 +482,16 @@ static int debugfs_allocs_read(struct file *file, char __user *buf,
if (alloc_offset < (phys_addr_t)*curr_pos)
continue;
- ret = print_alloc(curr_alloc, &local_buf_pos, available_space -
- (size_t)(local_buf_pos - local_buf));
- if (ret == -EINVAL) /* No more room */
+ ret = print_alloc(instance, curr_alloc, &local_buf_pos,
+ available_space - (size_t)(local_buf_pos -
+ local_buf));
+
+ if (ret == -EINVAL) { /* No more room */
+ readout_aborted = true;
break;
- else if (ret < 0)
+ } else if (ret < 0) {
goto out;
-
+ }
/*
* There could be an overflow issue here in the unlikely case
* where the region is placed at the end of the address range
@@ -418,6 +500,28 @@ static int debugfs_allocs_read(struct file *file, char __user *buf,
* defer fixing it till it happens.
*/
*curr_pos = (void *)(alloc_offset + 1);
+
+ /* Make sure to also print status if there were any prints */
+ instance->cona_status_printed = false;
+ }
+
+ if (!readout_aborted && !instance->cona_status_printed) {
+ ret = print_alloc_status(instance, &local_buf_pos,
+ available_space -
+ (size_t)(local_buf_pos - local_buf));
+
+ if (ret == -EINVAL) /* No more room */
+ readout_aborted = true;
+ else if (ret < 0)
+ goto out;
+ else
+ instance->cona_status_printed = true;
+ }
+
+ if (!readout_aborted) {
+ instance->cona_status_free = 0;
+ instance->cona_status_used = 0;
+ instance->cona_status_biggest_free = 0;
}
bytes_read = (size_t)(local_buf_pos - local_buf);
@@ -430,7 +534,6 @@ static int debugfs_allocs_read(struct file *file, char __user *buf,
out:
kfree(local_buf);
-
mutex_unlock(&lock);
return ret;