From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965413AbbJ0Rcm (ORCPT ); Tue, 27 Oct 2015 13:32:42 -0400 Received: from mail-wi0-f172.google.com ([209.85.212.172]:34460 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965365AbbJ0Rci (ORCPT ); Tue, 27 Oct 2015 13:32:38 -0400 From: =?UTF-8?q?B=C3=A1lint=20Czobor?= To: "Rafael J. Wysocki" , Viresh Kumar Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Todd Poynor , =?UTF-8?q?B=C3=A1lint=20Czobor?= Subject: [PATCH 32/70] cpufreq: interactive: specify duration of CPU speed boost pulse Date: Tue, 27 Oct 2015 18:30:20 +0100 Message-Id: <1445967059-6897-32-git-send-email-czoborbalint@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1445967059-6897-1-git-send-email-czoborbalint@gmail.com> References: <1445967059-6897-1-git-send-email-czoborbalint@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Todd Poynor Sysfs attribute boostpulse_duration specifies the duration of boosting CPU speed in response to bootpulse events. Duration is specified in usecs, default 80ms. Change-Id: Ifd41625574891a44f1787a4e85d1e7b4f2afb52b Signed-off-by: Todd Poynor Signed-off-by: Bálint Czobor --- drivers/cpufreq/cpufreq_interactive.c | 52 ++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index d0d51ee..8b44a82 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -95,11 +95,12 @@ static unsigned long timer_rate; #define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE static unsigned long above_hispeed_delay_val; -/* - * Non-zero means longer-term speed boost active. - */ - +/* Non-zero means indefinite speed boost active */ static int boost_val; +/* Duration of a boot pulse in usecs */ +static int boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME; +/* End time of boost pulse in ktime converted to usecs */ +static u64 boostpulse_endtime; static bool governidle; module_param(governidle, bool, S_IWUSR | S_IRUGO); @@ -268,6 +269,7 @@ static void cpufreq_interactive_timer(unsigned long data) unsigned int loadadjfreq; unsigned int index; unsigned long flags; + bool boosted; smp_rmb(); @@ -286,8 +288,9 @@ static void cpufreq_interactive_timer(unsigned long data) do_div(cputime_speedadj, delta_time); loadadjfreq = (unsigned int)cputime_speedadj * 100; cpu_load = loadadjfreq / pcpu->target_freq; + boosted = boost_val || now < boostpulse_endtime; - if ((cpu_load >= go_hispeed_load || boost_val) && + if ((cpu_load >= go_hispeed_load || boosted) && pcpu->target_freq < hispeed_freq) new_freq = hispeed_freq; else @@ -327,8 +330,18 @@ static void cpufreq_interactive_timer(unsigned long data) } } - pcpu->floor_freq = new_freq; - pcpu->floor_validate_time = now; + /* + * Update the timestamp for checking whether speed has been held at + * or above the selected frequency for a minimum of min_sample_time, + * if not boosted to hispeed_freq. If boosted to hispeed_freq then we + * allow the speed to drop as soon as the boostpulse duration expires + * (or the indefinite boost is turned off). + */ + + if (!boosted || new_freq > hispeed_freq) { + pcpu->floor_freq = new_freq; + pcpu->floor_validate_time = now; + } if (pcpu->target_freq == new_freq) { trace_cpufreq_interactive_already( @@ -774,6 +787,7 @@ static ssize_t store_boostpulse(struct kobject *kobj, struct attribute *attr, if (ret < 0) return ret; + boostpulse_endtime = ktime_to_us(ktime_get()) + boostpulse_duration_val; trace_cpufreq_interactive_boost("pulse"); cpufreq_interactive_boost(); return count; @@ -782,6 +796,29 @@ static ssize_t store_boostpulse(struct kobject *kobj, struct attribute *attr, static struct global_attr boostpulse = __ATTR(boostpulse, 0200, NULL, store_boostpulse); +static ssize_t show_boostpulse_duration( + struct kobject *kobj, struct attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", boostpulse_duration_val); +} + +static ssize_t store_boostpulse_duration( + struct kobject *kobj, struct attribute *attr, const char *buf, + size_t count) +{ + int ret; + unsigned long val; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + boostpulse_duration_val = val; + return count; +} + +define_one_global_rw(boostpulse_duration); + static struct attribute *interactive_attributes[] = { &target_loads_attr.attr, &hispeed_freq_attr.attr, @@ -791,6 +828,7 @@ static struct attribute *interactive_attributes[] = { &timer_rate_attr.attr, &boost.attr, &boostpulse.attr, + &boostpulse_duration.attr, NULL, }; -- 1.7.9.5