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

Commit bfc52594 authored by Ke Wang's avatar Ke Wang Committed by Todd Kjos
Browse files

ANDROID: sched/walt: Fix lockdep assert issue



commit c8d50e06 ("ANDROID: DEBUG: Temporarily disable lockdep
asserting on update_task_ravg") is a temporary commit to disable the
lockdep assert in walt_update_task_ravg(). The root cause is that there
are two paths enetering here without holding the rq lock in the pure
scheduler: one is move_queued_task(), another is detach_task().

Now fix this by making sure the rq lock is held at the two paths listed
above as it did in android4.4.

The following warning message occurs when enable lockdep_assert_held()
in walt_update_task_ravg():

[    0.850221] c3 WARNING: CPU: 3 PID: 28 at kernel/sched/walt.c:763 walt_update_task_ravg+0x28c/0x634
...
[    1.379256] c3 [<ffffff8008101038>] walt_update_task_ravg+0x28c/0x634
[    1.385587] c3 [<ffffff80081017f8>] walt_fixup_busy_time+0x108/0x404
[    1.392006] c3 [<ffffff80080dc91c>] set_task_cpu+0x220/0x2a4
[    1.397639] c3 [<ffffff80080e48a8>] detach_task+0x60/0x74
[    1.402929] c3 [<ffffff80080e4c24>] active_load_balance_cpu_stop+0x2cc/0x350
[    1.410045] c3 [<ffffff800816582c>] cpu_stopper_thread+0xb0/0x118
[    1.416029] c3 [<ffffff80080d418c>] smpboot_thread_fn+0x214/0x258
[    1.422100] c3 [<ffffff80080cfd40>] kthread+0x128/0x130
[    1.427304] c3 [<ffffff8008084834>] ret_from_fork+0x10/0x18

Bug: 120440300
Change-Id: Id3da7ad0dbc9d0d316cd7365b96c3686daba0340
Signed-off-by: default avatarKe Wang <ke.wang@spreadtrum.com>
parent 578e66bf
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -950,12 +950,17 @@ static inline bool is_cpu_allowed(struct task_struct *p, int cpu)
static struct rq *move_queued_task(struct rq *rq, struct rq_flags *rf,
				   struct task_struct *p, int new_cpu)
{
	struct rq *new_rq = cpu_rq(new_cpu);

	lockdep_assert_held(&rq->lock);

	p->on_rq = TASK_ON_RQ_MIGRATING;
	dequeue_task(rq, p, DEQUEUE_NOCLOCK);
	rq_unpin_lock(rq, rf);
	double_lock_balance(rq, new_rq);
	set_task_cpu(p, new_cpu);
	rq_unlock(rq, rf);
	double_unlock_balance(rq, new_rq);
	raw_spin_unlock(&rq->lock);

	rq = cpu_rq(new_cpu);

+13 −7
Original line number Diff line number Diff line
@@ -8791,13 +8791,18 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
/*
 * detach_task() -- detach the task for the migration specified in env
 */
static void detach_task(struct task_struct *p, struct lb_env *env)
static void detach_task(struct task_struct *p, struct lb_env *env,
			struct rq_flags *rf)
{
	lockdep_assert_held(&env->src_rq->lock);

	p->on_rq = TASK_ON_RQ_MIGRATING;
	deactivate_task(env->src_rq, p, DEQUEUE_NOCLOCK);
	rq_unpin_lock(env->src_rq, rf);
	double_lock_balance(env->src_rq, env->dst_rq);
	set_task_cpu(p, env->dst_cpu);
	double_unlock_balance(env->src_rq, env->dst_rq);
	rq_repin_lock(env->src_rq, rf);
}

/*
@@ -8806,7 +8811,8 @@ static void detach_task(struct task_struct *p, struct lb_env *env)
 *
 * Returns a task if successful and NULL otherwise.
 */
static struct task_struct *detach_one_task(struct lb_env *env)
static struct task_struct *detach_one_task(struct lb_env *env,
					   struct rq_flags *rf)
{
	struct task_struct *p, *n;

@@ -8816,7 +8822,7 @@ static struct task_struct *detach_one_task(struct lb_env *env)
		if (!can_migrate_task(p, env))
			continue;

		detach_task(p, env);
		detach_task(p, env, rf);

		/*
		 * Right now, this is only the second place where
@@ -8838,7 +8844,7 @@ static const unsigned int sched_nr_migrate_break = 32;
 *
 * Returns number of detached tasks if successful and 0 otherwise.
 */
static int detach_tasks(struct lb_env *env)
static int detach_tasks(struct lb_env *env, struct rq_flags *rf)
{
	struct list_head *tasks = &env->src_rq->cfs_tasks;
	struct task_struct *p;
@@ -8883,7 +8889,7 @@ static int detach_tasks(struct lb_env *env)
		if ((load / 2) > env->imbalance)
			goto next;

		detach_task(p, env);
		detach_task(p, env, rf);
		list_add(&p->se.group_node, &env->tasks);

		detached++;
@@ -10421,7 +10427,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
		 * cur_ld_moved - load moved in current iteration
		 * ld_moved     - cumulative load moved across iterations
		 */
		cur_ld_moved = detach_tasks(&env);
		cur_ld_moved = detach_tasks(&env, &rf);

		/*
		 * We've detached some tasks from busiest_rq. Every
@@ -10848,7 +10854,7 @@ static int active_load_balance_cpu_stop(void *data)
		schedstat_inc(sd->alb_count);
		update_rq_clock(busiest_rq);

		p = detach_one_task(&env);
		p = detach_one_task(&env, &rf);
		if (p) {
			schedstat_inc(sd->alb_pushed);
			/* Active balancing done, reset the failure counter. */