From 15207c298585b5885136a9ef93453e808ba9ffb8 Mon Sep 17 00:00:00 2001 From: Ioannis Ilkos Date: Fri, 17 Apr 2020 16:31:00 +0100 Subject: [PATCH] ANDROID: add ion_stat tracepoint to common kernel Emitted an event whenever ion buffers are created or freed. This enables tracking ion memory utilization changes, as well as individual buffer allocations. This was inspired by the pixel kernel patches by timmurray@ and carmenjackson@. Test: manual test on cuttlefish Bug: 154302786 Change-Id: I4d4b23ae4dbda5012d3582f5564a87e0d08c68c7 Signed-off-by: Ioannis Ilkos --- drivers/staging/android/ion/Makefile | 1 + drivers/staging/android/ion/ion.c | 20 ++++++++- drivers/staging/android/ion/ion_trace.h | 55 +++++++++++++++++++++++++ lib/vsprintf.c | 1 + 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 drivers/staging/android/ion/ion_trace.h diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index 22818c0fa4b2..e99ebb86a715 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ION) += ion-alloc.o +CFLAGS_ion.o = -I$(src) ion-alloc-objs += ion.o ion-ioctl.o ion_heap.o ion-alloc-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o ion-alloc-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 49bf964b2879..5692828dd23d 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -29,6 +29,8 @@ #include #include +#define CREATE_TRACE_POINTS +#include "ion_trace.h" #include "ion.h" static struct ion_device *internal_dev; @@ -61,6 +63,20 @@ static void ion_buffer_add(struct ion_device *dev, rb_insert_color(&buffer->node, &dev->buffers); } +static void track_buffer_created(struct ion_buffer *buffer) +{ + long total = atomic_long_add_return(buffer->size, &total_heap_bytes); + + trace_ion_stat(buffer->sg_table, buffer->size, total); +} + +static void track_buffer_destroyed(struct ion_buffer *buffer) +{ + long total = atomic_long_sub_return(buffer->size, &total_heap_bytes); + + trace_ion_stat(buffer->sg_table, -buffer->size, total); +} + /* this function should only be called while dev->lock is held */ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, struct ion_device *dev, @@ -102,7 +118,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, mutex_lock(&dev->buffer_lock); ion_buffer_add(dev, buffer); mutex_unlock(&dev->buffer_lock); - atomic_long_add(len, &total_heap_bytes); + track_buffer_created(buffer); return buffer; err1: @@ -131,7 +147,7 @@ static void _ion_buffer_destroy(struct ion_buffer *buffer) mutex_lock(&dev->buffer_lock); rb_erase(&buffer->node, &dev->buffers); mutex_unlock(&dev->buffer_lock); - atomic_long_sub(buffer->size, &total_heap_bytes); + track_buffer_destroyed(buffer); if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ion_heap_freelist_add(heap, buffer); diff --git a/drivers/staging/android/ion/ion_trace.h b/drivers/staging/android/ion/ion_trace.h new file mode 100644 index 000000000000..8233691a73eb --- /dev/null +++ b/drivers/staging/android/ion/ion_trace.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * drivers/staging/android/ion/ion-trace.h + * + * Copyright (C) 2020 Google, Inc. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ion + +#if !defined(_ION_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _ION_TRACE_H + +#include + +#ifndef __ION_PTR_TO_HASHVAL +static unsigned int __ion_ptr_to_hash(const void *ptr) +{ + unsigned long hashval; + + if (ptr_to_hashval(ptr, &hashval)) + return 0; + + /* The hashed value is only 32-bit */ + return (unsigned int)hashval; +} + +#define __ION_PTR_TO_HASHVAL +#endif + +TRACE_EVENT(ion_stat, + TP_PROTO(const void *addr, long len, + unsigned long total_allocated), + TP_ARGS(addr, len, total_allocated), + TP_STRUCT__entry(__field(unsigned int, buffer_id) + __field(long, len) + __field(unsigned long, total_allocated) + ), + TP_fast_assign(__entry->buffer_id = __ion_ptr_to_hash(addr); + __entry->len = len; + __entry->total_allocated = total_allocated; + ), + TP_printk("buffer_id=%u len=%ldB total_allocated=%ldB", + __entry->buffer_id, + __entry->len, + __entry->total_allocated) + ); + +#endif /* _ION_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE ion_trace +#include diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 630d42636dcf..c826ebaa6563 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1733,6 +1733,7 @@ int ptr_to_hashval(const void *ptr, unsigned long *hashval_out) { return __ptr_to_hashval(ptr, hashval_out); } +EXPORT_SYMBOL_GPL(ptr_to_hashval); /* Maps a pointer to a 32 bit unique identifier. */ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)