From patchwork Mon Mar 3 07:48:50 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 25588 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f198.google.com (mail-pd0-f198.google.com [209.85.192.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D024B20540 for ; Mon, 3 Mar 2014 07:49:42 +0000 (UTC) Received: by mail-pd0-f198.google.com with SMTP id fp1sf9217581pdb.1 for ; Sun, 02 Mar 2014 23:49:41 -0800 (PST) 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; bh=7H5bQa7iFr4pyHoVxEFH5Oc17AR+TeO8P3cQzV2ZZog=; b=kTmujVQfp3H6OYDyrmCqTm1dntFqqoujXrTvNcxFu4e5yZUzCTbUfKKxWsqYaL0bov /4J3+oBZ7YoZp49KhDrV+WXVm5okUcDcmKAZ48U1es9J4wAB054KaqZV+AFdxl9jcEIq wiGF7HEx9N2d7P5KukZLdYR8/uacQ5k14l+IOr7DQps6/kdVnn621xN9Q5RYZQYCQ+oA 5KueLZ6tJ0FF1JgetKMGyASVfJj80JR8sN/yUOTlHhMgBIMc0TPUk8X0yy8dNC2EJYW9 nJGLH5obC+sd/7G6sil0FvI2ZC5RvhgHWGvo8GSvtLwi1rjBk0txJriytEtRrK2d499N uQ7Q== X-Gm-Message-State: ALoCoQm8xAOEnV+6v7y3/2HP+El5YACgQkj7xKW6rLjsxg/heWLWu/7P2U6Kl8OraCzNBnLGKqNJ X-Received: by 10.68.201.7 with SMTP id jw7mr7656007pbc.8.1393832981387; Sun, 02 Mar 2014 23:49:41 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.92.65 with SMTP id a59ls2053067qge.72.gmail; Sun, 02 Mar 2014 23:49:41 -0800 (PST) X-Received: by 10.52.75.101 with SMTP id b5mr132390vdw.40.1393832981179; Sun, 02 Mar 2014 23:49:41 -0800 (PST) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id i3si4441825vcp.127.2014.03.02.23.49.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Mar 2014 23:49:41 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.176 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id la4so3238340vcb.35 for ; Sun, 02 Mar 2014 23:49:41 -0800 (PST) X-Received: by 10.58.200.229 with SMTP id jv5mr15754321vec.15.1393832981086; Sun, 02 Mar 2014 23:49:41 -0800 (PST) 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.220.130.193 with SMTP id u1csp36224vcs; Sun, 2 Mar 2014 23:49:40 -0800 (PST) X-Received: by 10.66.156.137 with SMTP id we9mr18315290pab.30.1393832979793; Sun, 02 Mar 2014 23:49:39 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id yo5si9699256pab.63.2014.03.02.23.49.32; Sun, 02 Mar 2014 23:49:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753625AbaCCHtT (ORCPT + 26 others); Mon, 3 Mar 2014 02:49:19 -0500 Received: from mail-pa0-f41.google.com ([209.85.220.41]:65235 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753199AbaCCHtK (ORCPT ); Mon, 3 Mar 2014 02:49:10 -0500 Received: by mail-pa0-f41.google.com with SMTP id hz1so760242pad.28 for ; Sun, 02 Mar 2014 23:49:10 -0800 (PST) X-Received: by 10.66.149.231 with SMTP id ud7mr18381909pab.8.1393832950264; Sun, 02 Mar 2014 23:49:10 -0800 (PST) Received: from localhost.localdomain (z88l218.static.ctm.net. [202.175.88.218]) by mx.google.com with ESMTPSA id os1sm78855252pac.20.2014.03.02.23.49.04 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Mar 2014 23:49:09 -0800 (PST) From: Daniel Lezcano To: peterz@infradead.org, mingo@kernel.org, tglx@linutronix.de, rjw@rjwysocki.net Cc: nicolas.pitre@linaro.org, preeti@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org Subject: [PATCH V4 1/5] idle/cpuidle: Split cpuidle_idle_call main function into smaller functions Date: Mon, 3 Mar 2014 08:48:50 +0100 Message-Id: <1393832934-11625-1-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <20140228125604.GN27965@twins.programming.kicks-ass.net> References: <20140228125604.GN27965@twins.programming.kicks-ass.net> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: daniel.lezcano@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.176 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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: , In order to allow better integration between the cpuidle framework and the scheduler, reducing the distance between these two sub-components will facilitate this integration by moving part of the cpuidle code in the idle task file and, because idle.c is in the sched directory, we have access to the scheduler's private structures. This patch splits the cpuidle_idle_call main entry function into 3 calls to a newly added API: 1. select the idle state 2. enter the idle state 3. reflect the idle state The cpuidle_idle_call calls these three functions to implement the main idle entry function. Signed-off-by: Daniel Lezcano Acked-by: Nicolas Pitre --- ChangeLog: V4: * rebased on top of tip/master V3: * moved broadcast timer outside of cpuidle_enter() as suggested by Preeti U Murthy : https://lkml.org/lkml/2014/2/24/601 V2: * splitted cpuidle_select error check into 'cpuidle_enabled' function --- drivers/cpuidle/cpuidle.c | 96 +++++++++++++++++++++++++++++++++++----------- include/linux/cpuidle.h | 19 +++++++++ 2 files changed, 94 insertions(+), 21 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ Index: cpuidle-next/drivers/cpuidle/cpuidle.c =================================================================== --- cpuidle-next.orig/drivers/cpuidle/cpuidle.c +++ cpuidle-next/drivers/cpuidle/cpuidle.c @@ -65,6 +65,26 @@ int cpuidle_play_dead(void) } /** + * cpuidle_enabled - check if the cpuidle framework is ready + * @dev: cpuidle device for this cpu + * @drv: cpuidle driver for this cpu + * + * Return 0 on success, otherwise: + * -NODEV : the cpuidle framework is not available + * -EBUSY : the cpuidle framework is not initialized + */ +int cpuidle_enabled(struct cpuidle_driver *drv, struct cpuidle_device *dev) +{ + if (off || !initialized) + return -ENODEV; + + if (!drv || !dev || !dev->enabled) + return -EBUSY; + + return 0; +} + +/** * cpuidle_enter_state - enter the state and update stats * @dev: cpuidle device for this cpu * @drv: cpuidle driver for this cpu @@ -108,6 +128,51 @@ int cpuidle_enter_state(struct cpuidle_d } /** + * cpuidle_select - ask the cpuidle framework to choose an idle state + * + * @drv: the cpuidle driver + * @dev: the cpuidle device + * + * Returns the index of the idle state. + */ +int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) +{ + return cpuidle_curr_governor->select(drv, dev); +} + +/** + * cpuidle_enter - enter into the specified idle state + * + * @drv: the cpuidle driver tied with the cpu + * @dev: the cpuidle device + * @index: the index in the idle state table + * + * Returns the index in the idle state, < 0 in case of error. + * The error code depends on the backend driver + */ +int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev, + int index) +{ + if (cpuidle_state_is_coupled(dev, drv, index)) + return cpuidle_enter_state_coupled(dev, drv, index); + return cpuidle_enter_state(dev, drv, index); +} + +/** + * cpuidle_reflect - tell the underlying governor what was the state + * we were in + * + * @dev : the cpuidle device + * @index: the index in the idle state table + * + */ +void cpuidle_reflect(struct cpuidle_device *dev, int index) +{ + if (cpuidle_curr_governor->reflect) + cpuidle_curr_governor->reflect(dev, index); +} + +/** * cpuidle_idle_call - the main idle loop * * NOTE: no locks or semaphores should be used here @@ -116,26 +181,21 @@ int cpuidle_enter_state(struct cpuidle_d int cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv; - int next_state, entered_state; + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); + int next_state, entered_state, ret; bool broadcast; - if (off || !initialized) - return -ENODEV; - - /* check if the device is ready */ - if (!dev || !dev->enabled) - return -EBUSY; - - drv = cpuidle_get_cpu_driver(dev); + ret = cpuidle_enabled(drv, dev); + if (ret < 0) + return ret; /* ask the governor for the next state */ - next_state = cpuidle_curr_governor->select(drv, dev); + next_state = cpuidle_select(drv, dev); + if (need_resched()) { dev->last_residency = 0; /* give the governor an opportunity to reflect on the outcome */ - if (cpuidle_curr_governor->reflect) - cpuidle_curr_governor->reflect(dev, next_state); + cpuidle_reflect(dev, next_state); local_irq_enable(); return 0; } @@ -146,14 +206,9 @@ int cpuidle_idle_call(void) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu)) return -EBUSY; - trace_cpu_idle_rcuidle(next_state, dev->cpu); - if (cpuidle_state_is_coupled(dev, drv, next_state)) - entered_state = cpuidle_enter_state_coupled(dev, drv, - next_state); - else - entered_state = cpuidle_enter_state(dev, drv, next_state); + entered_state = cpuidle_enter(drv, dev, next_state); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); @@ -161,8 +216,7 @@ int cpuidle_idle_call(void) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); /* give the governor an opportunity to reflect on the outcome */ - if (cpuidle_curr_governor->reflect) - cpuidle_curr_governor->reflect(dev, entered_state); + cpuidle_reflect(dev, entered_state); return 0; } Index: cpuidle-next/include/linux/cpuidle.h =================================================================== --- cpuidle-next.orig/include/linux/cpuidle.h +++ cpuidle-next/include/linux/cpuidle.h @@ -119,6 +119,15 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern void disable_cpuidle(void); + +extern int cpuidle_enabled(struct cpuidle_driver *drv, + struct cpuidle_device *dev); +extern int cpuidle_select(struct cpuidle_driver *drv, + struct cpuidle_device *dev); +extern int cpuidle_enter(struct cpuidle_driver *drv, + struct cpuidle_device *dev, int index); +extern void cpuidle_reflect(struct cpuidle_device *dev, int index); + extern int cpuidle_idle_call(void); extern int cpuidle_register_driver(struct cpuidle_driver *drv); extern struct cpuidle_driver *cpuidle_get_driver(void); @@ -141,6 +150,16 @@ extern int cpuidle_play_dead(void); extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); #else static inline void disable_cpuidle(void) { } +static inline int cpuidle_enabled(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } +static inline int cpuidle_select(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } +static inline int cpuidle_enter(struct cpuidle_driver *drv, + struct cpuidle_device *dev, int index) +{return -ENODEV; } +static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { } static inline int cpuidle_idle_call(void) { return -ENODEV; } static inline int cpuidle_register_driver(struct cpuidle_driver *drv) {return -ENODEV; }