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 <ilkos@google.com>
This commit is contained in:
Ioannis Ilkos 2020-04-17 16:31:00 +01:00
parent ab51ca10ee
commit 15207c2985
4 changed files with 75 additions and 2 deletions

View File

@ -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

View File

@ -29,6 +29,8 @@
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#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);

View File

@ -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 <linux/tracepoint.h>
#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 <trace/define_trace.h>

View File

@ -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)