media_module: Add a function to acquire of the statistics decoding time: [1/1]

PD#SWPL-3057

Problem:
We need to acquire statistics of the decoding time.

Solution:
Add a function to acquire statistics of the decoding time.

Verify:
Verified u212

Change-Id: Ibcd898b36944c5ae1f6ca3cbeecadd78e8578a9a
Signed-off-by: Peng Yixin <yixin.peng@amlogic.com>
This commit is contained in:
Peng Yixin
2018-09-24 12:54:00 +08:00
committed by Dongjin Kim
parent 0755e30a17
commit df7f38c8bc

View File

@@ -19,6 +19,8 @@
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/debugfs.h>
#include <linux/moduleparam.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "vdec_profile.h"
@@ -32,9 +34,40 @@
static DEFINE_MUTEX(vdec_profile_mutex);
static int rec_wp;
static bool rec_wrapped;
static uint dec_time_stat_flag;
static uint dec_time_stat_reset;
struct dentry *root, *event;
#define MAX_INSTANCE_MUN 9
struct vdec_profile_time_stat_s {
int time_6ms_less_cnt;
int time_6_9ms_cnt;
int time_9_12ms_cnt;
int time_12_15ms_cnt;
int time_15_18ms_cnt;
int time_18_21ms_cnt;
int time_21ms_up_cnt;
u64 time_max_us;
u64 time_total_us;
};
struct vdec_profile_statistics_s {
bool status;
u64 run_lasttimestamp;
int run_cnt;
u64 cb_lasttimestamp;
int cb_cnt;
u64 decode_first_us;
struct vdec_profile_time_stat_s run2cb_time_stat;
struct vdec_profile_time_stat_s decode_time_stat;
};
static struct vdec_profile_statistics_s statistics_s[MAX_INSTANCE_MUN];
struct vdec_profile_rec_s {
struct vdec_s *vdec;
u64 timestamp;
@@ -84,6 +117,90 @@ static u64 get_us_time_system(void)
return div64_u64(timeval_to_ns(&tv), 1000);
}
static void vdec_profile_update_alloc_time(
struct vdec_profile_time_stat_s *time_stat, u64 startus, u64 endus)
{
u64 spend_time_us = endus - startus;
if (spend_time_us > 0 && spend_time_us < 100000000) {
if (spend_time_us < 6000)
time_stat->time_6ms_less_cnt++;
else if (spend_time_us < 9000)
time_stat->time_6_9ms_cnt++;
else if (spend_time_us < 12000)
time_stat->time_9_12ms_cnt++;
else if (spend_time_us < 15000)
time_stat->time_12_15ms_cnt++;
else if (spend_time_us < 18000)
time_stat->time_15_18ms_cnt++;
else if (spend_time_us < 21000)
time_stat->time_18_21ms_cnt++;
else
time_stat->time_21ms_up_cnt++;
}
if (spend_time_us > time_stat->time_max_us)
time_stat->time_max_us = spend_time_us;
time_stat->time_total_us += spend_time_us;
}
static void vdec_profile_statistics(struct vdec_s *vdec, int event)
{
struct vdec_profile_statistics_s *time_stat = NULL;
u64 timestamp;
int i;
if (vdec->id >= MAX_INSTANCE_MUN)
return;
if (event != VDEC_PROFILE_EVENT_RUN &&
event != VDEC_PROFILE_EVENT_CB)
return;
mutex_lock(&vdec_profile_mutex);
if (dec_time_stat_reset == 1) {
if (event != VDEC_PROFILE_EVENT_RUN) {
mutex_unlock(&vdec_profile_mutex);
return;
}
for (i = 0; i < MAX_INSTANCE_MUN; i++)
memset(&statistics_s[i], 0,
sizeof(struct vdec_profile_statistics_s));
dec_time_stat_reset = 0;
}
time_stat = &statistics_s[vdec->id];
timestamp = get_us_time_system();
if (time_stat->status == false) {
time_stat->decode_first_us = timestamp;
time_stat->status = true;
}
if (event == VDEC_PROFILE_EVENT_RUN) {
time_stat->run_lasttimestamp = timestamp;
time_stat->run_cnt++;
} else if (event == VDEC_PROFILE_EVENT_CB) {
/*run2cb statistics*/
vdec_profile_update_alloc_time(&time_stat->run2cb_time_stat, time_stat->run_lasttimestamp, timestamp);
/*decode statistics*/
if (time_stat->cb_cnt == 0)
vdec_profile_update_alloc_time(&time_stat->decode_time_stat, time_stat->decode_first_us, timestamp);
else
vdec_profile_update_alloc_time(&time_stat->decode_time_stat, time_stat->cb_lasttimestamp, timestamp);
time_stat->cb_lasttimestamp = timestamp;
time_stat->cb_cnt++;
}
mutex_unlock(&vdec_profile_mutex);
}
void vdec_profile_more(struct vdec_s *vdec, int event, int para1, int para2)
{
mutex_lock(&vdec_profile_mutex);
@@ -107,6 +224,8 @@ EXPORT_SYMBOL(vdec_profile_more);
void vdec_profile(struct vdec_s *vdec, int event)
{
vdec_profile_more(vdec, event, 0 , 0);
if (dec_time_stat_flag == 1)
vdec_profile_statistics(vdec, event);
}
EXPORT_SYMBOL(vdec_profile);
@@ -114,6 +233,9 @@ void vdec_profile_flush(struct vdec_s *vdec)
{
int i;
if (vdec->id >= MAX_INSTANCE_MUN)
return;
mutex_lock(&vdec_profile_mutex);
for (i = 0; i < PROFILE_REC_SIZE; i++) {
@@ -121,6 +243,8 @@ void vdec_profile_flush(struct vdec_s *vdec)
recs[i].vdec = NULL;
}
memset(&statistics_s[vdec->id], 0, sizeof(struct vdec_profile_statistics_s));
mutex_unlock(&vdec_profile_mutex);
}
@@ -183,11 +307,84 @@ static int vdec_profile_dbg_show(struct seq_file *m, void *v)
return 0;
}
static int time_stat_profile_dbg_show(struct seq_file *m, void *v)
{
int i;
mutex_lock(&vdec_profile_mutex);
for (i = 0; i < MAX_INSTANCE_MUN; i++)
{
if (statistics_s[i].status == false)
continue;
seq_printf(m, "[%d]run_cnt:%d, cb_cnt:%d\n\
\t\t\ttime_total_us:%llu\n\
\t\t\trun2cb time:\n\
\t\t\ttime_max_us:%llu\n\
\t\t\t[%d]run2cb ave_us:%llu\n\
\t\t\ttime_6ms_less_cnt:%d\n\
\t\t\ttime_6_9ms_cnt:%d\n\
\t\t\ttime_9_12ms_cnt:%d\n\
\t\t\ttime_12_15ms_cnt:%d\n\
\t\t\ttime_15_18ms_cnt:%d\n\
\t\t\ttime_18_21ms_cnt:%d\n\
\t\t\ttime_21ms_up_cnt:%d\n\
\t\t\tdecode time:\n\
\t\t\ttime_total_us:%llu\n\
\t\t\ttime_max_us:%llu\n\
\t\t\t[%d]cb2cb ave_us:%llu\n\
\t\t\ttime_6ms_less_cnt:%d\n\
\t\t\ttime_6_9ms_cnt:%d\n\
\t\t\ttime_9_12ms_cnt:%d\n\
\t\t\ttime_12_15ms_cnt:%d\n\
\t\t\ttime_15_18ms_cnt:%d\n\
\t\t\ttime_18_21ms_cnt:%d\n\
\t\t\ttime_21ms_up_cnt:%d\n",
i,
statistics_s[i].run_cnt,
statistics_s[i].cb_cnt,
statistics_s[i].run2cb_time_stat.time_total_us,
statistics_s[i].run2cb_time_stat.time_max_us,
i,
div_u64(statistics_s[i].run2cb_time_stat.time_total_us , statistics_s[i].cb_cnt),
statistics_s[i].run2cb_time_stat.time_6ms_less_cnt,
statistics_s[i].run2cb_time_stat.time_6_9ms_cnt,
statistics_s[i].run2cb_time_stat.time_9_12ms_cnt,
statistics_s[i].run2cb_time_stat.time_12_15ms_cnt,
statistics_s[i].run2cb_time_stat.time_15_18ms_cnt,
statistics_s[i].run2cb_time_stat.time_18_21ms_cnt,
statistics_s[i].run2cb_time_stat.time_21ms_up_cnt,
statistics_s[i].decode_time_stat.time_total_us,
statistics_s[i].decode_time_stat.time_max_us,
i,
div_u64(statistics_s[i].decode_time_stat.time_total_us , statistics_s[i].cb_cnt),
statistics_s[i].decode_time_stat.time_6ms_less_cnt,
statistics_s[i].decode_time_stat.time_6_9ms_cnt,
statistics_s[i].decode_time_stat.time_9_12ms_cnt,
statistics_s[i].decode_time_stat.time_12_15ms_cnt,
statistics_s[i].decode_time_stat.time_15_18ms_cnt,
statistics_s[i].decode_time_stat.time_18_21ms_cnt,
statistics_s[i].decode_time_stat.time_21ms_up_cnt);
}
mutex_unlock(&vdec_profile_mutex);
return 0;
}
static int vdec_profile_dbg_open(struct inode *inode, struct file *file)
{
return single_open(file, vdec_profile_dbg_show, NULL);
}
static int time_stat_profile_dbg_open(struct inode *inode, struct file *file)
{
return single_open(file, time_stat_profile_dbg_show, NULL);
}
static const struct file_operations event_dbg_fops = {
.open = vdec_profile_dbg_open,
.read = seq_read,
@@ -195,6 +392,14 @@ static const struct file_operations event_dbg_fops = {
.release = single_release,
};
static const struct file_operations time_stat_dbg_fops = {
.open = time_stat_profile_dbg_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#if 0 /*DEBUG_TMP*/
static int __init vdec_profile_init_debugfs(void)
{
@@ -224,7 +429,7 @@ err:
int vdec_profile_init_debugfs(void)
{
struct dentry *root, *event;
struct dentry *root, *event, *time_stat;
root = debugfs_create_dir("vdec_profile", NULL);
if (IS_ERR(root) || !root)
@@ -235,10 +440,17 @@ int vdec_profile_init_debugfs(void)
if (!event)
goto err_1;
time_stat = debugfs_create_file("time_stat", 0400, root, NULL,
&time_stat_dbg_fops);
if (!time_stat)
goto err_2;
mutex_init(&vdec_profile_mutex);
return 0;
err_2:
debugfs_remove(event);
err_1:
debugfs_remove(root);
err:
@@ -254,5 +466,10 @@ void vdec_profile_exit_debugfs(void)
}
EXPORT_SYMBOL(vdec_profile_exit_debugfs);
module_param(dec_time_stat_flag, uint, 0664);
module_param(dec_time_stat_reset, uint, 0664);
/*module_init(vdec_profile_init_debugfs);*/