From patchwork Thu Sep 4 15:32:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 36726 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f197.google.com (mail-qc0-f197.google.com [209.85.216.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 844C120CBB for ; Thu, 4 Sep 2014 15:48:26 +0000 (UTC) Received: by mail-qc0-f197.google.com with SMTP id c9sf31241878qcz.8 for ; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe :content-transfer-encoding; bh=BUNHf0ypFG4o/FL18VWRTNBnEUbzlxyVcaCp4EgBp8w=; b=W47D1h1dWARDut3zHCnqJaO2Pc5eoAEVoY9a/7HrDeDCSNg7JbZbtaA29v4eCa6GrO QMlohE5T2rzsCwOpMNfnuV2cqrjHJtucMgMun/tHlDYMqHKNRaikHZOo0acyUtj5YTng 46obp5eySksTUqWriI0KW3VppC6I+O5J5WJ7yUv355gFFWzNtFIPnX1bw9TLxjKfRVY3 Zu+C7jhdlrnrEsQVYLG/aIINlhBB5bm26Se75DkSsfIKstqcEdHWRxl8GL7PmQ8u0CDW MoYV71UtMRUhWDOUbybZaHx0NDvzDStMDRrJgKTbIFL1/2DXvozinS9EeYSFJCiV1cP3 X09Q== X-Gm-Message-State: ALoCoQkOkQ+i4SHz8mzFP/MIJ55r+4nxCiI+dIq8ZorY0x83D8MYpAZvQ4I8fkExuzir6DxH2Vse X-Received: by 10.224.67.135 with SMTP id r7mr2884631qai.5.1409845706406; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.49.41 with SMTP id p38ls212071qga.55.gmail; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) X-Received: by 10.220.97.5 with SMTP id j5mr5021024vcn.16.1409845706197; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) Received: from mail-vc0-f172.google.com (mail-vc0-f172.google.com [209.85.220.172]) by mx.google.com with ESMTPS id cr2si5968655vcb.8.2014.09.04.08.48.26 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 04 Sep 2014 08:48:26 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.172 as permitted sender) client-ip=209.85.220.172; Received: by mail-vc0-f172.google.com with SMTP id ij19so10847793vcb.31 for ; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) X-Received: by 10.220.187.134 with SMTP id cw6mr2293618vcb.71.1409845706106; Thu, 04 Sep 2014 08:48:26 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp858995vcb; Thu, 4 Sep 2014 08:48:25 -0700 (PDT) X-Received: by 10.66.221.193 with SMTP id qg1mr10103510pac.9.1409845705126; Thu, 04 Sep 2014 08:48:25 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id tk2si4435221pac.83.2014.09.04.08.48.19 for ; Thu, 04 Sep 2014 08:48:19 -0700 (PDT) Received-SPF: none (google.com: linux-pm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750776AbaIDPsB (ORCPT + 15 others); Thu, 4 Sep 2014 11:48:01 -0400 Received: from relais.videotron.ca ([24.201.245.36]:60017 "EHLO relais.videotron.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754193AbaIDPr7 (ORCPT ); Thu, 4 Sep 2014 11:47:59 -0400 X-Greylist: delayed 918 seconds by postgrey-1.27 at vger.kernel.org; Thu, 04 Sep 2014 11:47:57 EDT Received: from yoda.home ([66.130.143.177]) by VL-VM-MR001.ip.videotron.ca (Oracle Communications Messaging Exchange Server 7u4-22.01 64bit (built Apr 21 2011)) with ESMTP id <0NBD00IA6V6ETKE0@VL-VM-MR001.ip.videotron.ca>; Thu, 04 Sep 2014 11:32:38 -0400 (EDT) Received: from xanadu.home (xanadu.home [192.168.2.2]) by yoda.home (Postfix) with ESMTP id 7F2992DA08B8; Thu, 04 Sep 2014 11:32:38 -0400 (EDT) From: Nicolas Pitre To: Peter Zijlstra , Ingo Molnar Cc: Daniel Lezcano , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org Subject: [PATCH v2 2/2] sched/fair: leverage the idle state info when choosing the "idlest" cpu Date: Thu, 04 Sep 2014 11:32:10 -0400 Message-id: <1409844730-12273-3-git-send-email-nicolas.pitre@linaro.org> X-Mailer: git-send-email 1.8.4.108.g55ea5f6 In-reply-to: <1409844730-12273-1-git-send-email-nicolas.pitre@linaro.org> References: <1409844730-12273-1-git-send-email-nicolas.pitre@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: nicolas.pitre@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.172 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Content-transfer-encoding: 7BIT The code in find_idlest_cpu() looks for the CPU with the smallest load. However, if multiple CPUs are idle, the first idle CPU is selected irrespective of the depth of its idle state. Among the idle CPUs we should pick the one with with the shallowest idle state, or the latest to have gone idle if all idle CPUs are in the same state. The later applies even when cpuidle is configured out. This patch doesn't cover the following issues: - The idle exit latency of a CPU might be larger than the time needed to migrate the waking task to an already running CPU with sufficient capacity, and therefore performance would benefit from task packing in such case (in most cases task packing is about power saving). - Some idle states have a non negligible and non abortable entry latency which needs to run to completion before the exit latency can start. A concurrent patch series is making this info available to the cpuidle core. Once available, the entry latency with the idle timestamp could determine when the exit latency may be effective. Those issues will be handled in due course. In the mean time, what is implemented here should improve things already compared to the current state of affairs. Based on an initial patch from Daniel Lezcano. Signed-off-by: Nicolas Pitre Acked-by: Daniel Lezcano --- kernel/sched/fair.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index bfa3c86d0d..416329e1a6 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -4428,20 +4429,48 @@ static int find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) { unsigned long load, min_load = ULONG_MAX; - int idlest = -1; + unsigned int min_exit_latency = UINT_MAX; + u64 latest_idle_timestamp = 0; + int least_loaded_cpu = this_cpu; + int shallowest_idle_cpu = -1; int i; /* Traverse only the allowed CPUs */ for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) { - load = weighted_cpuload(i); - - if (load < min_load || (load == min_load && i == this_cpu)) { - min_load = load; - idlest = i; + if (idle_cpu(i)) { + struct rq *rq = cpu_rq(i); + struct cpuidle_state *idle = idle_get_state(rq); + if (idle && idle->exit_latency < min_exit_latency) { + /* + * We give priority to a CPU whose idle state + * has the smallest exit latency irrespective + * of any idle timestamp. + */ + min_exit_latency = idle->exit_latency; + latest_idle_timestamp = rq->idle_stamp; + shallowest_idle_cpu = i; + } else if ((!idle || idle->exit_latency == min_exit_latency) && + rq->idle_stamp > latest_idle_timestamp) { + /* + * If equal or no active idle state, then + * the most recently idled CPU might have + * a warmer cache. + */ + latest_idle_timestamp = rq->idle_stamp; + shallowest_idle_cpu = i; + } + cpuidle_put_state(rq); + } else { + load = weighted_cpuload(i); + if (load < min_load || + (load == min_load && i == this_cpu)) { + min_load = load; + least_loaded_cpu = i; + } } } - return idlest; + return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu; } /*