From patchwork Wed Feb 3 14:02:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 61091 Delivered-To: patch@linaro.org Received: by 10.112.43.199 with SMTP id y7csp310138lbl; Wed, 3 Feb 2016 06:02:39 -0800 (PST) X-Received: by 10.98.13.150 with SMTP id 22mr2340255pfn.143.1454508159684; Wed, 03 Feb 2016 06:02:39 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ik8si9452130pac.235.2016.02.03.06.02.39; Wed, 03 Feb 2016 06:02:39 -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; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dkim=pass header.i=@linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932507AbcBCOCh (ORCPT + 30 others); Wed, 3 Feb 2016 09:02:37 -0500 Received: from mail-pa0-f50.google.com ([209.85.220.50]:34380 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755869AbcBCOCc (ORCPT ); Wed, 3 Feb 2016 09:02:32 -0500 Received: by mail-pa0-f50.google.com with SMTP id uo6so14338646pac.1 for ; Wed, 03 Feb 2016 06:02:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ay3079T98r9NE0oT4WqA2PGYUuHjwx4cOs4VYb9On18=; b=g+TotU+Z8r8iJws6Fqw2WZ/F0xFa3boqjH2iNyAzjHs0FiOsADhP9Ulk4lUcN+F1E9 P7JpcR1rgocbm+jut8OILWmpmjfoPOtNNQyUW50d67xmcYY43n9+O0FbHF0fjtl3McpH ChQXxfW3wHsrVwzw7rIADqFUUTA/by/IxLdTU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ay3079T98r9NE0oT4WqA2PGYUuHjwx4cOs4VYb9On18=; b=WddZh83wJlJHB48du8Zq2xAwDZP63J1r/+T1kYBXWUkiMz+aqlq5Ch/8RPEzHJPAw7 bjRJpAlczCfgEmX/NK7fjWsi5yvBvBS6wAH0mkFEvOBNWljBHOVuHPqmS4tYc/WJqo2G LJJmajt6nTqu5YVoMzYyE6v/yoorDANFBJOG8QMD62dz6Q3ySYt8DGXMUQGBMspW6sh8 R8nvqP1hSJVIv3UDqRd74kH33E3bfOrVl3KUEgXS6vAAqh9d7vpFDaz/+R9F3yBDdwDA cUYAN+mXuPS4Qkx0YFKYAzTOqC1Lm9jc/bDbnWRJRdEYq62JIZrzh7z67YiIBxxGQcEB a+qw== X-Gm-Message-State: AG10YOSGi7C3HJfC4LKyJ0piZo/sYKAuiA9l23xMMlRY2nkLSrF14PcuQbUFGg5lFEDB0yEP X-Received: by 10.66.102.70 with SMTP id fm6mr2403391pab.80.1454508152173; Wed, 03 Feb 2016 06:02:32 -0800 (PST) Received: from localhost ([122.172.22.246]) by smtp.gmail.com with ESMTPSA id u90sm10210820pfa.60.2016.02.03.06.02.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Feb 2016 06:02:31 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , juri.lelli@arm.com Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, skannan@codeaurora.org, peterz@infradead.org, mturquette@baylibre.com, steve.muckle@linaro.org, vincent.guittot@linaro.org, morten.rasmussen@arm.com, dietmar.eggemann@arm.com, linux-kernel@vger.kernel.org, Viresh Kumar Subject: [PATCH V2 1/7] cpufreq: governor: Treat min_sampling_rate as a governor-specific tunable Date: Wed, 3 Feb 2016 19:32:17 +0530 Message-Id: <92be8bede3340aa93549b468528f60244fbc50f2.1454507872.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.0.79.gdc08a19 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The min_sampling_rate governor tunable is a field in struct dbs_data, so it has to be handled in a special way separate from the rest of governor tunables. In particular, that requires a special macro to be present for creating its show/store sysfs attribute callbacks. However, there is no real need for the data structures and code in question to be arranged this way and if min_sampling_rate is moved to data structures holding the other governor tunables, the sysfs attribute creation macros that work with those tunables will also work with min_sampling_rate and the special macro for it won't be necessary any more. That will make it easier to modify the governor code going forward, so do it. [ Rafael: Written changelog ] Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq_conservative.c | 14 ++++++------- drivers/cpufreq/cpufreq_governor.c | 36 ++++++++++++++++++++-------------- drivers/cpufreq/cpufreq_governor.h | 18 ++--------------- drivers/cpufreq/cpufreq_ondemand.c | 14 ++++++------- 4 files changed, 37 insertions(+), 45 deletions(-) -- 2.7.0.79.gdc08a19 diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 606ad74abe6e..57750367bd26 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -185,7 +185,7 @@ static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, if (ret != 1) return -EINVAL; - cs_tuners->sampling_rate = max(input, dbs_data->min_sampling_rate); + cs_tuners->sampling_rate = max(input, cs_tuners->min_sampling_rate); return count; } @@ -281,7 +281,7 @@ show_store_one(cs, up_threshold); show_store_one(cs, down_threshold); show_store_one(cs, ignore_nice_load); show_store_one(cs, freq_step); -declare_show_sampling_rate_min(cs); +show_one(cs, min_sampling_rate); gov_sys_pol_attr_rw(sampling_rate); gov_sys_pol_attr_rw(sampling_down_factor); @@ -289,10 +289,10 @@ gov_sys_pol_attr_rw(up_threshold); gov_sys_pol_attr_rw(down_threshold); gov_sys_pol_attr_rw(ignore_nice_load); gov_sys_pol_attr_rw(freq_step); -gov_sys_pol_attr_ro(sampling_rate_min); +gov_sys_pol_attr_ro(min_sampling_rate); static struct attribute *dbs_attributes_gov_sys[] = { - &sampling_rate_min_gov_sys.attr, + &min_sampling_rate_gov_sys.attr, &sampling_rate_gov_sys.attr, &sampling_down_factor_gov_sys.attr, &up_threshold_gov_sys.attr, @@ -308,7 +308,7 @@ static struct attribute_group cs_attr_group_gov_sys = { }; static struct attribute *dbs_attributes_gov_pol[] = { - &sampling_rate_min_gov_pol.attr, + &min_sampling_rate_gov_pol.attr, &sampling_rate_gov_pol.attr, &sampling_down_factor_gov_pol.attr, &up_threshold_gov_pol.attr, @@ -340,10 +340,10 @@ static int cs_init(struct dbs_data *dbs_data, bool notify) tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; tuners->ignore_nice_load = 0; tuners->freq_step = DEF_FREQUENCY_STEP; + tuners->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * + jiffies_to_usecs(10); dbs_data->tuners = tuners; - dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * - jiffies_to_usecs(10); if (notify) cpufreq_register_notifier(&cs_cpufreq_notifier_block, diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index e0d111024d48..9a7edc91ad57 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -286,16 +286,32 @@ static void dbs_timer_handler(unsigned long data) queue_work(system_wq, &shared->work); } -static void set_sampling_rate(struct dbs_data *dbs_data, - unsigned int sampling_rate) +static void set_sampling_rate(struct cpufreq_policy *policy, + struct dbs_data *dbs_data) { + unsigned int *sampling_rate; + unsigned int *min_sampling_rate; + unsigned int latency; + + /* policy latency is in ns. Convert it to us first */ + latency = policy->cpuinfo.transition_latency / 1000; + if (latency == 0) + latency = 1; + if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - cs_tuners->sampling_rate = sampling_rate; + sampling_rate = &cs_tuners->sampling_rate; + min_sampling_rate = &cs_tuners->min_sampling_rate; } else { struct od_dbs_tuners *od_tuners = dbs_data->tuners; - od_tuners->sampling_rate = sampling_rate; + sampling_rate = &od_tuners->sampling_rate; + min_sampling_rate = &od_tuners->min_sampling_rate; } + + /* Bring kernel and HW constraints together */ + *min_sampling_rate = max(*min_sampling_rate, + MIN_LATENCY_MULTIPLIER * latency); + *sampling_rate = max(*min_sampling_rate, latency * LATENCY_MULTIPLIER); } static int alloc_common_dbs_info(struct cpufreq_policy *policy, @@ -338,7 +354,6 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy, struct dbs_data *dbs_data, struct common_dbs_data *cdata) { - unsigned int latency; int ret; /* State should be equivalent to EXIT */ @@ -373,16 +388,7 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy, if (ret) goto free_common_dbs_info; - /* policy latency is in ns. Convert it to us first */ - latency = policy->cpuinfo.transition_latency / 1000; - if (latency == 0) - latency = 1; - - /* Bring kernel and HW constraints together */ - dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate, - MIN_LATENCY_MULTIPLIER * latency); - set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate, - latency * LATENCY_MULTIPLIER)); + set_sampling_rate(policy, dbs_data); if (!have_governor_per_policy()) cdata->gdbs_data = dbs_data; diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 91e767a058a7..ad44a8546a3a 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -183,6 +183,7 @@ struct od_dbs_tuners { unsigned int up_threshold; unsigned int powersave_bias; unsigned int io_is_busy; + unsigned int min_sampling_rate; }; struct cs_dbs_tuners { @@ -192,6 +193,7 @@ struct cs_dbs_tuners { unsigned int up_threshold; unsigned int down_threshold; unsigned int freq_step; + unsigned int min_sampling_rate; }; /* Common Governor data across policies */ @@ -230,7 +232,6 @@ struct common_dbs_data { /* Governor Per policy data */ struct dbs_data { struct common_dbs_data *cdata; - unsigned int min_sampling_rate; int usage_count; void *tuners; }; @@ -254,21 +255,6 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate) return delay; } -#define declare_show_sampling_rate_min(_gov) \ -static ssize_t show_sampling_rate_min_gov_sys \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ - return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ -} \ - \ -static ssize_t show_sampling_rate_min_gov_pol \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - struct dbs_data *dbs_data = policy->governor_data; \ - return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ -} - extern struct mutex cpufreq_governor_lock; void gov_add_timers(struct cpufreq_policy *policy, unsigned int delay); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index eae51070c034..b31f64745232 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -250,7 +250,7 @@ static void update_sampling_rate(struct dbs_data *dbs_data, int cpu; od_tuners->sampling_rate = new_rate = max(new_rate, - dbs_data->min_sampling_rate); + od_tuners->min_sampling_rate); /* * Lock governor so that governor start/stop can't execute in parallel. @@ -442,7 +442,7 @@ show_store_one(od, up_threshold); show_store_one(od, sampling_down_factor); show_store_one(od, ignore_nice_load); show_store_one(od, powersave_bias); -declare_show_sampling_rate_min(od); +show_one(od, min_sampling_rate); gov_sys_pol_attr_rw(sampling_rate); gov_sys_pol_attr_rw(io_is_busy); @@ -450,10 +450,10 @@ gov_sys_pol_attr_rw(up_threshold); gov_sys_pol_attr_rw(sampling_down_factor); gov_sys_pol_attr_rw(ignore_nice_load); gov_sys_pol_attr_rw(powersave_bias); -gov_sys_pol_attr_ro(sampling_rate_min); +gov_sys_pol_attr_ro(min_sampling_rate); static struct attribute *dbs_attributes_gov_sys[] = { - &sampling_rate_min_gov_sys.attr, + &min_sampling_rate_gov_sys.attr, &sampling_rate_gov_sys.attr, &up_threshold_gov_sys.attr, &sampling_down_factor_gov_sys.attr, @@ -469,7 +469,7 @@ static struct attribute_group od_attr_group_gov_sys = { }; static struct attribute *dbs_attributes_gov_pol[] = { - &sampling_rate_min_gov_pol.attr, + &min_sampling_rate_gov_pol.attr, &sampling_rate_gov_pol.attr, &up_threshold_gov_pol.attr, &sampling_down_factor_gov_pol.attr, @@ -509,12 +509,12 @@ static int od_init(struct dbs_data *dbs_data, bool notify) * not depending on HZ, but fixed (very low). The deferred * timer might skip some samples if idle/sleeping as needed. */ - dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; + tuners->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; } else { tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; /* For correct statistics, we need 10 ticks for each measure */ - dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * + tuners->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10); }