From patchwork Wed Jan 30 13:00:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Baltieri X-Patchwork-Id: 2067421 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 551E0DF264 for ; Wed, 30 Jan 2013 13:00:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753398Ab3A3NAe (ORCPT ); Wed, 30 Jan 2013 08:00:34 -0500 Received: from mail-ea0-f172.google.com ([209.85.215.172]:44564 "EHLO mail-ea0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753427Ab3A3NAb (ORCPT ); Wed, 30 Jan 2013 08:00:31 -0500 Received: by mail-ea0-f172.google.com with SMTP id f13so698559eaa.3 for ; Wed, 30 Jan 2013 05:00:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=Hl69C5fllsP+p5v1m7dygcXfpKf8uDfgWK4FVbJQzNg=; b=O6/O0ko0Uw/1w7JCbG5MBoHvDnFJ7YUMqw3Xl9qRfSazmE7DOOr1bAvjeh5OtwdYGy 5DO2V9wyoLe65pfoHo2v/WIw8myO6ibu4BJeBEuZLxTxCzrabEI8YW6an93CPrYZ1pcP gKzlQjEB2TrcCeWFQ4uRpdi8GZmgW4F24MnQ3vvqI/uBXqfGWc+RFpUfk8egstMHtBOC VxPgriF3/TyP6mw9H8J47qTNa2po27N8L9IwVg1NEGUJ+lAWEPW/MndtIckY5eKnX1km PwNPTT5J+8cvc33E/jgBiYLyNhclttJ+EhF0BAPw6gKpIwK4xiqbGVukzju06LSKWPW3 +bXQ== X-Received: by 10.14.211.137 with SMTP id w9mr14505432eeo.39.1359550829596; Wed, 30 Jan 2013 05:00:29 -0800 (PST) Received: from localhost ([2a01:2003:1:1e91:8e70:5aff:feac:ad8]) by mx.google.com with ESMTPS id h5sm1913733eem.1.2013.01.30.05.00.21 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 30 Jan 2013 05:00:28 -0800 (PST) From: Fabio Baltieri To: "Rafael J. Wysocki" , cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, Viresh Kumar Cc: Linus Walleij , swarren@wwwdotorg.org, linaro-dev@lists.linaro.org, Nicolas Pitre , mathieu.poirier@linaro.org, Joseph Lo , linux-kernel@vger.kernel.org, Rickard Andersson , Fabio Baltieri Subject: [PATCH v7 1/4] cpufreq: handle SW coordinated CPUs Date: Wed, 30 Jan 2013 14:00:00 +0100 Message-Id: <1359550803-18577-2-git-send-email-fabio.baltieri@linaro.org> X-Mailer: git-send-email 1.7.12.1 In-Reply-To: <1359550803-18577-1-git-send-email-fabio.baltieri@linaro.org> References: <1359550803-18577-1-git-send-email-fabio.baltieri@linaro.org> X-Gm-Message-State: ALoCoQl/AhQa2O4/Y7BbvETS1wFEoi5DgSnMGlROZGLoCLURBWoyHw5S8/4rqbY5WRIsyyjGLBqC Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Rickard Andersson This patch fixes a bug that occurred when we had load on a secondary CPU and the primary CPU was sleeping. Only one sampling timer was spawned and it was spawned as a deferred timer on the primary CPU, so when a secondary CPU had a change in load this was not detected by the cpufreq governor (both ondemand and conservative). This patch make sure that deferred timers are run on all CPUs in the case of software controlled CPUs that run on the same frequency. Signed-off-by: Rickard Andersson Signed-off-by: Fabio Baltieri --- drivers/cpufreq/cpufreq_conservative.c | 3 ++- drivers/cpufreq/cpufreq_governor.c | 31 +++++++++++++++++++++++-------- drivers/cpufreq/cpufreq_governor.h | 1 + drivers/cpufreq/cpufreq_ondemand.c | 3 ++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 64ef737..b9d7f14 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -122,7 +122,8 @@ static void cs_dbs_timer(struct work_struct *work) dbs_check_cpu(&cs_dbs_data, cpu); - schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay); + schedule_delayed_work_on(smp_processor_id(), &dbs_info->cdbs.work, + delay); mutex_unlock(&dbs_info->cdbs.timer_mutex); } diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 6c5f1d3..8393d6e 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -161,17 +161,27 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) } EXPORT_SYMBOL_GPL(dbs_check_cpu); -static inline void dbs_timer_init(struct dbs_data *dbs_data, - struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate) +bool dbs_sw_coordinated_cpus(struct cpu_dbs_common_info *cdbs) +{ + struct cpufreq_policy *policy = cdbs->cur_policy; + + return cpumask_weight(policy->cpus) > 1; +} +EXPORT_SYMBOL_GPL(dbs_sw_coordinated_cpus); + +static inline void dbs_timer_init(struct dbs_data *dbs_data, int cpu, + unsigned int sampling_rate) { int delay = delay_for_sampling_rate(sampling_rate); + struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu); - INIT_DEFERRABLE_WORK(&cdbs->work, dbs_data->gov_dbs_timer); - schedule_delayed_work_on(cdbs->cpu, &cdbs->work, delay); + schedule_delayed_work_on(cpu, &cdbs->work, delay); } -static inline void dbs_timer_exit(struct cpu_dbs_common_info *cdbs) +static inline void dbs_timer_exit(struct dbs_data *dbs_data, int cpu) { + struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu); + cancel_delayed_work_sync(&cdbs->work); } @@ -217,6 +227,10 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, if (ignore_nice) j_cdbs->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; + + mutex_init(&j_cdbs->timer_mutex); + INIT_DEFERRABLE_WORK(&j_cdbs->work, + dbs_data->gov_dbs_timer); } /* @@ -275,15 +289,16 @@ second_time: } mutex_unlock(&dbs_data->mutex); - mutex_init(&cpu_cdbs->timer_mutex); - dbs_timer_init(dbs_data, cpu_cdbs, *sampling_rate); + for_each_cpu(j, policy->cpus) + dbs_timer_init(dbs_data, j, *sampling_rate); break; case CPUFREQ_GOV_STOP: if (dbs_data->governor == GOV_CONSERVATIVE) cs_dbs_info->enable = 0; - dbs_timer_exit(cpu_cdbs); + for_each_cpu(j, policy->cpus) + dbs_timer_exit(dbs_data, j); mutex_lock(&dbs_data->mutex); mutex_destroy(&cpu_cdbs->timer_mutex); diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index f661654..5bf6fb8 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -171,6 +171,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate) u64 get_cpu_idle_time(unsigned int cpu, u64 *wall); void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); +bool dbs_sw_coordinated_cpus(struct cpu_dbs_common_info *cdbs); int cpufreq_governor_dbs(struct dbs_data *dbs_data, struct cpufreq_policy *policy, unsigned int event); #endif /* _CPUFREQ_GOVERNER_H */ diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 7731f7c..93bb56d 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -243,7 +243,8 @@ static void od_dbs_timer(struct work_struct *work) } } - schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay); + schedule_delayed_work_on(smp_processor_id(), &dbs_info->cdbs.work, + delay); mutex_unlock(&dbs_info->cdbs.timer_mutex); }