Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1ea5a45 authored by Joonwoo Park's avatar Joonwoo Park Committed by Gerrit - the friendly Code Review server
Browse files

sched: introduce sched_{up,down}migrate knobs



Introduce knobs sched_upmigrate and sched_downmigrate to
control thresholds to up and down migrate tasks between clusters at a
runtime for ease of power and performance tuning.

Change-Id: I17a464388b404b61d9a9dbe1beee4883c4db8e3f
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
[satyap@codeaurora.org: resolve merge conflicts & update
functinality as needed on msm-4.14]
Signed-off-by: default avatarSatya Durga Srinivasu Prabhala <satyap@codeaurora.org>
parent 5d5db8a6
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ extern unsigned int sysctl_sched_sync_hint_enable;
extern unsigned int sysctl_sched_cstate_aware;
extern unsigned int sysctl_sched_wakeup_granularity;
extern unsigned int sysctl_sched_child_runs_first;
extern unsigned int sysctl_sched_capacity_margin_up;
extern unsigned int sysctl_sched_capacity_margin_down;
#ifdef CONFIG_SCHED_WALT
extern unsigned int sysctl_sched_use_walt_cpu_util;
extern unsigned int sysctl_sched_use_walt_task_util;
@@ -92,6 +94,10 @@ extern int sched_rt_handler(struct ctl_table *table, int write,
		void __user *buffer, size_t *lenp,
		loff_t *ppos);

extern int sched_updown_migrate_handler(struct ctl_table *table,
					int write, void __user *buffer,
					size_t *lenp, loff_t *ppos);

extern int sysctl_numa_balancing(struct ctl_table *table, int write,
				 void __user *buffer, size_t *lenp,
				 loff_t *ppos);
+3 −0
Original line number Diff line number Diff line
@@ -63,6 +63,9 @@ extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
				      void __user *, size_t *, loff_t *);
extern int proc_do_large_bitmap(struct ctl_table *, int,
				void __user *, size_t *, loff_t *);
extern int proc_douintvec_capacity(struct ctl_table *table, int write,
				   void __user *buffer, size_t *lenp,
				   loff_t *ppos);

/*
 * Register a set of sysctl names by calling register_sysctl_table
+26 −0
Original line number Diff line number Diff line
@@ -6677,6 +6677,32 @@ void sched_move_task(struct task_struct *tsk)
	task_rq_unlock(rq, tsk, &rf);
}

#ifdef CONFIG_PROC_SYSCTL
int sched_updown_migrate_handler(struct ctl_table *table, int write,
				 void __user *buffer, size_t *lenp,
				 loff_t *ppos)
{
	int ret;
	unsigned int *data = (unsigned int *)table->data;
	unsigned int old_val;
	static DEFINE_MUTEX(mutex);

	mutex_lock(&mutex);
	old_val = *data;

	ret = proc_douintvec_capacity(table, write, buffer, lenp, ppos);

	if (!ret && write && sysctl_sched_capacity_margin_up >
				sysctl_sched_capacity_margin_down) {
		ret = -EINVAL;
		*data = old_val;
	}
	mutex_unlock(&mutex);

	return ret;
}
#endif

static inline struct task_group *css_tg(struct cgroup_subsys_state *css)
{
	return css ? container_of(css, struct task_group, css) : NULL;
+16 −4
Original line number Diff line number Diff line
@@ -181,6 +181,9 @@ unsigned int sysctl_sched_cfs_bandwidth_slice = 5000UL;
 */
unsigned int capacity_margin				= 1280;

unsigned int sysctl_sched_capacity_margin_up = 1078; /* ~5% margin */
unsigned int sysctl_sched_capacity_margin_down = 1205; /* ~15% margin */

static inline void update_load_add(struct load_weight *lw, unsigned long inc)
{
	lw->weight += inc;
@@ -6904,9 +6907,18 @@ static int cpu_util_wake(int cpu, struct task_struct *p)
	return (util >= capacity) ? capacity : util;
}

static inline int task_fits_capacity(struct task_struct *p, long capacity)
static inline int task_fits_capacity(struct task_struct *p,
					long capacity,
					int cpu)
{
	return capacity * 1024 > boosted_task_util(p) * capacity_margin;
	unsigned int margin;

	if (capacity_orig_of(task_cpu(p)) > capacity_orig_of(cpu))
		margin = sysctl_sched_capacity_margin_down;
	else
		margin = sysctl_sched_capacity_margin_up;

	return capacity * 1024 > boosted_task_util(p) * margin;
}

static int start_cpu(bool boosted)
@@ -7210,7 +7222,7 @@ static int wake_cap(struct task_struct *p, int cpu, int prev_cpu)
	/* Bring task utilization in sync with prev_cpu */
	sync_entity_load_avg(&p->se);

	return task_fits_capacity(p, min_cap);
	return task_fits_capacity(p, min_cap, cpu);
}

static bool cpu_overutilized(int cpu)
@@ -7830,7 +7842,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
static inline void update_misfit_task(struct rq *rq, struct task_struct *p)
{
#ifdef CONFIG_SMP
	rq->misfit_task = !task_fits_capacity(p, capacity_of(rq->cpu));
	rq->misfit_task = !task_fits_capacity(p, capacity_of(rq->cpu), rq->cpu);
#endif
}

+52 −0
Original line number Diff line number Diff line
@@ -394,6 +394,20 @@ static struct ctl_table kern_table[] = {
		.extra1		= &min_wakeup_granularity_ns,
		.extra2		= &max_wakeup_granularity_ns,
	},
	{
		.procname	= "sched_upmigrate",
		.data		= &sysctl_sched_capacity_margin_up,
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= sched_updown_migrate_handler,
	},
	{
		.procname	= "sched_downmigrate",
		.data		= &sysctl_sched_capacity_margin_down,
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= sched_updown_migrate_handler,
	},
#ifdef CONFIG_SMP
	{
		.procname	= "sched_tunable_scaling",
@@ -3172,6 +3186,39 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
	}
}

static int do_proc_douintvec_capacity_conv(bool *negp, unsigned long *lvalp,
					   int *valp, int write, void *data)
{
	if (write) {
		if (*negp)
			return -EINVAL;
		*valp = SCHED_FIXEDPOINT_SCALE * 100 / *lvalp;
	} else {
		*negp = false;
		*lvalp = SCHED_FIXEDPOINT_SCALE * 100 / *valp;
	}

	return 0;
}

/**
 * proc_douintvec_capacity - read a vector of integers in percentage and convert
 *			    into sched capacity
 * @table: the sysctl table
 * @write: %TRUE if this is a write to the sysctl file
 * @buffer: the user buffer
 * @lenp: the size of the user buffer
 * @ppos: file position
 *
 * Returns 0 on success.
 */
int proc_douintvec_capacity(struct ctl_table *table, int write,
			    void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return do_proc_dointvec(table, write, buffer, lenp, ppos,
				do_proc_douintvec_capacity_conv, NULL);
}

#else /* CONFIG_PROC_SYSCTL */

int proc_dostring(struct ctl_table *table, int write,
@@ -3235,6 +3282,11 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
    return -ENOSYS;
}

int proc_douintvec_capacity(struct ctl_table *table, int write,
			    void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return -ENOSYS;
}

#endif /* CONFIG_PROC_SYSCTL */