rk: ion: Add ion snapshot function for debug
authorCMY <cmy@rock-chips.com>
Mon, 14 Apr 2014 02:10:29 +0000 (10:10 +0800)
committerCMY <cmy@rock-chips.com>
Mon, 14 Apr 2014 02:14:43 +0000 (10:14 +0800)
  currently supported features: buffer allocation failure in time to
  save the current ion each heap and client status, etc.

drivers/staging/android/ion/ion.c
drivers/staging/android/ion/ion_cma_heap.c
drivers/staging/android/ion/ion_priv.h
drivers/staging/android/ion/ion_system_heap.c

index 885cb60530bf7dad1b8c5c24a4368b9e88029b74..72d8b337696b62d67239762605148584de291033 100755 (executable)
@@ -2022,3 +2022,59 @@ void __init ion_reserve(struct ion_platform_data *data)
                        data->heaps[i].size);
        }
 }
+
+#define ION_SNAPSHOT_BUFFER_LEN                1<<18
+int ion_snapshot_save(struct ion_device *idev)
+{
+       static struct seq_file seqf;
+       struct ion_heap *heap;
+       struct rb_node *n;
+
+       if (!seqf.buf) {
+               seqf.size = ION_SNAPSHOT_BUFFER_LEN;
+               seqf.buf = kmalloc(seqf.size, GFP_KERNEL);
+               if (!seqf.buf)
+                       return -ENOMEM;
+               printk("%s: create snapshot 0x%x@0x%lx\n", __func__, seqf.size,
+                       __pa(seqf.buf));
+       } else {
+               printk("%s: save snapshot 0x%x@0x%lx\n", __func__, seqf.size,
+                       __pa(seqf.buf));
+               memset(seqf.buf, 0, seqf.size);
+               seqf.count = 0;
+       }
+
+       down_read(&idev->lock);
+
+       plist_for_each_entry(heap, &idev->heaps, node) {
+               seqf.private = (void*)heap;
+               seq_printf(&seqf, "++++++++++++++++ HEAP: %s ++++++++++++++++\n",
+                       heap->name);
+               ion_debug_heap_show(&seqf, NULL);
+               seq_printf(&seqf, "\n");
+               if (ION_HEAP_TYPE_DMA==heap->type)
+                       ion_cma_heap_debug_show(&seqf, NULL);
+       }
+
+       for (n = rb_first(&idev->clients); n; n = rb_next(n)) {
+               struct ion_client *client = rb_entry(n, struct ion_client, node);
+               seqf.private = (void*)client;
+               if (client->task) {
+                       char task_comm[TASK_COMM_LEN];
+
+                       get_task_comm(task_comm, client->task);
+                       seq_printf(&seqf, "++++++++++++++++ CLIENT: %s(PID-%d) ++++++++++++++++\n",
+                               task_comm, client->pid);
+               } else {
+                       seq_printf(&seqf, "++++++++++++++++ CLIENT: %s(PID-%d) ++++++++++++++++\n",
+                               client->display_name, client->pid);
+               }
+
+               ion_debug_client_show(&seqf, NULL);
+               seq_printf(&seqf, "\n");
+       }
+
+       up_read(&idev->lock);
+
+       return 0;
+}
index 6cae791d881c8aae48b83a4da71b39b93739d9c7..e70869e3172de589b9f7d2e7078cb41730b690e7 100755 (executable)
@@ -120,6 +120,7 @@ free_mem:
        dma_free_coherent(dev, len, info->cpu_addr, info->handle);
 err:
        kfree(info);
+       ion_snapshot_save(heap->dev);
        return ION_CMA_ALLOCATE_FAILED;
 }
 
index cb00d1b2e02c61a20a8ff8fadd578bada3bf8eee..e7a4ec92322130e8a60f6b5eec9efe52750fc147 100755 (executable)
@@ -436,4 +436,6 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
 void ion_pages_sync_for_device(struct device *dev, struct page *page,
                size_t size, enum dma_data_direction dir);
 
+int ion_snapshot_save(struct ion_device *idev);
+
 #endif /* _ION_PRIV_H */
index e61993d3c2c4079cb5e437588cc16cc46e36ed1d..5dccc34ecc3a29ec3668c33707af878dd32fd2ae 100755 (executable)
@@ -193,6 +193,7 @@ err:
                free_buffer_page(sys_heap, buffer, info->page, info->order);
                kfree(info);
        }
+       ion_snapshot_save(heap->dev);
        return -ENOMEM;
 }