147 lines
3.3 KiB
C
147 lines
3.3 KiB
C
|
/*
|
||
|
* task util initialization
|
||
|
*
|
||
|
* Copyright (C) 2018 Samsung Electronics Co., Ltd
|
||
|
* Lakkyung Jung <lakkyung.jung@samsung.com>
|
||
|
*/
|
||
|
|
||
|
#include <linux/sched.h>
|
||
|
|
||
|
#include "ems.h"
|
||
|
#include "../sched.h"
|
||
|
|
||
|
enum {
|
||
|
TYPE_BASE_CFS_RQ_UTIL = 0,
|
||
|
TYPE_BASE_INHERIT_PARENT_UTIL,
|
||
|
TYPE_MAX_NUM,
|
||
|
};
|
||
|
|
||
|
static unsigned long init_util_type = TYPE_BASE_CFS_RQ_UTIL;
|
||
|
static unsigned long init_util_ratio = 25; /* 25% */
|
||
|
|
||
|
static void base_cfs_rq_util(struct sched_entity *se)
|
||
|
{
|
||
|
struct cfs_rq *cfs_rq = se->cfs_rq;
|
||
|
struct sched_avg *sa = &se->avg;
|
||
|
int cpu = cpu_of(cfs_rq->rq);
|
||
|
unsigned long cap_org = capacity_orig_of(cpu);
|
||
|
long cap = (long)(cap_org - cfs_rq->avg.util_avg) / 2;
|
||
|
|
||
|
if (cap > 0) {
|
||
|
if (cfs_rq->avg.util_avg != 0) {
|
||
|
sa->util_avg = cfs_rq->avg.util_avg * se->load.weight;
|
||
|
sa->util_avg /= (cfs_rq->avg.load_avg + 1);
|
||
|
|
||
|
if (sa->util_avg > cap)
|
||
|
sa->util_avg = cap;
|
||
|
} else {
|
||
|
sa->util_avg = cap_org * init_util_ratio / 100;
|
||
|
}
|
||
|
/*
|
||
|
* If we wish to restore tuning via setting initial util,
|
||
|
* this is where we should do it.
|
||
|
*/
|
||
|
sa->util_sum = (u32)(sa->util_avg * LOAD_AVG_MAX);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void base_inherit_parent_util(struct sched_entity *se)
|
||
|
{
|
||
|
struct sched_avg *sa = &se->avg;
|
||
|
struct task_struct *p = current;
|
||
|
|
||
|
sa->util_avg = p->se.avg.util_avg;
|
||
|
sa->util_sum = p->se.avg.util_sum;
|
||
|
}
|
||
|
|
||
|
void exynos_init_entity_util_avg(struct sched_entity *se)
|
||
|
{
|
||
|
int type = init_util_type;
|
||
|
|
||
|
switch(type) {
|
||
|
case TYPE_BASE_CFS_RQ_UTIL:
|
||
|
base_cfs_rq_util(se);
|
||
|
break;
|
||
|
case TYPE_BASE_INHERIT_PARENT_UTIL:
|
||
|
base_inherit_parent_util(se);
|
||
|
break;
|
||
|
default:
|
||
|
pr_info("%s: Not support initial util type %ld\n",
|
||
|
__func__, init_util_type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static ssize_t show_initial_util_type(struct kobject *kobj,
|
||
|
struct kobj_attribute *attr, char *buf)
|
||
|
{
|
||
|
return snprintf(buf, 10, "%ld\n", init_util_type);
|
||
|
}
|
||
|
|
||
|
static ssize_t store_initial_util_type(struct kobject *kobj,
|
||
|
struct kobj_attribute *attr, const char *buf,
|
||
|
size_t count)
|
||
|
{
|
||
|
long input;
|
||
|
|
||
|
if (!sscanf(buf, "%ld", &input))
|
||
|
return -EINVAL;
|
||
|
|
||
|
input = input < 0 ? 0 : input;
|
||
|
input = input >= TYPE_MAX_NUM ? TYPE_MAX_NUM - 1 : input;
|
||
|
|
||
|
init_util_type = input;
|
||
|
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t show_initial_util_ratio(struct kobject *kobj,
|
||
|
struct kobj_attribute *attr, char *buf)
|
||
|
{
|
||
|
return snprintf(buf, 10, "%ld\n", init_util_ratio);
|
||
|
}
|
||
|
|
||
|
static ssize_t store_initial_util_ratio(struct kobject *kobj,
|
||
|
struct kobj_attribute *attr, const char *buf,
|
||
|
size_t count)
|
||
|
{
|
||
|
long input;
|
||
|
|
||
|
if (!sscanf(buf, "%ld", &input))
|
||
|
return -EINVAL;
|
||
|
|
||
|
init_util_ratio = !!input;
|
||
|
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static struct kobj_attribute initial_util_type =
|
||
|
__ATTR(initial_util_type, 0644, show_initial_util_type, store_initial_util_type);
|
||
|
|
||
|
static struct kobj_attribute initial_util_ratio =
|
||
|
__ATTR(initial_util_ratio, 0644, show_initial_util_ratio, store_initial_util_ratio);
|
||
|
|
||
|
static struct attribute *attrs[] = {
|
||
|
&initial_util_type.attr,
|
||
|
&initial_util_ratio.attr,
|
||
|
NULL,
|
||
|
};
|
||
|
|
||
|
static const struct attribute_group attr_group = {
|
||
|
.attrs = attrs,
|
||
|
};
|
||
|
|
||
|
static int __init init_util_sysfs(void)
|
||
|
{
|
||
|
struct kobject *kobj;
|
||
|
|
||
|
kobj = kobject_create_and_add("init_util", ems_kobj);
|
||
|
if (!kobj)
|
||
|
return -EINVAL;
|
||
|
|
||
|
if (sysfs_create_group(kobj, &attr_group))
|
||
|
return -EINVAL;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
late_initcall(init_util_sysfs);
|