ion: tracing: add ftrace events for ion allocations
Add ftrace events for ion allocations to make it easier to profile
their performance.
Change-Id: I9f32e076cd50d7d3a145353dfcef74f0f6cdf8a0
Signed-off-by: Liam Mark <lmark@codeaurora.org>
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 78efb03..81409b0 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -31,6 +31,7 @@
#include <linux/swap.h>
#include <linux/mm_types.h>
#include <linux/dma-contiguous.h>
+#include <trace/events/kmem.h>
#ifndef SZ_1M
#define SZ_1M (1 << 20)
@@ -316,6 +317,7 @@
unsigned long mask, pfn, pageno, start = 0;
struct cma *cma = dev_get_cma_area(dev);
int ret;
+ int tries = 0;
if (!cma || !cma->count)
return NULL;
@@ -349,6 +351,9 @@
} else if (ret != -EBUSY) {
goto error;
}
+ tries++;
+ trace_dma_alloc_contiguous_retry(tries);
+
pr_debug("%s(): memory range at %p is busy, retrying\n",
__func__, pfn_to_page(pfn));
/* try again with a bit different memory target */
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index e9b3bb3..f7a94e3 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -2,7 +2,7 @@
* drivers/gpu/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -34,6 +34,8 @@
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
#include <linux/msm_ion.h>
+#include <trace/events/kmem.h>
+
#include <mach/iommu_domains.h>
#include "ion_priv.h"
@@ -433,9 +435,16 @@
if (secure_allocation &&
(heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP))
continue;
+ trace_ion_alloc_buffer_start(client->name, heap->name, len,
+ heap_mask, flags);
buffer = ion_buffer_create(heap, dev, len, align, flags);
+ trace_ion_alloc_buffer_end(client->name, heap->name, len,
+ heap_mask, flags);
if (!IS_ERR_OR_NULL(buffer))
break;
+
+ trace_ion_alloc_buffer_fallback(client->name, heap->name, len,
+ heap_mask, flags, PTR_ERR(buffer));
if (dbg_str_idx < MAX_DBG_STR_LEN) {
unsigned int len_left = MAX_DBG_STR_LEN-dbg_str_idx-1;
int ret_value = snprintf(&dbg_str[dbg_str_idx],
@@ -454,10 +463,15 @@
}
mutex_unlock(&dev->lock);
- if (buffer == NULL)
+ if (buffer == NULL) {
+ trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
+ heap_mask, flags, -ENODEV);
return ERR_PTR(-ENODEV);
+ }
if (IS_ERR(buffer)) {
+ trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
+ heap_mask, flags, PTR_ERR(buffer));
pr_debug("ION is unable to allocate 0x%x bytes (alignment: "
"0x%x) from heap(s) %sfor client %s with heap "
"mask 0x%x\n",
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index ea0ec41..d5761d4 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -28,6 +28,7 @@
#include <linux/fmem.h>
#include <linux/iommu.h>
#include <linux/dma-mapping.h>
+#include <trace/events/kmem.h>
#include <asm/mach/map.h>
@@ -141,8 +142,10 @@
&(cp_heap->handle),
0,
&attrs);
- if (!cp_heap->cpu_addr)
+ if (!cp_heap->cpu_addr) {
+ trace_ion_cp_alloc_retry(tries);
msleep(20);
+ }
}
if (!cp_heap->cpu_addr)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 08fa272..18485c3 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -302,6 +302,199 @@
__entry->alloc_migratetype == __entry->fallback_migratetype)
);
+
+DECLARE_EVENT_CLASS(ion_alloc,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags),
+
+ TP_STRUCT__entry(
+ __field(const char *, client_name)
+ __field(const char *, heap_name)
+ __field(size_t, len)
+ __field(unsigned int, mask)
+ __field(unsigned int, flags)
+ ),
+
+ TP_fast_assign(
+ __entry->client_name = client_name;
+ __entry->heap_name = heap_name;
+ __entry->len = len;
+ __entry->mask = mask;
+ __entry->flags = flags;
+ ),
+
+ TP_printk("client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x",
+ __entry->client_name,
+ __entry->heap_name,
+ __entry->len,
+ __entry->mask,
+ __entry->flags)
+);
+
+DEFINE_EVENT(ion_alloc, ion_alloc_buffer_start,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags)
+);
+
+DEFINE_EVENT(ion_alloc, ion_alloc_buffer_end,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags)
+);
+
+DECLARE_EVENT_CLASS(ion_alloc_error,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags,
+ long error),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags, error),
+
+ TP_STRUCT__entry(
+ __field(const char *, client_name)
+ __field(const char *, heap_name)
+ __field(size_t, len)
+ __field(unsigned int, mask)
+ __field(unsigned int, flags)
+ __field(long, error)
+ ),
+
+ TP_fast_assign(
+ __entry->client_name = client_name;
+ __entry->heap_name = heap_name;
+ __entry->len = len;
+ __entry->mask = mask;
+ __entry->flags = flags;
+ __entry->error = error;
+ ),
+
+ TP_printk(
+ "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x error=%ld",
+ __entry->client_name,
+ __entry->heap_name,
+ __entry->len,
+ __entry->mask,
+ __entry->flags,
+ __entry->error)
+);
+
+
+DEFINE_EVENT(ion_alloc_error, ion_alloc_buffer_fallback,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags,
+ long error),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags, error)
+);
+
+DEFINE_EVENT(ion_alloc_error, ion_alloc_buffer_fail,
+
+ TP_PROTO(const char *client_name,
+ const char *heap_name,
+ size_t len,
+ unsigned int mask,
+ unsigned int flags,
+ long error),
+
+ TP_ARGS(client_name, heap_name, len, mask, flags, error)
+);
+
+
+DECLARE_EVENT_CLASS(alloc_retry,
+
+ TP_PROTO(int tries),
+
+ TP_ARGS(tries),
+
+ TP_STRUCT__entry(
+ __field(int, tries)
+ ),
+
+ TP_fast_assign(
+ __entry->tries = tries;
+ ),
+
+ TP_printk("tries=%d",
+ __entry->tries)
+);
+
+DEFINE_EVENT(alloc_retry, ion_cp_alloc_retry,
+
+ TP_PROTO(int tries),
+
+ TP_ARGS(tries)
+);
+
+DEFINE_EVENT(alloc_retry, migrate_retry,
+
+ TP_PROTO(int tries),
+
+ TP_ARGS(tries)
+);
+
+DEFINE_EVENT(alloc_retry, dma_alloc_contiguous_retry,
+
+ TP_PROTO(int tries),
+
+ TP_ARGS(tries)
+);
+
+DECLARE_EVENT_CLASS(migrate_pages,
+
+ TP_PROTO(int mode),
+
+ TP_ARGS(mode),
+
+ TP_STRUCT__entry(
+ __field(int, mode)
+ ),
+
+ TP_fast_assign(
+ __entry->mode = mode;
+ ),
+
+ TP_printk("mode=%d",
+ __entry->mode)
+);
+
+DEFINE_EVENT(migrate_pages, migrate_pages_start,
+
+ TP_PROTO(int mode),
+
+ TP_ARGS(mode)
+);
+
+DEFINE_EVENT(migrate_pages, migrate_pages_end,
+
+ TP_PROTO(int mode),
+
+ TP_ARGS(mode)
+);
+
#endif /* _TRACE_KMEM_H */
/* This part must be outside protection */
diff --git a/mm/migrate.c b/mm/migrate.c
index ee026af..99ff32a 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -34,6 +34,7 @@
#include <linux/syscalls.h>
#include <linux/hugetlb.h>
#include <linux/gfp.h>
+#include <trace/events/kmem.h>
#include <asm/tlbflush.h>
@@ -988,6 +989,7 @@
int swapwrite = current->flags & PF_SWAPWRITE;
int rc;
+ trace_migrate_pages_start(mode);
if (!swapwrite)
current->flags |= PF_SWAPWRITE;
@@ -1006,6 +1008,7 @@
goto out;
case -EAGAIN:
retry++;
+ trace_migrate_retry(retry);
break;
case 0:
nr_succeeded++;
@@ -1026,6 +1029,7 @@
if (!swapwrite)
current->flags &= ~PF_SWAPWRITE;
+ trace_migrate_pages_end(mode);
if (rc)
return rc;