From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932072Ab1EZQBk (ORCPT ); Thu, 26 May 2011 12:01:40 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:55131 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752519Ab1EZQBj (ORCPT ); Thu, 26 May 2011 12:01:39 -0400 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:mime-version:content-type :content-disposition:user-agent; b=oU6+jvUR0OPc1EU9qYl1PVeOcXC7woZaXVVMFJnCTWtHQz8DyvK865KMsu8nIPnK1S uVqKg55+0Cwljsy+7nDnI2D6l/Mlr8Z8W/bdeLavvSq6A6nXETGr/M3r+O8NPw23jhNu HN3SPwqjZW7/A+B43mmktd2kZ1Bdk7yYN+WfI= Date: Thu, 26 May 2011 19:01:37 +0300 From: Sergey Senozhatsky To: Ingo Molnar Cc: Peter Zijlstra , "Paul E. McKenney" , Andrew Morton , linux-kernel@vger.kernel.org Subject: [PATCH] sched_rt: RCU-protect for_each_domain() within find_lowest_rq() Message-ID: <20110526160137.GA5716@swordfish.minsk.epam.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Protect for_each_domain() within find_lowest_rq() with RCU read-side critical section, suppressing suspicious rcu_dereference_check(): [ 2752.503488] =================================================== [ 2752.503494] [ INFO: suspicious rcu_dereference_check() usage. ] [ 2752.503497] --------------------------------------------------- [ 2752.503501] kernel/sched_rt.c:1266 invoked rcu_dereference_check() without protection! [ 2752.503504] [ 2752.503505] other info that might help us debug this: [ 2752.503506] [ 2752.503510] rcu_scheduler_active = 1, debug_locks = 0 [ 2752.503514] 3 locks held by rcub0/9: [ 2752.503517] #0: (&lock->wait_lock){+.+...}, at: [] rt_mutex_slowlock+0x34/0x154 [ 2752.503534] #1: (&p->pi_lock){-.-.-.}, at: [] task_blocks_on_rt_mutex+0x124/0x1d1 [ 2752.503547] #2: (&rq->lock){-.-.-.}, at: [] rt_mutex_setprio+0x5f/0x252 [ 2752.503559] [ 2752.503569] Call Trace: [ 2752.503579] [] lockdep_rcu_dereference+0xa7/0xaf [ 2752.503587] [] find_lowest_rq+0x131/0x1ad [ 2752.503593] [] push_rt_task.part.133+0x89/0x247 [ 2752.503599] [] switched_to_rt+0x2a/0x65 [ 2752.503605] [] rt_mutex_setprio+0x1c8/0x252 [ 2752.503610] [] __rt_mutex_adjust_prio+0x1d/0x21 [ 2752.503616] [] task_blocks_on_rt_mutex+0x160/0x1d1 [ 2752.503622] [] rt_mutex_slowlock+0xbc/0x154 [ 2752.503629] [] rt_mutex_lock+0x12/0x14 [ 2752.503637] [] rcu_boost+0xad/0xe1 [ 2752.503644] [] ? _raw_spin_unlock_irqrestore+0x56/0x74 [ 2752.503652] [] ? finish_wait+0x5e/0x67 [ 2752.503657] [] rcu_boost_kthread+0xd3/0xfc [ 2752.503663] [] ? __init_waitqueue_head+0x46/0x46 [ 2752.503669] [] ? rcu_boost+0xe1/0xe1 [ 2752.503675] [] kthread+0x9a/0xa2 [ 2752.503683] [] kernel_thread_helper+0x4/0x10 [ 2752.503689] [] ? finish_task_switch+0x76/0xf0 [ 2752.503695] [] ? retint_restore_args+0x13/0x13 [ 2752.503701] [] ? __init_kthread_worker+0x53/0x53 [ 2752.503707] [] ? gs_change+0x13/0x13 Signed-off-by: Sergey Senozhatsky --- kernel/sched_rt.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 64b2a37..242e476 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1263,6 +1263,7 @@ static int find_lowest_rq(struct task_struct *task) if (!cpumask_test_cpu(this_cpu, lowest_mask)) this_cpu = -1; /* Skip this_cpu opt if not among lowest */ + rcu_read_lock(); for_each_domain(cpu, sd) { if (sd->flags & SD_WAKE_AFFINE) { int best_cpu; @@ -1272,15 +1273,20 @@ static int find_lowest_rq(struct task_struct *task) * remote processor. */ if (this_cpu != -1 && - cpumask_test_cpu(this_cpu, sched_domain_span(sd))) - return this_cpu; + cpumask_test_cpu(this_cpu, sched_domain_span(sd))) { + cpu = this_cpu; + goto out_unlock; + } best_cpu = cpumask_first_and(lowest_mask, sched_domain_span(sd)); - if (best_cpu < nr_cpu_ids) - return best_cpu; + if (best_cpu < nr_cpu_ids) { + cpu = best_cpu; + goto out_unlock; + } } } + rcu_read_unlock(); /* * And finally, if there were no matches within the domains @@ -1294,6 +1300,10 @@ static int find_lowest_rq(struct task_struct *task) if (cpu < nr_cpu_ids) return cpu; return -1; + +out_unlock: + rcu_read_unlock(); + return cpu; } /* Will lock the rq it finds */