forked from rubenslte/android_kernel_samsung_msm8226
Merge "ocmem: Add debugfs node to track latency for ocmem"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
c6771fce69
@@ -85,6 +85,12 @@ struct ocmem_zone {
|
||||
atomic_long_t z_stat[NR_OCMEM_ZSTAT_ITEMS];
|
||||
struct gen_pool *z_pool;
|
||||
struct ocmem_zone_ops *z_ops;
|
||||
unsigned int max_alloc_time;
|
||||
unsigned int min_alloc_time;
|
||||
u64 total_alloc_time;
|
||||
unsigned int max_free_time;
|
||||
unsigned int min_free_time;
|
||||
u64 total_free_time;
|
||||
};
|
||||
|
||||
enum op_code {
|
||||
|
||||
@@ -587,6 +587,34 @@ static const struct file_operations stats_show_fops = {
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int ocmem_timing_show(struct seq_file *f, void *dummy)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (i = OCMEM_GRAPHICS; i < OCMEM_CLIENT_MAX; i++) {
|
||||
struct ocmem_zone *z = get_zone(i);
|
||||
if (z && z->active == true)
|
||||
seq_printf(f, "zone %s\t: alloc_delay:[max:%d, min:%d, total:%llu,cnt:%lu] free_delay:[max:%d, min:%d, total:%llu, cnt:%lu]\n",
|
||||
get_name(z->owner), z->max_alloc_time,
|
||||
z->min_alloc_time, z->total_alloc_time,
|
||||
get_ocmem_stat(z, 1), z->max_free_time,
|
||||
z->min_free_time, z->total_free_time,
|
||||
get_ocmem_stat(z, 6));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocmem_timing_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, ocmem_timing_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations timing_show_fops = {
|
||||
.open = ocmem_timing_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int ocmem_zone_init(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
@@ -656,6 +684,13 @@ static int ocmem_zone_init(struct platform_device *pdev)
|
||||
zone->max_regions = 0;
|
||||
INIT_LIST_HEAD(&zone->req_list);
|
||||
zone->z_ops = z_ops;
|
||||
zone->max_alloc_time = 0;
|
||||
zone->min_alloc_time = 0xFFFFFFFF;
|
||||
zone->total_alloc_time = 0;
|
||||
zone->max_free_time = 0;
|
||||
zone->min_free_time = 0xFFFFFFFF;
|
||||
zone->total_free_time = 0;
|
||||
|
||||
if (part->p_tail) {
|
||||
z_ops->allocate = allocate_tail;
|
||||
z_ops->free = free_tail;
|
||||
@@ -688,6 +723,12 @@ static int ocmem_zone_init(struct platform_device *pdev)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("timing", S_IRUGO, pdata->debug_node,
|
||||
NULL, &timing_show_fops)) {
|
||||
dev_err(dev, "Unable to create debugfs node for timing\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Total active zones = %d\n", active_zones);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,11 @@ struct ocmem_buf *ocmem_allocate(int client_id, unsigned long size)
|
||||
{
|
||||
bool can_block = false;
|
||||
bool can_wait = true;
|
||||
struct ocmem_buf *buffer;
|
||||
struct timeval start_time;
|
||||
struct timeval end_time;
|
||||
unsigned int delay;
|
||||
struct ocmem_zone *zone;
|
||||
|
||||
if (!check_id(client_id)) {
|
||||
pr_err("ocmem: Invalid client id: %d\n", client_id);
|
||||
@@ -129,8 +134,33 @@ struct ocmem_buf *ocmem_allocate(int client_id, unsigned long size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return __ocmem_allocate_range(client_id, size, size,
|
||||
zone = get_zone(client_id);
|
||||
if (!zone) {
|
||||
pr_err("ocmem: Zone not found for client %d\n", client_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do_gettimeofday(&start_time);
|
||||
|
||||
buffer = __ocmem_allocate_range(client_id, size, size,
|
||||
size, can_block, can_wait);
|
||||
|
||||
do_gettimeofday(&end_time);
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
delay = (end_time.tv_sec * USEC_PER_SEC + end_time.tv_usec)
|
||||
- (start_time.tv_sec * USEC_PER_SEC + start_time.tv_usec);
|
||||
|
||||
if (delay > zone->max_alloc_time)
|
||||
zone->max_alloc_time = delay;
|
||||
if (delay < zone->min_alloc_time)
|
||||
zone->min_alloc_time = delay;
|
||||
zone->total_alloc_time += delay;
|
||||
inc_ocmem_stat(zone, NR_SYNC_ALLOCATIONS);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
EXPORT_SYMBOL(ocmem_allocate);
|
||||
|
||||
@@ -250,6 +280,12 @@ EXPORT_SYMBOL(ocmem_allocate_nb);
|
||||
|
||||
int ocmem_free(int client_id, struct ocmem_buf *buffer)
|
||||
{
|
||||
int rc;
|
||||
struct timeval start_time;
|
||||
struct timeval end_time;
|
||||
unsigned int delay;
|
||||
struct ocmem_zone *zone;
|
||||
|
||||
if (!check_id(client_id)) {
|
||||
pr_err("ocmem: Invalid client id: %d\n", client_id);
|
||||
return -EINVAL;
|
||||
@@ -261,12 +297,38 @@ int ocmem_free(int client_id, struct ocmem_buf *buffer)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
zone = get_zone(client_id);
|
||||
if (!zone) {
|
||||
pr_err("ocmem: Zone not found for client %d\n", client_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!buffer) {
|
||||
pr_err("ocmem: Invalid buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return __ocmem_free(client_id, buffer);
|
||||
do_gettimeofday(&start_time);
|
||||
|
||||
rc = __ocmem_free(client_id, buffer);
|
||||
|
||||
do_gettimeofday(&end_time);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
delay = (end_time.tv_sec * USEC_PER_SEC + end_time.tv_usec)
|
||||
- (start_time.tv_sec * USEC_PER_SEC + start_time.tv_usec);
|
||||
|
||||
if (delay > zone->max_free_time)
|
||||
zone->max_free_time = delay;
|
||||
if (delay < zone->min_free_time)
|
||||
zone->min_free_time = delay;
|
||||
zone->total_free_time += delay;
|
||||
inc_ocmem_stat(zone, NR_FREES);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(ocmem_free);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user