From patchwork Fri Jun 26 03:51:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 191791 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp111965ilg; Thu, 25 Jun 2020 20:52:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMkpN9vzltAs23k1KDUo8hUJlTpZ/uZu6KeZ5l787FhhrYZ/0qTEgBQr7UKGUtH4Xn39Mr X-Received: by 2002:a05:6402:312a:: with SMTP id dd10mr1447482edb.320.1593143524157; Thu, 25 Jun 2020 20:52:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593143524; cv=none; d=google.com; s=arc-20160816; b=tra905U3VdNvWfAWB8981/ks972Zj0742X94Cw2yvsc8zir1stK7e0NrSGYbiCbJR1 Cemli4L1dVKXncTpP4KNha5dGTovBM4aA0vnUl+HO5Lzzjb1IXhf3MSb+vCdEymtMARm 6drffrH9XyXIAs/G2FbKvxvn9gPYRwnS9rvZe7SpN6QjqTRbg4R5e6qC77l84C3QA+AA Lc6t9RFiybSw45rdZkGoWxiZC6+FELyDL8kjsCKYimPtQqNtwhxkraq6l6qm0f0YVTsf /H3avO2ymAHQrn5AxF6srJU/L0OW7Piu6snEoy/bhAg8D0Y9T/VNtbNrtJIbDspeewIB OVnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GyDv1eGRF/Hpb1vrzd8yB8yhzJQyRsKrTey51yyHxdU=; b=qym8UhjdaseSDpSCrjbOFhragbM3gCKQJUJQO0mRx0PKb0EXpBWUhcLybGE0UbjAxC 8O8li6+b9nFJ+qq4n3ZTxr5tvLgQLa2Zvm+Jgxa1Mxsth6TTEhyxDUGsRWi4xBr4GlOE ZNj5lPzOjDqmHaJqi8GNdX9NsY6Se3AMOxS+LLUHushKr+uJWkZdKCNWc7GZZdh6R446 OWvl64rfc7hUFnOun6KP7C+ZgWaMgLEW2h9RmjOb3VK0Ie/GHrGdqaPpp1tCyF4ojSCr iYZM6S1xJY+i1Y60KQpxaVjs+MottCppLvBnjNdrTYy6uvJZds96yTXTXUHYr/NmBfVL xX3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LUyFKxIg; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d17si4351528edu.223.2020.06.25.20.52.04; Thu, 25 Jun 2020 20:52:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LUyFKxIg; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728458AbgFZDvz (ORCPT + 10 others); Thu, 25 Jun 2020 23:51:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728456AbgFZDvx (ORCPT ); Thu, 25 Jun 2020 23:51:53 -0400 Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 884A3C08C5C1 for ; Thu, 25 Jun 2020 20:51:53 -0700 (PDT) Received: by mail-pf1-x442.google.com with SMTP id b16so4051294pfi.13 for ; Thu, 25 Jun 2020 20:51:53 -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:in-reply-to:references :mime-version:content-transfer-encoding; bh=GyDv1eGRF/Hpb1vrzd8yB8yhzJQyRsKrTey51yyHxdU=; b=LUyFKxIgIyvGIQS/g+X8sYxv4buWkAC81fMiXoz7jLPGMBEGnPH8nmLaqQQekj+kJn Uc+6UNcsse1LFmwa6/A+rxfMb/KLnoOG7unc2sZokqvLxYttTymWWaUTjTIW2/nX2SR+ 7uJAaw+rJfyg1YJN4Huu6A7THXod2joPnZOBX3d8kAQ3yjzzn9sjdmrw2BDCkGCc7tX7 BI6VxxjEq4EjwdIM4bFBhnt9KTlvvLozwx99WfuMnciWJf90TPU5B+CstXkh3U1RJdtp bD9AL38vohzyM+2gNFD/K9WI8TPrTfKi0zfF6Wa0wKpmi6UQYJIn3wVw+6W+TPLjqTjt RUXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GyDv1eGRF/Hpb1vrzd8yB8yhzJQyRsKrTey51yyHxdU=; b=XvVXnxNjv28/7Qf7lN3yTe4XdD7nWjHV7qJRcVTvD2+Qy9r3tRiUKEZ9YXJ0WE+kKS 4cUT+BUOnjNSSv6UDUhE3XM4Rtmmx6jpeeDl/waGjn3ATFVxsgJEz8IDjocdS7hN4GWz 87HAOFNDUE67CQ2qvbDJeGiA9iEwEuwDYsktep+0X5r0SEkHowZkaOOoMCOdlRWdQMMr 6X7vizYWNaqK4h31kqQbU/6w3sEjnLH7WGRDLzR67SKfCRmv7Rjjwtm5WU51zU3/45Qk hqu57ePJfTYNcu1M264EYBsKiiQIXFde3tGBZDgiqzFfmvuTuZtpY0G7+LhO/4CPvGcF WNuA== X-Gm-Message-State: AOAM53145Ktrjlc0463zJRKC+ytY37hrqi99IkHAFMrFT7FPbQKlbvQi Jf0g7RO9zOQkUqMfUI5Y1prDAA== X-Received: by 2002:aa7:8388:: with SMTP id u8mr881390pfm.253.1593143513036; Thu, 25 Jun 2020 20:51:53 -0700 (PDT) Received: from localhost ([122.172.127.76]) by smtp.gmail.com with ESMTPSA id z26sm3837606pfr.187.2020.06.25.20.51.52 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 25 Jun 2020 20:51:52 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Viresh Kumar Cc: linux-pm@vger.kernel.org, Vincent Guittot , kernel-team@android.com, tkjos@google.com, adharmap@codeaurora.org, Quentin Perret , linux-kernel@vger.kernel.org Subject: [PATCH V3 1/3] cpufreq: Fix locking issues with governors Date: Fri, 26 Jun 2020 09:21:42 +0530 Message-Id: X-Mailer: git-send-email 2.25.0.rc1.19.g042ed3e048af In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The locking around governors handling isn't adequate currently. The list of governors should never be traversed without locking in place. Also we must make sure the governor isn't removed while it is still referenced by code. Reported-by: Quentin Perret Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 59 ++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 23 deletions(-) -- 2.25.0.rc1.19.g042ed3e048af Reviewed-by: Quentin Perret diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0128de3603df..e798a1193bdf 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -621,6 +621,24 @@ static struct cpufreq_governor *find_governor(const char *str_governor) return NULL; } +static struct cpufreq_governor *get_governor(const char *str_governor) +{ + struct cpufreq_governor *t; + + mutex_lock(&cpufreq_governor_mutex); + t = find_governor(str_governor); + if (!t) + goto unlock; + + if (!try_module_get(t->owner)) + t = NULL; + +unlock: + mutex_unlock(&cpufreq_governor_mutex); + + return t; +} + static unsigned int cpufreq_parse_policy(char *str_governor) { if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) @@ -640,28 +658,14 @@ static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor) { struct cpufreq_governor *t; - mutex_lock(&cpufreq_governor_mutex); - - t = find_governor(str_governor); - if (!t) { - int ret; - - mutex_unlock(&cpufreq_governor_mutex); - - ret = request_module("cpufreq_%s", str_governor); - if (ret) - return NULL; - - mutex_lock(&cpufreq_governor_mutex); + t = get_governor(str_governor); + if (t) + return t; - t = find_governor(str_governor); - } - if (t && !try_module_get(t->owner)) - t = NULL; - - mutex_unlock(&cpufreq_governor_mutex); + if (request_module("cpufreq_%s", str_governor)) + return NULL; - return t; + return get_governor(str_governor); } /** @@ -815,12 +819,14 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, goto out; } + mutex_lock(&cpufreq_governor_mutex); for_each_governor(t) { if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) - goto out; + break; i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name); } + mutex_unlock(&cpufreq_governor_mutex); out: i += sprintf(&buf[i], "\n"); return i; @@ -1058,11 +1064,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) struct cpufreq_governor *def_gov = cpufreq_default_governor(); struct cpufreq_governor *gov = NULL; unsigned int pol = CPUFREQ_POLICY_UNKNOWN; + bool put_governor = false; + int ret; if (has_target()) { /* Update policy governor to the one used before hotplug. */ - gov = find_governor(policy->last_governor); + gov = get_governor(policy->last_governor); if (gov) { + put_governor = true; pr_debug("Restoring governor %s for cpu %d\n", policy->governor->name, policy->cpu); } else if (def_gov) { @@ -1089,7 +1098,11 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) return -ENODATA; } - return cpufreq_set_policy(policy, gov, pol); + ret = cpufreq_set_policy(policy, gov, pol); + if (put_governor) + module_put(gov->owner); + + return ret; } static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) From patchwork Fri Jun 26 03:51:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 191793 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp112012ilg; Thu, 25 Jun 2020 20:52:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwmtuCMvg8U7q7Xo+earKBJwDnwo0mM/H18NArWunMYbFoLqgAXRdF699cAqBQSQUDu5fHI X-Received: by 2002:a05:6402:16db:: with SMTP id r27mr1427288edx.139.1593143530667; Thu, 25 Jun 2020 20:52:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593143530; cv=none; d=google.com; s=arc-20160816; b=XA2q4AD+/ut9BGJkHfN4zTZuZSHMvSO6Nzxo0M4BAkWvQ0rrl0G5gIhGuqI/KmzmOY noOGxYBv+m53LdgbqxwM1aCF3bejBnGmV2mpbq3lCKOcgupYpHAuHTR5t5+BB3rGPXk1 gfM/Ak4FQFhpSB3oyMufiHX8UdMYOVsgoA69InDAp3fa4y1kvhYNxReihspmOh8r1/Vb Us9UAy8MMaL5k+w0vsqbjvWGqovwh8zWIa5b+Sw8yN1ztbrjOZsrrYBvKp5+ECGI3MD1 TIJxylHhdsp8PPK5E5H01lYy23pVqObsVWsyw5yr5XW3x3bN7c2AccEyW+vQBrP705ig /fhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=bDEuNi6VcWGVZVG3Ao7I2ar+mftbkIzW0ZQYBhMw7zM=; b=NLq8Uck4RoO6J0Ew8vLKnDF0vOjhd7aFo6kfsEN6sTacppLLjAVp6z0IKHnA24Bodx sNDoOLSlLaEW356DWcTZE8H90vyzGH2c3K5TEbVRTLFKF2UcwEbb6LEy27TjJEqtyilV OhJqr7jFY0cijCPtNOMJNE8Dj/IPVVN5wCbpQMshV78IDfk1i2+wGfR4Fjpndn0Fb+uo wLLsmToyE5Tvud37usspTVmcMt8RTRSCc5aIZ8M4KSwrzrJ517C1QrY82eBOIrSiIkp+ v5LtGmoFKQJLsRCv0CTQQJn+3upKpd+tv/KXBx9+SNcRb2jIlWGo/Kk9r+9B5JNFn9+D 0WuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wcvPUDCY; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j7si1253123edy.448.2020.06.25.20.52.10; Thu, 25 Jun 2020 20:52:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wcvPUDCY; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728473AbgFZDv6 (ORCPT + 10 others); Thu, 25 Jun 2020 23:51:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726104AbgFZDv5 (ORCPT ); Thu, 25 Jun 2020 23:51:57 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F14F7C08C5C1 for ; Thu, 25 Jun 2020 20:51:56 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id e9so4365221pgo.9 for ; Thu, 25 Jun 2020 20:51:56 -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:in-reply-to:references :mime-version:content-transfer-encoding; bh=bDEuNi6VcWGVZVG3Ao7I2ar+mftbkIzW0ZQYBhMw7zM=; b=wcvPUDCYNg0VoRCPuSICiKnZcq2vobgSOlnfY8Z3efK+1eAEzvDJSGHyQpRUWfyvxC XzwvY7fSDagVhRnGyduvbpsXjslT9EPFXb0dS2FSJeFHFgzkj6JRunX7PXgQQ7/jpS7T uc6ABXV22lRh8uMuIx8ib0HN0MnTXN7S9P+/Qh+cI1owcBtVhpbVp5UqvsvLHDbD3Vrj uw7IFMf5CdC7qXEj+vope0cFkOC3U8gEbqZpzzZojl4+Z48HSjSVn9ryZGuoS1Fs8oeO RBeuQgqdvhpjHYVi9V+WAXYEYlHm4IOXHnsXDX2ovJzacZ1Oc5IZQn2m+qKgeOkG/ZmA 15vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bDEuNi6VcWGVZVG3Ao7I2ar+mftbkIzW0ZQYBhMw7zM=; b=g/XzGiaVsvFiW/l2ORmktlAcsPEPPhYHpi94cJoNwAwyP5wPXMCiaA6C8BdkFqypTm o/M50LxuMAdeWQp121fSgcIRbEXTvGMIDUElOYVvVU4VMxuaSOS6vHbRBE80zjFO0SNZ 4/5PxovSPa2I1a3mh6CK3zob5GAPBn7NnsbbXtC1Y480eVsTu5PgsJd5luD82uulePVJ z5i2Zasx2seqIz8DeHIzEBpYZ6dHL7IzbVboXkO/1k3nUM0DID/I031SYtuYhIfrwtNg ocBpmBNpR69/BbUjQiOjl+d4okgdW8lOweupJU8cQgESCXITq+Msq5cJbWqzebQ/tZdh eJmw== X-Gm-Message-State: AOAM533z8TF3AgxDe8Q89cY3HFJraXDwr2gmjoGID6ovYfzrRxm0QUP/ WbCT0FdkNk9RlFewzzg8lxtoQDn2ue8= X-Received: by 2002:a63:495c:: with SMTP id y28mr1020538pgk.30.1593143516459; Thu, 25 Jun 2020 20:51:56 -0700 (PDT) Received: from localhost ([122.172.127.76]) by smtp.gmail.com with ESMTPSA id iq19sm9467176pjb.48.2020.06.25.20.51.55 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 25 Jun 2020 20:51:55 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Arnd Bergmann , Viresh Kumar , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman Cc: linux-pm@vger.kernel.org, kernel-team@android.com, tkjos@google.com, adharmap@codeaurora.org, Quentin Perret , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 2/3] cpufreq: Register governors at core_initcall Date: Fri, 26 Jun 2020 09:21:43 +0530 Message-Id: <088d0d017f1fe57edef0f50b2cfaeb785b6908df.1593143118.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.25.0.rc1.19.g042ed3e048af In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Quentin Perret Currently, most CPUFreq governors are registered at core_initcall time when used as default, and module_init otherwise. In preparation for letting users specify the default governor on the kernel command line, change all of them to use core_initcall unconditionally, as is already the case for schedutil and performance. This will enable us to assume builtin governors have been registered before the builtin CPUFreq drivers probe. And since all governors now have similar init/exit patterns, introduce two new macros cpufreq_governor_{init,exit}() to factorize the code. Acked-by: Viresh Kumar Signed-off-by: Quentin Perret Signed-off-by: Viresh Kumar --- .../platforms/cell/cpufreq_spudemand.c | 26 ++----------------- drivers/cpufreq/cpufreq_conservative.c | 22 ++++------------ drivers/cpufreq/cpufreq_ondemand.c | 24 +++++------------ drivers/cpufreq/cpufreq_performance.c | 14 ++-------- drivers/cpufreq/cpufreq_powersave.c | 18 +++---------- drivers/cpufreq/cpufreq_userspace.c | 18 +++---------- include/linux/cpufreq.h | 14 ++++++++++ kernel/sched/cpufreq_schedutil.c | 6 +---- 8 files changed, 36 insertions(+), 106 deletions(-) -- 2.25.0.rc1.19.g042ed3e048af diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c index 55b31eadb3c8..ca7849e113d7 100644 --- a/arch/powerpc/platforms/cell/cpufreq_spudemand.c +++ b/arch/powerpc/platforms/cell/cpufreq_spudemand.c @@ -126,30 +126,8 @@ static struct cpufreq_governor spu_governor = { .stop = spu_gov_stop, .owner = THIS_MODULE, }; - -/* - * module init and destoy - */ - -static int __init spu_gov_init(void) -{ - int ret; - - ret = cpufreq_register_governor(&spu_governor); - if (ret) - printk(KERN_ERR "registration of governor failed\n"); - return ret; -} - -static void __exit spu_gov_exit(void) -{ - cpufreq_unregister_governor(&spu_governor); -} - - -module_init(spu_gov_init); -module_exit(spu_gov_exit); +cpufreq_governor_init(spu_governor); +cpufreq_governor_exit(spu_governor); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Krafft "); - diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 737ff3b9c2c0..aa39ff31ec9f 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -322,17 +322,7 @@ static struct dbs_governor cs_governor = { .start = cs_start, }; -#define CPU_FREQ_GOV_CONSERVATIVE (&cs_governor.gov) - -static int __init cpufreq_gov_dbs_init(void) -{ - return cpufreq_register_governor(CPU_FREQ_GOV_CONSERVATIVE); -} - -static void __exit cpufreq_gov_dbs_exit(void) -{ - cpufreq_unregister_governor(CPU_FREQ_GOV_CONSERVATIVE); -} +#define CPU_FREQ_GOV_CONSERVATIVE (cs_governor.gov) MODULE_AUTHOR("Alexander Clouter "); MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for " @@ -343,11 +333,9 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE struct cpufreq_governor *cpufreq_default_governor(void) { - return CPU_FREQ_GOV_CONSERVATIVE; + return &CPU_FREQ_GOV_CONSERVATIVE; } - -core_initcall(cpufreq_gov_dbs_init); -#else -module_init(cpufreq_gov_dbs_init); #endif -module_exit(cpufreq_gov_dbs_exit); + +cpufreq_governor_init(CPU_FREQ_GOV_CONSERVATIVE); +cpufreq_governor_exit(CPU_FREQ_GOV_CONSERVATIVE); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 82a4d37ddecb..ac361a8b1d3b 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -408,7 +408,7 @@ static struct dbs_governor od_dbs_gov = { .start = od_start, }; -#define CPU_FREQ_GOV_ONDEMAND (&od_dbs_gov.gov) +#define CPU_FREQ_GOV_ONDEMAND (od_dbs_gov.gov) static void od_set_powersave_bias(unsigned int powersave_bias) { @@ -429,7 +429,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias) continue; policy = cpufreq_cpu_get_raw(cpu); - if (!policy || policy->governor != CPU_FREQ_GOV_ONDEMAND) + if (!policy || policy->governor != &CPU_FREQ_GOV_ONDEMAND) continue; policy_dbs = policy->governor_data; @@ -461,16 +461,6 @@ void od_unregister_powersave_bias_handler(void) } EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler); -static int __init cpufreq_gov_dbs_init(void) -{ - return cpufreq_register_governor(CPU_FREQ_GOV_ONDEMAND); -} - -static void __exit cpufreq_gov_dbs_exit(void) -{ - cpufreq_unregister_governor(CPU_FREQ_GOV_ONDEMAND); -} - MODULE_AUTHOR("Venkatesh Pallipadi "); MODULE_AUTHOR("Alexey Starikovskiy "); MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " @@ -480,11 +470,9 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND struct cpufreq_governor *cpufreq_default_governor(void) { - return CPU_FREQ_GOV_ONDEMAND; + return &CPU_FREQ_GOV_ONDEMAND; } - -core_initcall(cpufreq_gov_dbs_init); -#else -module_init(cpufreq_gov_dbs_init); #endif -module_exit(cpufreq_gov_dbs_exit); + +cpufreq_governor_init(CPU_FREQ_GOV_ONDEMAND); +cpufreq_governor_exit(CPU_FREQ_GOV_ONDEMAND); diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index def9afe0f5b8..71c1d9aba772 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -23,16 +23,6 @@ static struct cpufreq_governor cpufreq_gov_performance = { .limits = cpufreq_gov_performance_limits, }; -static int __init cpufreq_gov_performance_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_performance); -} - -static void __exit cpufreq_gov_performance_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_performance); -} - #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE struct cpufreq_governor *cpufreq_default_governor(void) { @@ -50,5 +40,5 @@ MODULE_AUTHOR("Dominik Brodowski "); MODULE_DESCRIPTION("CPUfreq policy governor 'performance'"); MODULE_LICENSE("GPL"); -core_initcall(cpufreq_gov_performance_init); -module_exit(cpufreq_gov_performance_exit); +cpufreq_governor_init(cpufreq_gov_performance); +cpufreq_governor_exit(cpufreq_gov_performance); diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index 1ae66019eb83..7749522355b5 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -23,16 +23,6 @@ static struct cpufreq_governor cpufreq_gov_powersave = { .owner = THIS_MODULE, }; -static int __init cpufreq_gov_powersave_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_powersave); -} - -static void __exit cpufreq_gov_powersave_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_powersave); -} - MODULE_AUTHOR("Dominik Brodowski "); MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'"); MODULE_LICENSE("GPL"); @@ -42,9 +32,7 @@ struct cpufreq_governor *cpufreq_default_governor(void) { return &cpufreq_gov_powersave; } - -core_initcall(cpufreq_gov_powersave_init); -#else -module_init(cpufreq_gov_powersave_init); #endif -module_exit(cpufreq_gov_powersave_exit); + +cpufreq_governor_init(cpufreq_gov_powersave); +cpufreq_governor_exit(cpufreq_gov_powersave); diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index b43e7cd502c5..50a4d7846580 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -126,16 +126,6 @@ static struct cpufreq_governor cpufreq_gov_userspace = { .owner = THIS_MODULE, }; -static int __init cpufreq_gov_userspace_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_userspace); -} - -static void __exit cpufreq_gov_userspace_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_userspace); -} - MODULE_AUTHOR("Dominik Brodowski , " "Russell King "); MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'"); @@ -146,9 +136,7 @@ struct cpufreq_governor *cpufreq_default_governor(void) { return &cpufreq_gov_userspace; } - -core_initcall(cpufreq_gov_userspace_init); -#else -module_init(cpufreq_gov_userspace_init); #endif -module_exit(cpufreq_gov_userspace_exit); + +cpufreq_governor_init(cpufreq_gov_userspace); +cpufreq_governor_exit(cpufreq_gov_userspace); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3494f6763597..e62b022cb07e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -577,6 +577,20 @@ unsigned int cpufreq_policy_transition_delay_us(struct cpufreq_policy *policy); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); +#define cpufreq_governor_init(__governor) \ +static int __init __governor##_init(void) \ +{ \ + return cpufreq_register_governor(&__governor); \ +} \ +core_initcall(__governor##_init) + +#define cpufreq_governor_exit(__governor) \ +static void __exit __governor##_exit(void) \ +{ \ + return cpufreq_unregister_governor(&__governor); \ +} \ +module_exit(__governor##_exit) + struct cpufreq_governor *cpufreq_default_governor(void); struct cpufreq_governor *cpufreq_fallback_governor(void); diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 7fbaee24c824..402a09af9f43 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -909,11 +909,7 @@ struct cpufreq_governor *cpufreq_default_governor(void) } #endif -static int __init sugov_register(void) -{ - return cpufreq_register_governor(&schedutil_gov); -} -core_initcall(sugov_register); +cpufreq_governor_init(schedutil_gov); #ifdef CONFIG_ENERGY_MODEL extern bool sched_energy_update; From patchwork Fri Jun 26 03:51:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 191792 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp111983ilg; Thu, 25 Jun 2020 20:52:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzwpTVD+d+saQRREPjQdy7GZEfjgAvW5xRytABYmFYi3bNUK3+U3oxBA4RS16uMSpnrlpHq X-Received: by 2002:a05:6402:2d0:: with SMTP id b16mr1468428edx.152.1593143527298; Thu, 25 Jun 2020 20:52:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593143527; cv=none; d=google.com; s=arc-20160816; b=E8ReGyKEs5ZZgPLV17MO3JwZLVjOcficLLHvVFj3cxbDSitzYEIz4X1IYahnwypfcS UoGEzLc88mnmg3tmifzLurjZZIrfQJFQAQsX3lYSNtRWk2cA2U54M2B61oity46wLP72 jpD+3XLE9MiHva9KBOaIPqBTdLDW6VpA8C5C7SmHBSzxI/V3+i05RzC4BCWOoAZFrDZC oWMCypbaswvIms2GaevgkU4ypAqOEHm3RGB1+VVUc1Uw7Z4iVGTsVYyO1fPjOezpWOMX lBujFUjZ/NZ1btavtbMaLXT0Apg49Kg/qmydL99V2fGA1K4DYU35WrcOzQpftm+V7fU5 Pecg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1kNSCiHNHSb6jIhG+JaGhvWbvnCv4GNFP8GZBjcVO0Y=; b=S2nMFeWuJwGN+PZ93u9SSCw+vcc80ZWHBBANxNspxinGOSFkxQ0++bH2hZERh5r+7D dCT8OI1AE9HkzV1XK1Vs5pa1zh7ryCdxfvfy5q3WnitV0qudI+YiDOY/2Bs+NQRCgdmR EwkkP+heGNgknKf3Qdez3KPPKze6J9I4TfVlPRKEho1qxNzWgW6jscDBbr1lrfS91nWW zsz7tFGUtI9iW8oniwc2l1dEoFO6TFafIUcwEwTuEgNUhyYZeXI033+wzq6iTFKUPWcl 12ON3dnyfYAMw4RCQ2ac9/3e7UqsDpHo4q0GbSsTY7axAavulP8196j/PCPfI+mz/S4E 7cNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=REu2vVnN; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cn9si5568188edb.325.2020.06.25.20.52.07; Thu, 25 Jun 2020 20:52:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=REu2vVnN; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728481AbgFZDwD (ORCPT + 10 others); Thu, 25 Jun 2020 23:52:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728477AbgFZDwA (ORCPT ); Thu, 25 Jun 2020 23:52:00 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0917DC08C5DB for ; Thu, 25 Jun 2020 20:52:00 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id a127so4055884pfa.12 for ; Thu, 25 Jun 2020 20:52:00 -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:in-reply-to:references :mime-version:content-transfer-encoding; bh=1kNSCiHNHSb6jIhG+JaGhvWbvnCv4GNFP8GZBjcVO0Y=; b=REu2vVnNvFUO7RMznNy7FQBFECB9nt/3gLuM5qsneFWLgFzaMJa3uw3MHsopvaIhRw PbNnmBTaimtKOz0klQp0RnQodX5uRKSH9pOq1Ccz3zTI4vV7+v0MISmgwCZGCkc21vZN U52lXDHn+Y5h2h8hpp74pkX3e4Xn6Fqw0fyKD/EE6CQz38h8MhZnzIGlb5VfyqxU5MAA gb8Q4OnL2jpwG2KyrfR2BHXksxqb2G1KFHUhKDdsVFtA7dnMzYVwnpziKtHmLattaA6x P1FnWmQNQaAou+Uwc+cmpdSWtLmP9SJ2gRcQjE0KhbOZDgERvj50ZKjAmRaLZn3zKK1O rHDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1kNSCiHNHSb6jIhG+JaGhvWbvnCv4GNFP8GZBjcVO0Y=; b=YzU0cnW52ZHMiG1gJYW0HIPanx9q2E0iOxnlNtXoVPUMaJQSAPtcdLFPRheLny0ARy Zg9xNuLeyMEauQNJ9Gxb2d9D/0EZl+iGymkDYjGC4Otjego+QttVyq0NLyQVGsrUOhCx CE90xdRUCkg8gERoY6JZGiyMt4BpKcDWhPEDTsfSNFU9Y9lU+tX34MlJbr65mVnZLfHM k9OD5L71we2rO79UE//y2T+P9G0jnXTUtwXqyUxyDTCkov8Lw3e4N0gB0OGCm++80EyD qHILbskvZTDA8Xj3QZ9krhpZ1Vi9tEaoLXj8spVTuNfYWbb6K4TG5foG4K2J7oi8GLDk eE8w== X-Gm-Message-State: AOAM533+cBId5tXGbht7VABEdTev2c+x9Y209F9WVFGO7m5p33KE2XLH bUTWPmY2j9/VRI+FOtVXimLTfw== X-Received: by 2002:aa7:9abc:: with SMTP id x28mr885223pfi.39.1593143519452; Thu, 25 Jun 2020 20:51:59 -0700 (PDT) Received: from localhost ([122.172.127.76]) by smtp.gmail.com with ESMTPSA id k2sm21272108pgm.11.2020.06.25.20.51.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 25 Jun 2020 20:51:58 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Jonathan Corbet , Viresh Kumar Cc: linux-pm@vger.kernel.org, Vincent Guittot , kernel-team@android.com, tkjos@google.com, adharmap@codeaurora.org, Quentin Perret , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 3/3] cpufreq: Specify default governor on command line Date: Fri, 26 Jun 2020 09:21:44 +0530 Message-Id: <7eb38608b2b32c0c72dfb160c51206ec42e74e35.1593143118.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.25.0.rc1.19.g042ed3e048af In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Quentin Perret Currently, the only way to specify the default CPUfreq governor is via Kconfig options, which suits users who can build the kernel themselves perfectly. However, for those who use a distro-like kernel (such as Android, with the Generic Kernel Image project), the only way to use a different default is to boot to userspace, and to then switch using the sysfs interface. Being able to specify the default governor on the command line, like is the case for cpuidle, would enable those users to specify their governor of choice earlier on, and to simplify slighlty the userspace boot procedure. To support this use-case, add a kernel command line parameter enabling to specify a default governor for CPUfreq, which takes precedence over the builtin default. This implementation has one notable limitation: the default governor must be registered before the driver. This is solved for builtin governors and drivers using appropriate *_initcall() functions. And in the modular case, this must be reflected as a constraint on the module loading order. Signed-off-by: Quentin Perret [ Viresh: Converted 'default_governor' to a string and parsing it only at initcall level, and several updates to cpufreq_init_policy(). ] Signed-off-by: Viresh Kumar --- .../admin-guide/kernel-parameters.txt | 5 +++ Documentation/admin-guide/pm/cpufreq.rst | 6 ++-- drivers/cpufreq/cpufreq.c | 36 ++++++++++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) -- 2.25.0.rc1.19.g042ed3e048af diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index fb95fad81c79..8deb5a89328a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -703,6 +703,11 @@ cpufreq.off=1 [CPU_FREQ] disable the cpufreq sub-system + cpufreq.default_governor= + [CPU_FREQ] Name of the default cpufreq governor or + policy to use. This governor must be registered in the + kernel before the cpufreq driver probes. + cpu_init_udelay=N [X86] Delay for N microsec between assert and de-assert of APIC INIT to start processors. This delay occurs diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst index 0c74a7784964..368e612145d2 100644 --- a/Documentation/admin-guide/pm/cpufreq.rst +++ b/Documentation/admin-guide/pm/cpufreq.rst @@ -147,9 +147,9 @@ CPUs in it. The next major initialization step for a new policy object is to attach a scaling governor to it (to begin with, that is the default scaling governor -determined by the kernel configuration, but it may be changed later -via ``sysfs``). First, a pointer to the new policy object is passed to the -governor's ``->init()`` callback which is expected to initialize all of the +determined by the kernel command line or configuration, but it may be changed +later via ``sysfs``). First, a pointer to the new policy object is passed to +the governor's ``->init()`` callback which is expected to initialize all of the data structures necessary to handle the given policy and, possibly, to add a governor ``sysfs`` interface to it. Next, the governor is started by invoking its ``->start()`` callback. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e798a1193bdf..93c6399c1a42 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list); #define for_each_governor(__governor) \ list_for_each_entry(__governor, &cpufreq_governor_list, governor_list) +static char cpufreq_param_governor[CPUFREQ_NAME_LEN]; +static char default_governor[CPUFREQ_NAME_LEN]; + /** * The "cpufreq driver" - the arch- or hardware-dependent low * level driver of CPUFreq support, and its spinlock. This lock @@ -1061,7 +1064,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void) static int cpufreq_init_policy(struct cpufreq_policy *policy) { - struct cpufreq_governor *def_gov = cpufreq_default_governor(); struct cpufreq_governor *gov = NULL; unsigned int pol = CPUFREQ_POLICY_UNKNOWN; bool put_governor = false; @@ -1071,22 +1073,29 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) /* Update policy governor to the one used before hotplug. */ gov = get_governor(policy->last_governor); if (gov) { - put_governor = true; pr_debug("Restoring governor %s for cpu %d\n", - policy->governor->name, policy->cpu); - } else if (def_gov) { - gov = def_gov; + gov->name, policy->cpu); } else { - return -ENODATA; + gov = get_governor(default_governor); + } + + if (gov) { + put_governor = true; + } else { + gov = cpufreq_default_governor(); + if (!gov) + return -ENODATA; } + } else { + /* Use the default policy if there is no last_policy. */ if (policy->last_policy) { pol = policy->last_policy; - } else if (def_gov) { - pol = cpufreq_parse_policy(def_gov->name); + } else { + pol = cpufreq_parse_policy(default_governor); /* - * In case the default governor is neiter "performance" + * In case the default governor is neither "performance" * nor "powersave", fall back to the initial policy * value set by the driver. */ @@ -2796,13 +2805,22 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); static int __init cpufreq_core_init(void) { + struct cpufreq_governor *gov = cpufreq_default_governor(); + char *name = gov->name; + if (cpufreq_disabled()) return -ENODEV; cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); BUG_ON(!cpufreq_global_kobject); + if (strlen(cpufreq_param_governor)) + name = cpufreq_param_governor; + + strncpy(default_governor, name, CPUFREQ_NAME_LEN); + return 0; } module_param(off, int, 0444); +module_param_string(default_governor, cpufreq_param_governor, CPUFREQ_NAME_LEN, 0444); core_initcall(cpufreq_core_init);