From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757155Ab2IXQzE (ORCPT ); Mon, 24 Sep 2012 12:55:04 -0400 Received: from casper.infradead.org ([85.118.1.10]:42398 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756692Ab2IXQzC convert rfc822-to-8bit (ORCPT ); Mon, 24 Sep 2012 12:55:02 -0400 Message-ID: <1348505678.11847.110.camel@twins> Subject: Re: 20% performance drop on PostgreSQL 9.2 from kernel 3.5.3 to 3.6-rc5 on AMD chipsets - bisected From: Peter Zijlstra To: Linus Torvalds Cc: Mel Gorman , Borislav Petkov , Nikolay Ulyanitsky , Mike Galbraith , linux-kernel@vger.kernel.org, Andreas Herrmann , Andrew Morton , Thomas Gleixner , Ingo Molnar Date: Mon, 24 Sep 2012 18:54:38 +0200 In-Reply-To: References: <20120914212717.GA29307@liondog.tnic> <20120924150048.GB11266@suse.de> <1348500647.11847.69.camel@twins> <1348502863.11847.92.camel@twins> Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT X-Mailer: Evolution 3.2.2- Mime-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 2012-09-24 at 09:33 -0700, Linus Torvalds wrote: > Sure, the "scan bits" bitops will return ">= nr_cpu_ids" for the "I > couldn't find a bit" thing, but that doesn't mean that everything else > should. Fair enough.. --- kernel/sched/fair.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6b800a1..329f78d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2634,25 +2634,12 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) */ static int select_idle_sibling(struct task_struct *p, int target) { - int cpu = smp_processor_id(); - int prev_cpu = task_cpu(p); struct sched_domain *sd; struct sched_group *sg; int i; - /* - * If the task is going to be woken-up on this cpu and if it is - * already idle, then it is the right target. - */ - if (target == cpu && idle_cpu(cpu)) - return cpu; - - /* - * If the task is going to be woken-up on the cpu where it previously - * ran and if it is currently idle, then it the right target. - */ - if (target == prev_cpu && idle_cpu(prev_cpu)) - return prev_cpu; + if (idle_cpu(target)) + return target; /* * Otherwise, iterate the domains and find an elegible idle cpu. @@ -2661,18 +2648,31 @@ static int select_idle_sibling(struct task_struct *p, int target) for_each_lower_domain(sd) { sg = sd->groups; do { - if (!cpumask_intersects(sched_group_cpus(sg), - tsk_cpus_allowed(p))) - goto next; + int candidate = -1; + /* + * In the SMT case the groups are the SMT-siblings, + * otherwise they're singleton groups. + */ for_each_cpu(i, sched_group_cpus(sg)) { + if (!cpumask_test_cpu(i, tsk_cpus_allowed(p))) + continue; + + /* + * If any of the SMT-siblings are !idle, the + * core isn't idle. + */ if (!idle_cpu(i)) goto next; + + if (candidate < 0) + candidate = i; } - target = cpumask_first_and(sched_group_cpus(sg), - tsk_cpus_allowed(p)); - goto done; + if (candidate >= 0) { + target = candidate; + goto done; + } next: sg = sg->next; } while (sg != sd->groups);