msm: kgsl: Freeze GPU memory objects to be dumped with the snapshot

In addition to the usual objects in a snapshot (registers, ringbuffer,
IBs, etc), there are a handful of indirect GPU buffer objects that are
created and used during draw operations. These include shaders, buffer
objects, and various state buffers.  Taken together, these buffer
objects can be large, much larger then the snapshot region we have set
aside. Fortunately, these buffers are independent and don't need to be
freed or overwritten when the context is reset.

Long story short we can take these buffers, put them in a list at snapshot
time and mark them so they don't get freed.  Then, when the snapshot is
grabbed dump them into the output stream inline and only then free them.
This allows us to snapshot a larger section of the GPU state without having
to worry about having enough memory set aside.  The only downside is that
some GPU memory will stick around, but we hope that hangs are few and far
between and that some entity will grab the dump soon after the hang so the
memory can be released.

Change-Id: Ic0dedbad0629fa483b077e727d512877bbbf81d6
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 9836043..905a36a 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -27,6 +27,9 @@
 
 #define SNAPSHOT_OBJ_TYPE_IB 0
 
+/* Keep track of how many bytes are frozen after a snapshot and tell the user */
+static int snapshot_frozen_objsize;
+
 static struct kgsl_snapshot_obj {
 	int type;
 	uint32_t gpuaddr;
@@ -354,6 +357,8 @@
 	/* Reset the list of objects */
 	objbufptr = 0;
 
+	snapshot_frozen_objsize = 0;
+
 	/* Get the physical address of the MMU pagetable */
 	ptbase = kgsl_mmu_get_current_ptbase(device);
 
@@ -425,5 +430,9 @@
 		snapshot = adreno_dev->gpudev->snapshot(adreno_dev, snapshot,
 			remain, hang);
 
+	if (snapshot_frozen_objsize)
+		KGSL_DRV_ERR(device, "GPU snapshot froze %dKb of GPU buffers\n",
+			snapshot_frozen_objsize / 1024);
+
 	return snapshot;
 }