From patchwork Thu Aug 18 08:55:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingbo Wen X-Patchwork-Id: 74141 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp240435qga; Thu, 18 Aug 2016 01:55:47 -0700 (PDT) X-Received: by 10.66.86.170 with SMTP id q10mr2047134paz.105.1471510547577; Thu, 18 Aug 2016 01:55:47 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f5si1526781pfk.77.2016.08.18.01.55.46; Thu, 18 Aug 2016 01:55:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753119AbcHRIzp (ORCPT + 14 others); Thu, 18 Aug 2016 04:55:45 -0400 Received: from mail-pa0-f49.google.com ([209.85.220.49]:35447 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751041AbcHRIzp (ORCPT ); Thu, 18 Aug 2016 04:55:45 -0400 Received: by mail-pa0-f49.google.com with SMTP id i5so4669373pat.2 for ; Thu, 18 Aug 2016 01:55:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=OWXL2zW2rVig3D6baVBxdRJz8fBoo7p57gVWCOESfNc=; b=exQ49kZYUFfd6+MBAjGR3i1oibGk4aVaLhxGIjxlzkcVpgBhDgtwleBdQcaj7k+ySz KV43QuYNIEkiX1GC+XaYvVQeGAGVH6hN7COTwpeRv5JE0WbZ3x0S/pYNlj4BZSlbdBQN usmLlkmIqeQuRcDokSuuBP+4/vUAzDQYaYAus= 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; bh=OWXL2zW2rVig3D6baVBxdRJz8fBoo7p57gVWCOESfNc=; b=dnYhjQB0Pcsq1JuZdVZ8VNAHrjeUTw+FT1voyK++X9O0f/+V0qW6NQxgwsS2NkzcsT 046laGA8b6IqVcOhnVZbNF9kEbnWswc5BGCX07D+1HwIzgwh1qUHoG7JY5zfScxXtJhf /aSXytN8rXp9cyWMVqVknZ8fng904/wdV/rNrE1kEoxjk4pK6O1wvbMjIwrXC2K/V09N jWm44/ZfNAozAG87Dp5gK8uZwLTsI/QWW1vBEfMj6YCHIexMUHyGeFjPcnWOcyGftqa5 +FT43iOmRt6iNPsYb3BBApBuUdKT5Fh764ACIIgzO0McnTeHsiKD7u3A/UMzTUp0uL7+ uh2w== X-Gm-Message-State: AEkooutSmwRK7aX8rN6NtOGNe8XcUk+/KLHjNcVav/g2NOlP2F/wNFJJjfHuG6anXubJeNXA X-Received: by 10.66.242.201 with SMTP id ws9mr2075063pac.7.1471510544239; Thu, 18 Aug 2016 01:55:44 -0700 (PDT) Received: from EF-wenpingbo.meizu.com ([103.26.122.10]) by smtp.gmail.com with ESMTPSA id k29sm2240040pfb.2.2016.08.18.01.55.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Aug 2016 01:55:43 -0700 (PDT) From: WEN Pingbo To: linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, steve.muckle@linaro.org, WEN Pingbo Subject: [PATCH] cpufreq: schedutil: set cpu freq to min in idle state Date: Thu, 18 Aug 2016 16:55:31 +0800 Message-Id: <1471510531-7330-1-git-send-email-pingbo.wen@linaro.org> X-Mailer: git-send-email 1.9.1 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The schedutil will keep the frequency high until next thread is arrived, when the cpu/cluster enter idle state, which is obviously abnormal and inefficient. This patch added a idle_timer, which will re-feed in every util callback. When cpu enter idle state, the idle_timer expires, and will pull down the frequency. Signed-off-by: WEN Pingbo --- kernel/sched/cpufreq_schedutil.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index a84641b..41cd74e 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -34,6 +34,7 @@ struct sugov_policy { s64 freq_update_delay_ns; unsigned int next_freq; + struct timer_list idle_timer; /* The next fields are only needed if fast switch cannot be used. */ struct irq_work irq_work; struct work_struct work; @@ -152,6 +153,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, struct cpufreq_policy *policy = sg_policy->policy; unsigned int next_f; + mod_timer(&sg_policy->idle_timer, jiffies + 1); + if (!sugov_should_update_freq(sg_policy, time)) return; @@ -215,6 +218,8 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time, raw_spin_lock(&sg_policy->update_lock); + mod_timer(&sg_policy->idle_timer, jiffies + 1); + sg_cpu->util = util; sg_cpu->max = max; sg_cpu->last_update = time; @@ -247,6 +252,18 @@ static void sugov_irq_work(struct irq_work *irq_work) schedule_work_on(smp_processor_id(), &sg_policy->work); } +static void sugov_idle_timer(unsigned long data) +{ + struct sugov_policy *sg_policy = (struct sugov_policy *)data; + struct cpufreq_policy *policy = sg_policy->policy; + struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, smp_processor_id()); + + /* CPU is in idle state, set to min directly to save power. */ + if (!sg_policy->work_in_progress && (policy->min != policy->cur)) + sugov_update_commit(sg_policy, sg_cpu->last_update, + policy->min); +} + /************************** sysfs interface ************************/ static struct sugov_tunables *global_tunables; @@ -310,6 +327,11 @@ static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy) init_irq_work(&sg_policy->irq_work, sugov_irq_work); INIT_WORK(&sg_policy->work, sugov_work); mutex_init(&sg_policy->work_lock); + + init_timer_pinned(&sg_policy->idle_timer); + sg_policy->idle_timer.function = sugov_idle_timer; + sg_policy->idle_timer.data = (unsigned long)sg_policy; + raw_spin_lock_init(&sg_policy->update_lock); return sg_policy; } @@ -468,6 +490,7 @@ static void sugov_stop(struct cpufreq_policy *policy) synchronize_sched(); + del_timer_sync(&sg_policy->idle_timer); irq_work_sync(&sg_policy->irq_work); cancel_work_sync(&sg_policy->work); }