From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932187AbbHMVaN (ORCPT ); Thu, 13 Aug 2015 17:30:13 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:42948 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932120AbbHMVaJ (ORCPT ); Thu, 13 Aug 2015 17:30:09 -0400 Date: Thu, 13 Aug 2015 23:30:03 +0200 From: Peter Zijlstra To: Sasha Levin Cc: hpa@zytor.com, torvalds@linux-foundation.org, efault@gmx.de, tglx@linutronix.de, linux-kernel@vger.kernel.org, mingo@kernel.org, linux-tip-commits@vger.kernel.org Subject: Re: [tip:sched/core] sched: Change the sched_class::set_cpus_allowed( ) calling context Message-ID: <20150813213003.GI16853@twins.programming.kicks-ass.net> References: <20150515154833.667516139@infradead.org> <55CCE638.3030907@oracle.com> <20150813203732.GF16853@twins.programming.kicks-ass.net> <55CD0515.3090404@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <55CD0515.3090404@oracle.com> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 13, 2015 at 04:59:01PM -0400, Sasha Levin wrote: > Seems to work fine now, thanks! I've no clue how this doesn't also explode on actual hardware, that code is convoluted, read and weep. Ingo, please stick somewhere appropriate :-) --- Subject: sched: Avoid trying to dequeue/enqueue the idle thread From: Peter Zijlstra Date: Thu Aug 13 23:09:29 CEST 2015 Sasha reports that his virtual machine tries to schedule the idle thread since commit 6c37067e2786 ("sched: Change the sched_class::set_cpus_allowed() calling context"). His trace shows this happening from idle_thread_get()->init_idle(), which is the _second_ init_idle() invocation on that task_struct, the first being done through idle_init()->fork_idle(). (this code is insane...) Because we call init_idle() twice in a row, its ->sched_class == &idle_sched_class and ->on_rq = TASK_ON_RQ_QUEUED. This means do_set_cpus_allowed() thinks we're queued and will call dequeue_task(), which is implemented with BUG() for the idle class, seeing how dequeueing the idle task is a daft thing. Aside of the whole insanity of calling init_idle() _twice_, change the code to call set_cpus_allowed_common() instead as this is 'obviously' before the idle task gets ran etc.. Fixes: 6c37067e2786 ("sched: Change the sched_class::set_cpus_allowed() calling context") Reported-by: Sasha Levin Tested-by: Sasha Levin Signed-off-by: Peter Zijlstra (Intel) --- kernel/sched/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4924,7 +4924,7 @@ void init_idle(struct task_struct *idle, idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); - do_set_cpus_allowed(idle, cpumask_of(cpu)); + set_cpus_allowed_common(idle, cpumask_of(cpu)); /* * We're having a chicken and egg problem, even though we are * holding rq->lock, the cpu isn't yet set to this cpu so the