mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "soc: qcom: mem-offline: log additional time stats"
This commit is contained in:
commit
3ea5777d6d
1 changed files with 172 additions and 43 deletions
|
|
@ -29,7 +29,6 @@ static struct kobject *kobj;
|
|||
static unsigned int sections_per_block;
|
||||
static u32 offline_granule;
|
||||
#define MODULE_CLASS_NAME "mem-offline"
|
||||
#define BUF_LEN 100
|
||||
|
||||
struct section_stat {
|
||||
unsigned long success_count;
|
||||
|
|
@ -39,6 +38,8 @@ struct section_stat {
|
|||
unsigned long worst_time;
|
||||
unsigned long total_time;
|
||||
unsigned long last_recorded_time;
|
||||
ktime_t resident_time;
|
||||
ktime_t resident_since;
|
||||
};
|
||||
|
||||
enum memory_states {
|
||||
|
|
@ -115,6 +116,7 @@ static void record_stat(unsigned long sec, ktime_t delay, int mode)
|
|||
unsigned int total_sec = end_section_nr - start_section_nr + 1;
|
||||
unsigned int blk_nr = (sec - start_section_nr + mode * total_sec) /
|
||||
sections_per_block;
|
||||
ktime_t now, delta;
|
||||
|
||||
if (sec > end_section_nr)
|
||||
return;
|
||||
|
|
@ -135,6 +137,18 @@ static void record_stat(unsigned long sec, ktime_t delay, int mode)
|
|||
mem_info[blk_nr].total_time / mem_info[blk_nr].success_count;
|
||||
|
||||
mem_info[blk_nr].last_recorded_time = delay;
|
||||
|
||||
now = ktime_get();
|
||||
mem_info[blk_nr].resident_since = now;
|
||||
|
||||
/* since other state has gone inactive, update the stats */
|
||||
mode = mode ? MEMORY_ONLINE : MEMORY_OFFLINE;
|
||||
blk_nr = (sec - start_section_nr + mode * total_sec) /
|
||||
sections_per_block;
|
||||
delta = ktime_sub(now, mem_info[blk_nr].resident_since);
|
||||
mem_info[blk_nr].resident_time =
|
||||
ktime_add(mem_info[blk_nr].resident_time, delta);
|
||||
mem_info[blk_nr].resident_since = 0;
|
||||
}
|
||||
|
||||
static int aop_send_msg(unsigned long addr, bool online)
|
||||
|
|
@ -434,75 +448,184 @@ static int mem_online_remaining_blocks(void)
|
|||
static ssize_t show_mem_offline_granule(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, BUF_LEN, "%lu\n", (unsigned long)offline_granule *
|
||||
SZ_1M);
|
||||
return scnprintf(buf, PAGE_SIZE, "%lu\n",
|
||||
(unsigned long)offline_granule * SZ_1M);
|
||||
}
|
||||
|
||||
static ssize_t show_mem_perf_stats(struct kobject *kobj,
|
||||
|
||||
static unsigned int print_blk_residency_percentage(char *buf, size_t sz,
|
||||
unsigned int tot_blks, ktime_t *total_time,
|
||||
enum memory_states mode)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int c = 0;
|
||||
int percent;
|
||||
unsigned int idx = tot_blks + 1;
|
||||
|
||||
for (i = 0; i <= tot_blks; i++) {
|
||||
percent = (int)ktime_divns(total_time[i + mode * idx] * 100,
|
||||
ktime_add(total_time[i + MEMORY_ONLINE * idx],
|
||||
total_time[i + MEMORY_OFFLINE * idx]));
|
||||
|
||||
c += scnprintf(buf + c, sz - c, "%d%%\t\t", percent);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
static unsigned int print_blk_residency_times(char *buf, size_t sz,
|
||||
unsigned int tot_blks, ktime_t *total_time,
|
||||
enum memory_states mode)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int c = 0;
|
||||
ktime_t now, delta;
|
||||
unsigned int idx = tot_blks + 1;
|
||||
|
||||
now = ktime_get();
|
||||
for (i = 0; i <= tot_blks; i++) {
|
||||
if (mem_sec_state[i] == mode)
|
||||
delta = ktime_sub(now,
|
||||
mem_info[i + mode * idx].resident_since);
|
||||
else
|
||||
delta = 0;
|
||||
delta = ktime_add(delta,
|
||||
mem_info[i + mode * idx].resident_time);
|
||||
c += scnprintf(buf + c, sz - c, "%lus\t\t",
|
||||
ktime_to_ms(delta) / MSEC_PER_SEC);
|
||||
total_time[i + mode * idx] = delta;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static ssize_t show_mem_stats(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
unsigned int blk_start = start_section_nr / sections_per_block;
|
||||
unsigned int blk_end = end_section_nr / sections_per_block;
|
||||
unsigned int idx = blk_end - blk_start + 1;
|
||||
unsigned int char_count = 0;
|
||||
unsigned int tot_blks = blk_end - blk_start;
|
||||
ktime_t *total_time;
|
||||
unsigned int idx = tot_blks + 1;
|
||||
unsigned int c = 0;
|
||||
unsigned int i, j;
|
||||
|
||||
size_t sz = PAGE_SIZE;
|
||||
ktime_t total = 0, total_online = 0, total_offline = 0;
|
||||
|
||||
total_time = kcalloc(idx * MAX_STATE, sizeof(*total_time), GFP_KERNEL);
|
||||
|
||||
if (!total_time)
|
||||
return -ENOMEM;
|
||||
|
||||
for (j = 0; j < MAX_STATE; j++) {
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\n\t%s\n\t\t\t", j == 0 ? "ONLINE" : "OFFLINE");
|
||||
for (i = blk_start; i <= blk_end; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%s%d\t\t", "mem", i);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tLast recd time:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lums\t\t", mem_info[i+j*idx].last_recorded_time);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c, "%lums\t\t",
|
||||
mem_info[i + j * idx].last_recorded_time);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tAvg time:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lums\t\t", mem_info[i+j*idx].avg_time);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%lums\t\t", mem_info[i + j * idx].avg_time);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tBest time:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lums\t\t", mem_info[i+j*idx].best_time);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%lums\t\t", mem_info[i + j * idx].best_time);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tWorst time:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lums\t\t", mem_info[i+j*idx].worst_time);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%lums\t\t", mem_info[i + j * idx].worst_time);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tSuccess count:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lu\t\t", mem_info[i+j*idx].success_count);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%lu\t\t", mem_info[i + j * idx].success_count);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"\tFail count:\t");
|
||||
for (i = 0; i <= blk_end - blk_start; i++)
|
||||
char_count += snprintf(buf + char_count, BUF_LEN,
|
||||
"%lu\t\t", mem_info[i+j*idx].fail_count);
|
||||
char_count += snprintf(buf + char_count, BUF_LEN, "\n");
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
c += scnprintf(buf + c, sz - c,
|
||||
"%lu\t\t", mem_info[i + j * idx].fail_count);
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
}
|
||||
return char_count;
|
||||
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c, "\tState:\t\t");
|
||||
for (i = 0; i <= tot_blks; i++) {
|
||||
c += scnprintf(buf + c, sz - c, "%s\t\t",
|
||||
mem_sec_state[i] == MEMORY_ONLINE ?
|
||||
"Online" : "Offline");
|
||||
}
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c, "\tOnline time:\t");
|
||||
c += print_blk_residency_times(buf + c, sz - c,
|
||||
tot_blks, total_time, MEMORY_ONLINE);
|
||||
|
||||
|
||||
c += scnprintf(buf + c, sz - c, "\n");
|
||||
c += scnprintf(buf + c, sz - c, "\tOffline time:\t");
|
||||
c += print_blk_residency_times(buf + c, sz - c,
|
||||
tot_blks, total_time, MEMORY_OFFLINE);
|
||||
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
c += scnprintf(buf + c, sz, "\tOnline %%:\t");
|
||||
c += print_blk_residency_percentage(buf + c, sz - c,
|
||||
tot_blks, total_time, MEMORY_ONLINE);
|
||||
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
c += scnprintf(buf + c, sz, "\tOffline %%:\t");
|
||||
c += print_blk_residency_percentage(buf + c, sz - c,
|
||||
tot_blks, total_time, MEMORY_OFFLINE);
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
total = ktime_add(total,
|
||||
ktime_add(total_time[i + MEMORY_ONLINE * idx],
|
||||
total_time[i + MEMORY_OFFLINE * idx]));
|
||||
|
||||
for (i = 0; i <= tot_blks; i++)
|
||||
total_online = ktime_add(total_online,
|
||||
total_time[i + MEMORY_ONLINE * idx]);
|
||||
|
||||
total_offline = ktime_sub(total, total_online);
|
||||
|
||||
c += scnprintf(buf + c, sz,
|
||||
"\tAvg Online %%:\t%d%%\n",
|
||||
((int)total_online * 100) / total);
|
||||
c += scnprintf(buf + c, sz,
|
||||
"\tAvg Offline %%:\t%d%%\n",
|
||||
((int)total_offline * 100) / total);
|
||||
|
||||
c += scnprintf(buf + c, sz, "\n");
|
||||
kfree(total_time);
|
||||
return c;
|
||||
}
|
||||
|
||||
static struct kobj_attribute perf_stats_attr =
|
||||
__ATTR(perf_stats, 0444, show_mem_perf_stats, NULL);
|
||||
static struct kobj_attribute stats_attr =
|
||||
__ATTR(stats, 0444, show_mem_stats, NULL);
|
||||
|
||||
static struct kobj_attribute offline_granule_attr =
|
||||
__ATTR(offline_granule, 0444, show_mem_offline_granule, NULL);
|
||||
|
||||
static struct attribute *mem_root_attrs[] = {
|
||||
&perf_stats_attr.attr,
|
||||
&stats_attr.attr,
|
||||
&offline_granule_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
|
@ -573,6 +696,7 @@ static int mem_offline_driver_probe(struct platform_device *pdev)
|
|||
{
|
||||
unsigned int total_blks;
|
||||
int ret, i;
|
||||
ktime_t now;
|
||||
|
||||
ret = mem_parse_dt(pdev);
|
||||
if (ret)
|
||||
|
|
@ -592,6 +716,11 @@ static int mem_offline_driver_probe(struct platform_device *pdev)
|
|||
if (!mem_info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* record time of online for all blocks */
|
||||
now = ktime_get();
|
||||
for (i = 0; i < total_blks; i++)
|
||||
mem_info[i].resident_since = now;
|
||||
|
||||
mem_sec_state = kcalloc(total_blks, sizeof(*mem_sec_state), GFP_KERNEL);
|
||||
if (!mem_sec_state) {
|
||||
ret = -ENOMEM;
|
||||
|
|
|
|||
Loading…
Reference in a new issue