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

Commit 980436fe authored by Pavankumar Kondeti's avatar Pavankumar Kondeti
Browse files

sched: Improve the scheduler



This change is for general scheduler improvement.

Change-Id: Ifebdb171fec030347e0582e5a91d3deac8812763
Signed-off-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent 04717e47
Loading
Loading
Loading
Loading
+157 −86
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ enum sched_boost_policy boost_policy;

static enum sched_boost_policy boost_policy_dt = SCHED_BOOST_NONE;
static DEFINE_MUTEX(boost_mutex);
static int boost_refcount[MAX_NUM_BOOST_TYPE];

/*
 * Scheduler boost type and boost policy might at first seem unrelated,
@@ -67,100 +66,172 @@ static bool verify_boost_params(int type)
	return type >= RESTRAINED_BOOST_DISABLE && type <= RESTRAINED_BOOST;
}

static void _sched_set_boost(int type)
static void sched_no_boost_nop(void)
{
	switch (type) {
	case NO_BOOST: /* All boost clear */
		if (boost_refcount[FULL_THROTTLE_BOOST] > 0) {
			core_ctl_set_boost(false);
			walt_enable_frequency_aggregation(false);
			boost_refcount[FULL_THROTTLE_BOOST] = 0;
		}
		if (boost_refcount[CONSERVATIVE_BOOST] > 0) {
			restore_cgroup_boost_settings();
			boost_refcount[CONSERVATIVE_BOOST] = 0;
}
		if (boost_refcount[RESTRAINED_BOOST] > 0) {
			walt_enable_frequency_aggregation(false);
			boost_refcount[RESTRAINED_BOOST] = 0;
		}
		break;

	case FULL_THROTTLE_BOOST:
	    boost_refcount[FULL_THROTTLE_BOOST]++;
		if (boost_refcount[FULL_THROTTLE_BOOST] == 1) {
static void sched_full_throttle_boost_enter(void)
{
	core_ctl_set_boost(true);
			restore_cgroup_boost_settings();
			if (!boost_refcount[RESTRAINED_BOOST])
	walt_enable_frequency_aggregation(true);
}
		break;

	case CONSERVATIVE_BOOST:
	    boost_refcount[CONSERVATIVE_BOOST]++;
		if ((boost_refcount[CONSERVATIVE_BOOST] == 1) &&
				!boost_refcount[FULL_THROTTLE_BOOST])
static void sched_full_throttle_boost_exit(void)
{
	core_ctl_set_boost(false);
	walt_enable_frequency_aggregation(false);
}

static void sched_conservative_boost_enter(void)
{
	update_cgroup_boost_settings();
		break;
}

	case RESTRAINED_BOOST:
	    boost_refcount[RESTRAINED_BOOST]++;
		if (boost_refcount[RESTRAINED_BOOST] == 1 &&
		    !boost_refcount[FULL_THROTTLE_BOOST])
static void sched_conservative_boost_exit(void)
{
	restore_cgroup_boost_settings();
}

static void sched_restrained_boost_enter(void)
{
	walt_enable_frequency_aggregation(true);
		break;
}

	case FULL_THROTTLE_BOOST_DISABLE:
		if (boost_refcount[FULL_THROTTLE_BOOST] >= 1) {
			boost_refcount[FULL_THROTTLE_BOOST]--;
			if (!boost_refcount[FULL_THROTTLE_BOOST]) {
				core_ctl_set_boost(false);
				if (boost_refcount[CONSERVATIVE_BOOST] >= 1)
					update_cgroup_boost_settings();
				if (!boost_refcount[RESTRAINED_BOOST])
					walt_enable_frequency_aggregation(
								false);
static void sched_restrained_boost_exit(void)
{
	walt_enable_frequency_aggregation(false);
}

struct sched_boost_data {
	int refcount;
	void (*enter)(void);
	void (*exit)(void);
};

static struct sched_boost_data sched_boosts[] = {
	[NO_BOOST] = {
		.refcount = 0,
		.enter = sched_no_boost_nop,
		.exit = sched_no_boost_nop,
	},
	[FULL_THROTTLE_BOOST] = {
		.refcount = 0,
		.enter = sched_full_throttle_boost_enter,
		.exit = sched_full_throttle_boost_exit,
	},
	[CONSERVATIVE_BOOST] = {
		.refcount = 0,
		.enter = sched_conservative_boost_enter,
		.exit = sched_conservative_boost_exit,
	},
	[RESTRAINED_BOOST] = {
		.refcount = 0,
		.enter = sched_restrained_boost_enter,
		.exit = sched_restrained_boost_exit,
	},
};

#define SCHED_BOOST_START FULL_THROTTLE_BOOST
#define SCHED_BOOST_END (RESTRAINED_BOOST + 1)

static int sched_effective_boost(void)
{
	int i;

	/*
	 * The boosts are sorted in descending order by
	 * priority.
	 */
	for (i = SCHED_BOOST_START; i < SCHED_BOOST_END; i++) {
		if (sched_boosts[i].refcount >= 1)
			return i;
	}
		break;

	case CONSERVATIVE_BOOST_DISABLE:
		if (boost_refcount[CONSERVATIVE_BOOST] >= 1) {
			boost_refcount[CONSERVATIVE_BOOST]--;
			if (!boost_refcount[CONSERVATIVE_BOOST])
				restore_cgroup_boost_settings();
	return NO_BOOST;
}
		break;

	case RESTRAINED_BOOST_DISABLE:
		if (boost_refcount[RESTRAINED_BOOST] >= 1) {
			boost_refcount[RESTRAINED_BOOST]--;
			if (!boost_refcount[RESTRAINED_BOOST] &&
			    !boost_refcount[FULL_THROTTLE_BOOST])
				walt_enable_frequency_aggregation(false);
static void sched_boost_disable(int type)
{
	struct sched_boost_data *sb = &sched_boosts[type];
	int next_boost;

	if (sb->refcount <= 0)
		return;

	sb->refcount--;

	if (sb->refcount)
		return;

	/*
	 * This boost's refcount becomes zero, so it must
	 * be disabled. Disable it first and then apply
	 * the next boost.
	 */
	sb->exit();

	next_boost = sched_effective_boost();
	sched_boosts[next_boost].enter();
}
		break;

	default:
		WARN_ON(1);
static void sched_boost_enable(int type)
{
	struct sched_boost_data *sb = &sched_boosts[type];
	int next_boost, prev_boost = sched_boost_type;

	sb->refcount++;

	if (sb->refcount != 1)
		return;

	/*
	 * This boost enable request did not come before.
	 * Take this new request and find the next boost
	 * by aggregating all the enabled boosts. If there
	 * is a change, disable the previous boost and enable
	 * the next boost.
	 */

	next_boost = sched_effective_boost();
	if (next_boost == prev_boost)
		return;

	sched_boosts[prev_boost].exit();
	sched_boosts[next_boost].enter();
}

static void sched_boost_disable_all(void)
{
	int i;

	for (i = SCHED_BOOST_START; i < SCHED_BOOST_END; i++) {
		if (sched_boosts[i].refcount > 0) {
			sched_boosts[i].exit();
			sched_boosts[i].refcount = 0;
		}
	}
}

	/* Aggregate final boost type */
	if (boost_refcount[FULL_THROTTLE_BOOST] >= 1)
		type = FULL_THROTTLE_BOOST;
	else if (boost_refcount[CONSERVATIVE_BOOST] >= 1)
		type = CONSERVATIVE_BOOST;
	else if (boost_refcount[RESTRAINED_BOOST] >= 1)
		type = RESTRAINED_BOOST;
static void _sched_set_boost(int type)
{
	if (type == 0)
		sched_boost_disable_all();
	else if (type > 0)
		sched_boost_enable(type);
	else
		type = NO_BOOST;
		sched_boost_disable(-type);

	sched_boost_type = type;
	sysctl_sched_boost = type;
	/*
	 * sysctl_sched_boost holds the boost request from
	 * user space which could be different from the
	 * effectively enabled boost. Update the effective
	 * boost here.
	 */

	set_boost_policy(type);
	trace_sched_set_boost(type);
	sched_boost_type = sched_effective_boost();
	sysctl_sched_boost = sched_boost_type;
	set_boost_policy(sysctl_sched_boost);
	trace_sched_set_boost(sysctl_sched_boost);
}

void sched_boost_parse_dt(void)