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

Commit 840d1a23 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "core_ctl: un-isolate BIG CPUs more aggressively"

parents f53ee91e 57fd979f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -178,7 +178,9 @@ extern u64 nr_running_integral(unsigned int cpu);
#endif

extern void sched_update_nr_prod(int cpu, long delta, bool inc);
extern void sched_get_nr_running_avg(int *avg, int *iowait_avg, int *big_avg);
extern void sched_get_nr_running_avg(int *avg, int *iowait_avg, int *big_avg,
				     unsigned int *max_nr,
				     unsigned int *big_max_nr);

extern void calc_global_load(unsigned long ticks);

+10 −4
Original line number Diff line number Diff line
@@ -1312,24 +1312,30 @@ TRACE_EVENT(sched_wake_idle_without_ipi,

TRACE_EVENT(sched_get_nr_running_avg,

	TP_PROTO(int avg, int big_avg, int iowait_avg),
	TP_PROTO(int avg, int big_avg, int iowait_avg,
		 unsigned int max_nr, unsigned int big_max_nr),

	TP_ARGS(avg, big_avg, iowait_avg),
	TP_ARGS(avg, big_avg, iowait_avg, max_nr, big_max_nr),

	TP_STRUCT__entry(
		__field( int,	avg			)
		__field( int,	big_avg			)
		__field( int,	iowait_avg		)
		__field( unsigned int,	max_nr		)
		__field( unsigned int,	big_max_nr	)
	),

	TP_fast_assign(
		__entry->avg		= avg;
		__entry->big_avg	= big_avg;
		__entry->iowait_avg	= iowait_avg;
		__entry->max_nr		= max_nr;
		__entry->big_max_nr	= big_max_nr;
	),

	TP_printk("avg=%d big_avg=%d iowait_avg=%d",
		__entry->avg, __entry->big_avg, __entry->iowait_avg)
	TP_printk("avg=%d big_avg=%d iowait_avg=%d max_nr=%u big_max_nr=%u",
		__entry->avg, __entry->big_avg, __entry->iowait_avg,
		__entry->max_nr, __entry->big_max_nr)
);

TRACE_EVENT(core_ctl_eval_need,
+22 −28
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ struct cluster_data {
	cpumask_t cpu_mask;
	unsigned int need_cpus;
	unsigned int task_thres;
	unsigned int max_nr;
	s64 need_ts;
	struct list_head lru;
	bool pending;
@@ -60,6 +61,7 @@ struct cpu_data {
	struct cluster_data *cluster;
	struct list_head sib;
	bool isolated_by_us;
	unsigned int max_nr;
};

static DEFINE_PER_CPU(struct cpu_data, cpu_state);
@@ -429,7 +431,6 @@ static struct kobj_type ktype_core_ctl = {

#define RQ_AVG_TOLERANCE 2
#define RQ_AVG_DEFAULT_MS 20
#define NR_RUNNING_TOLERANCE 5
static unsigned int rq_avg_period_ms = RQ_AVG_DEFAULT_MS;

static s64 rq_avg_timestamp_ms;
@@ -437,6 +438,7 @@ static s64 rq_avg_timestamp_ms;
static void update_running_avg(bool trigger_update)
{
	int avg, iowait_avg, big_avg, old_nrrun;
	int old_max_nr, max_nr, big_max_nr;
	s64 now;
	unsigned long flags;
	struct cluster_data *cluster;
@@ -450,40 +452,23 @@ static void update_running_avg(bool trigger_update)
		return;
	}
	rq_avg_timestamp_ms = now;
	sched_get_nr_running_avg(&avg, &iowait_avg, &big_avg);
	sched_get_nr_running_avg(&avg, &iowait_avg, &big_avg,
				 &max_nr, &big_max_nr);

	spin_unlock_irqrestore(&state_lock, flags);

	/*
	 * Round up to the next integer if the average nr running tasks
	 * is within NR_RUNNING_TOLERANCE/100 of the next integer.
	 * If normal rounding up is used, it will allow a transient task
	 * to trigger online event. By the time core is onlined, the task
	 * has finished.
	 * Rounding to closest suffers same problem because scheduler
	 * might only provide running stats per jiffy, and a transient
	 * task could skew the number for one jiffy. If core control
	 * samples every 2 jiffies, it will observe 0.5 additional running
	 * average which rounds up to 1 task.
	 */
	avg = (avg + NR_RUNNING_TOLERANCE) / 100;
	big_avg = (big_avg + NR_RUNNING_TOLERANCE) / 100;

	for_each_cluster(cluster, index) {
		if (!cluster->inited)
			continue;

		old_nrrun = cluster->nrrun;
		/*
		 * Big cluster only need to take care of big tasks, but if
		 * there are not enough big cores, big tasks need to be run
		 * on little as well. Thus for little's runqueue stat, it
		 * has to use overall runqueue average, or derive what big
		 * tasks would have to be run on little. The latter approach
		 * is not easy to get given core control reacts much slower
		 * than scheduler, and can't predict scheduler's behavior.
		 */
		old_max_nr = cluster->max_nr;
		cluster->nrrun = cluster->is_big_cluster ? big_avg : avg;
		if (cluster->nrrun != old_nrrun) {
		cluster->max_nr = cluster->is_big_cluster ? big_max_nr : max_nr;

		if (cluster->nrrun != old_nrrun ||
			cluster->max_nr != old_max_nr) {

			if (trigger_update)
				apply_need(cluster);
			else
@@ -493,6 +478,7 @@ static void update_running_avg(bool trigger_update)
	return;
}

#define MAX_NR_THRESHOLD	4
/* adjust needed CPUs based on current runqueue information */
static unsigned int apply_task_need(const struct cluster_data *cluster,
				    unsigned int new_need)
@@ -503,7 +489,15 @@ static unsigned int apply_task_need(const struct cluster_data *cluster,

	/* only unisolate more cores if there are tasks to run */
	if (cluster->nrrun > new_need)
		return new_need + 1;
		new_need = new_need + 1;

	/*
	 * We don't want tasks to be overcrowded in a cluster.
	 * If any CPU has more than MAX_NR_THRESHOLD in the last
	 * window, bring another CPU to help out.
	 */
	if (cluster->max_nr > MAX_NR_THRESHOLD)
		new_need = new_need + 1;

	return new_need;
}
+1 −1
Original line number Diff line number Diff line
@@ -1602,7 +1602,7 @@ unsigned int nr_eligible_big_tasks(int cpu)
	int nr_big = rq->hmp_stats.nr_big_tasks;
	int nr = rq->nr_running;

	if (cpu_max_possible_capacity(cpu) != max_possible_capacity)
	if (!is_max_capacity_cpu(cpu))
		return nr_big;

	return nr;
+7 −0
Original line number Diff line number Diff line
@@ -1225,6 +1225,11 @@ static inline bool hmp_capable(void)
	return max_possible_capacity != min_max_possible_capacity;
}

static inline bool is_max_capacity_cpu(int cpu)
{
	return cpu_max_possible_capacity(cpu) == max_possible_capacity;
}

/*
 * 'load' is in reference to "best cpu" at its best frequency.
 * Scale that in reference to a given cpu, accounting for how bad it is
@@ -1601,6 +1606,8 @@ static inline unsigned int nr_eligible_big_tasks(int cpu)
	return 0;
}

static inline bool is_max_capacity_cpu(int cpu) { return true; }

static inline int pct_task_load(struct task_struct *p) { return 0; }

static inline int cpu_capacity(int cpu)
Loading