gpu: ion: Add better debugfs information

In debugfs, clients now show individual allocations.
Carveout heaps now give the number of bytes currently
allocated out of total possible bytes. The system heaps
just show the number of bytes currently allocated.

Change-Id: I4acfcdc1089c73c28041e09cb6b5a03b956e936a
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index c37d952..930ba83 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -688,29 +688,25 @@
 {
 	struct ion_client *client = s->private;
 	struct rb_node *n;
-	size_t sizes[ION_NUM_HEAPS] = {0};
-	const char *names[ION_NUM_HEAPS] = {0};
-	int i;
 
+	seq_printf(s, "%16.16s: %16.16s : %16.16s : %16.16s\n", "heap_name",
+			"size_in_bytes", "handle refcount", "buffer");
 	mutex_lock(&client->lock);
 	for (n = rb_first(&client->handles); n; n = rb_next(n)) {
 		struct ion_handle *handle = rb_entry(n, struct ion_handle,
 						     node);
-		enum ion_heap_type type = handle->buffer->heap->type;
 
-		if (!names[type])
-			names[type] = handle->buffer->heap->name;
-		sizes[type] += handle->buffer->size;
+		seq_printf(s, "%16.16s: %16u : %16d : %16p\n",
+				handle->buffer->heap->name,
+				handle->buffer->size,
+				atomic_read(&handle->ref.refcount),
+				handle->buffer);
 	}
+
+	seq_printf(s, "%16.16s %d\n", "client refcount:",
+			atomic_read(&client->ref.refcount));
 	mutex_unlock(&client->lock);
 
-	seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes");
-	for (i = 0; i < ION_NUM_HEAPS; i++) {
-		if (!names[i])
-			continue;
-		seq_printf(s, "%16.16s: %16u %d\n", names[i], sizes[i],
-			   atomic_read(&client->ref.refcount));
-	}
 	return 0;
 }
 
@@ -1247,6 +1243,14 @@
 		seq_printf(s, "%16.s %16u %16u\n", client->name, client->pid,
 			   size);
 	}
+	if (heap->ops->get_allocated) {
+		seq_printf(s, "total bytes currently allocated: %lx\n",
+			heap->ops->get_allocated(heap));
+	}
+	if (heap->ops->get_total) {
+		seq_printf(s, "total heap size: %lx\n",
+			heap->ops->get_total(heap));
+	}
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 86d4c8e..a572ca8 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -31,6 +31,8 @@
 	struct ion_heap heap;
 	struct gen_pool *pool;
 	ion_phys_addr_t base;
+	unsigned long allocated_bytes;
+	unsigned long total_size;
 };
 
 ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
@@ -45,6 +47,7 @@
 	if (!offset)
 		return ION_CARVEOUT_ALLOCATE_FAIL;
 
+	carveout_heap->allocated_bytes += size;
 	return offset;
 }
 
@@ -57,6 +60,7 @@
 	if (addr == ION_CARVEOUT_ALLOCATE_FAIL)
 		return;
 	gen_pool_free(carveout_heap->pool, addr, size);
+	carveout_heap->allocated_bytes -= size;
 }
 
 static int ion_carveout_heap_phys(struct ion_heap *heap,
@@ -156,6 +160,22 @@
 	return 0;
 }
 
+static unsigned long ion_carveout_get_allocated(struct ion_heap *heap)
+{
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
+	return carveout_heap->allocated_bytes;
+}
+
+static unsigned long ion_carveout_get_total(struct ion_heap *heap)
+{
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
+	return carveout_heap->total_size;
+}
+
 static struct ion_heap_ops carveout_heap_ops = {
 	.allocate = ion_carveout_heap_allocate,
 	.free = ion_carveout_heap_free,
@@ -164,6 +184,8 @@
 	.map_kernel = ion_carveout_heap_map_kernel,
 	.unmap_kernel = ion_carveout_heap_unmap_kernel,
 	.cache_op = ion_carveout_cache_ops,
+	.get_allocated = ion_carveout_get_allocated,
+	.get_total = ion_carveout_get_total,
 };
 
 struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
@@ -189,6 +211,8 @@
 	}
 	carveout_heap->heap.ops = &carveout_heap_ops;
 	carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT;
+	carveout_heap->allocated_bytes = 0;
+	carveout_heap->total_size = heap_data->size;
 
 	return &carveout_heap->heap;
 }
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index fd5c125..10e2219 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -104,6 +104,8 @@
 	int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
 			void *vaddr, unsigned int offset,
 			unsigned int length, unsigned int cmd);
+	unsigned long (*get_allocated)(struct ion_heap *heap);
+	unsigned long (*get_total)(struct ion_heap *heap);
 };
 
 /**
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 5609b72..b26d48c 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -23,6 +23,9 @@
 #include "ion_priv.h"
 #include <mach/memory.h>
 
+static atomic_t system_heap_allocated;
+static atomic_t system_contig_heap_allocated;
+
 static int ion_system_heap_allocate(struct ion_heap *heap,
 				     struct ion_buffer *buffer,
 				     unsigned long size, unsigned long align,
@@ -31,12 +34,15 @@
 	buffer->priv_virt = vmalloc_user(size);
 	if (!buffer->priv_virt)
 		return -ENOMEM;
+
+	atomic_add(size, &system_heap_allocated);
 	return 0;
 }
 
 void ion_system_heap_free(struct ion_buffer *buffer)
 {
 	vfree(buffer->priv_virt);
+	atomic_sub(buffer->size, &system_heap_allocated);
 }
 
 struct scatterlist *ion_system_heap_map_dma(struct ion_heap *heap,
@@ -149,6 +155,11 @@
 	return 0;
 }
 
+static unsigned long ion_system_heap_get_allocated(struct ion_heap *heap)
+{
+	return atomic_read(&system_heap_allocated);
+}
+
 static struct ion_heap_ops vmalloc_ops = {
 	.allocate = ion_system_heap_allocate,
 	.free = ion_system_heap_free,
@@ -158,6 +169,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_heap_map_user,
 	.cache_op = ion_system_heap_cache_ops,
+	.get_allocated = ion_system_heap_get_allocated,
 };
 
 struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
@@ -186,12 +198,14 @@
 	buffer->priv_virt = kzalloc(len, GFP_KERNEL);
 	if (!buffer->priv_virt)
 		return -ENOMEM;
+	atomic_add(len, &system_contig_heap_allocated);
 	return 0;
 }
 
 void ion_system_contig_heap_free(struct ion_buffer *buffer)
 {
 	kfree(buffer->priv_virt);
+	atomic_sub(buffer->size, &system_contig_heap_allocated);
 }
 
 static int ion_system_contig_heap_phys(struct ion_heap *heap,
@@ -266,6 +280,11 @@
 	return 0;
 }
 
+static unsigned long ion_system_contig_heap_get_allocated(struct ion_heap *heap)
+{
+	return atomic_read(&system_contig_heap_allocated);
+}
+
 static struct ion_heap_ops kmalloc_ops = {
 	.allocate = ion_system_contig_heap_allocate,
 	.free = ion_system_contig_heap_free,
@@ -276,6 +295,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_contig_heap_map_user,
 	.cache_op = ion_system_contig_heap_cache_ops,
+	.get_allocated = ion_system_contig_heap_get_allocated,
 };
 
 struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)