Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp2525545pxu; Mon, 7 Dec 2020 08:43:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJw5D9iKFIQNSsQgCllTaEJN6pbfSNA3St4ubnjCJAJCl39JMw08v9dkHT+5mdill/A/M3wr X-Received: by 2002:a50:d2d2:: with SMTP id q18mr20417633edg.346.1607359437465; Mon, 07 Dec 2020 08:43:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607359437; cv=none; d=google.com; s=arc-20160816; b=tYQXnEFl5PjXwu6nOloZ32zIJyyjkJ0jFqtwpR/u0dzpMMryO2wFhoCTn3NaI178sg 04luVUAhFRX6zosGh+x8TgvYdrGDgHISajZkRLbtAsMzN3lMBSji34vcs5UiTMhvh1OZ 3gkSKNGdRPOi1j3n7SuJEOMXnYhRrrILjd7SOz+8pY+LLanqecUdn/QXO2+Bu3xD15lo EHTa7qPIRASqrFkIYTova+OgAitgu618bh1yQDZyffJ/n67ar3NCJc7+jU2D9lNHvgFw JU1ZO1gNwFyd92pk2v6wBmsWS9hO3LSdjd5P8lGv7wTQ76s3H5KMPsTG1zN/s+uW1kqA bgDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=8XpFCN36KMBbqQj76BW9MiXXv6mIKraIuAICWN3cDXM=; b=Fn1FXbTrdZ9bW7TSEyAhaGHSw5lvbiX9Jay201zrgdk2S7NTEdEO9YE9vgN6/H08yp ec289IQdHmLXjgLxHnwGAdMDLCuvCcQ7fOnj7mD3E5Bgp8luH+eGgAZGSHFnzV8SBlKQ Q2C62uTGhTNH5g+XVuIa02uX+6/TSg3iqFOLL6RJ/EACc52srnXZ20daOL2XSFOGajo1 kdS03qnZF9PkGO0L0kD6lF6pQj9odCg/JQH38wr4sW6Zy01BVJgGBAaN7wwtpoKnsQuo nWROtnQtzHKiVpUz49tk64irnybuEX5dDVoOWIGapwPAk5bChOoOqWXIaWQazw0Jgxee 5vTQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ly25si6558876ejb.326.2020.12.07.08.43.33; Mon, 07 Dec 2020 08:43:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727457AbgLGQkb (ORCPT + 99 others); Mon, 7 Dec 2020 11:40:31 -0500 Received: from cloudserver094114.home.pl ([79.96.170.134]:61978 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726698AbgLGQkb (ORCPT ); Mon, 7 Dec 2020 11:40:31 -0500 Received: from 89-64-79-106.dynamic.chello.pl (89.64.79.106) (HELO kreacher.localnet) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.83.530) id aa4a46705c8d1b84; Mon, 7 Dec 2020 17:39:48 +0100 From: "Rafael J. Wysocki" To: Linux PM Cc: LKML , Viresh Kumar , Srinivas Pandruvada , Peter Zijlstra , Doug Smythies , Giovanni Gherdovich Subject: [PATCH v1 4/4] cpufreq: intel_pstate: Implement the ->adjust_perf() callback Date: Mon, 07 Dec 2020 17:38:58 +0100 Message-ID: <3342398.tGQZsKHvNY@kreacher> In-Reply-To: <20360841.iInq7taT2Z@kreacher> References: <20360841.iInq7taT2Z@kreacher> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki Make intel_pstate expose the ->adjust_perf() callback when it operates in the passive mode with HWP enabled which causes the schedutil governor to use that callback instead of ->fast_switch(). The minimum and target performance-level values passed by the governor to ->adjust_perf() are converted to HWP.REQ.MIN and HWP.REQ.DESIRED, respectively, which allows the processor to adjust its configuration to maximize energy-efficiency while providing sufficient capacity. Signed-off-by: Rafael J. Wysocki --- Changes with respect to the RFC: - Drop the code related to the dropped "busy" argument of ->adjust_perf(). - Update the changelog accordingly. --- drivers/cpufreq/intel_pstate.c | 70 +++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 12 deletions(-) Index: linux-pm/drivers/cpufreq/intel_pstate.c =================================================================== --- linux-pm.orig/drivers/cpufreq/intel_pstate.c +++ linux-pm/drivers/cpufreq/intel_pstate.c @@ -2526,20 +2526,19 @@ static void intel_cpufreq_trace(struct c fp_toint(cpu->iowait_boost * 100)); } -static void intel_cpufreq_adjust_hwp(struct cpudata *cpu, u32 target_pstate, - bool strict, bool fast_switch) +static void intel_cpufreq_adjust_hwp(struct cpudata *cpu, u32 min, u32 max, + u32 desired, bool fast_switch) { u64 prev = READ_ONCE(cpu->hwp_req_cached), value = prev; value &= ~HWP_MIN_PERF(~0L); - value |= HWP_MIN_PERF(target_pstate); + value |= HWP_MIN_PERF(min); - /* - * The entire MSR needs to be updated in order to update the HWP min - * field in it, so opportunistically update the max too if needed. - */ value &= ~HWP_MAX_PERF(~0L); - value |= HWP_MAX_PERF(strict ? target_pstate : cpu->max_perf_ratio); + value |= HWP_MAX_PERF(max); + + value &= ~HWP_DESIRED_PERF(~0L); + value |= HWP_DESIRED_PERF(desired); if (value == prev) return; @@ -2569,11 +2568,15 @@ static int intel_cpufreq_update_pstate(s int old_pstate = cpu->pstate.current_pstate; target_pstate = intel_pstate_prepare_request(cpu, target_pstate); - if (hwp_active) - intel_cpufreq_adjust_hwp(cpu, target_pstate, - policy->strict_target, fast_switch); - else if (target_pstate != old_pstate) + if (hwp_active) { + int max_pstate = policy->strict_target ? + target_pstate : cpu->max_perf_ratio; + + intel_cpufreq_adjust_hwp(cpu, target_pstate, max_pstate, 0, + fast_switch); + } else if (target_pstate != old_pstate) { intel_cpufreq_adjust_perf_ctl(cpu, target_pstate, fast_switch); + } cpu->pstate.current_pstate = target_pstate; @@ -2634,6 +2637,47 @@ static unsigned int intel_cpufreq_fast_s return target_pstate * cpu->pstate.scaling; } +static void intel_cpufreq_adjust_perf(unsigned int cpunum, + unsigned long min_perf, + unsigned long target_perf, + unsigned long capacity) +{ + struct cpudata *cpu = all_cpu_data[cpunum]; + int old_pstate = cpu->pstate.current_pstate; + int cap_pstate, min_pstate, max_pstate, target_pstate; + + update_turbo_state(); + cap_pstate = global.turbo_disabled ? cpu->pstate.max_pstate : + cpu->pstate.turbo_pstate; + + /* Optimization: Avoid unnecessary divisions. */ + + target_pstate = cap_pstate; + if (target_perf < capacity) + target_pstate = DIV_ROUND_UP(cap_pstate * target_perf, capacity); + + min_pstate = cap_pstate; + if (min_perf < capacity) + min_pstate = DIV_ROUND_UP(cap_pstate * min_perf, capacity); + + if (min_pstate < cpu->pstate.min_pstate) + min_pstate = cpu->pstate.min_pstate; + + if (min_pstate < cpu->min_perf_ratio) + min_pstate = cpu->min_perf_ratio; + + max_pstate = min(cap_pstate, cpu->max_perf_ratio); + if (max_pstate < min_pstate) + max_pstate = min_pstate; + + target_pstate = clamp_t(int, target_pstate, min_pstate, max_pstate); + + intel_cpufreq_adjust_hwp(cpu, min_pstate, max_pstate, target_pstate, true); + + cpu->pstate.current_pstate = target_pstate; + intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_FAST_SWITCH, old_pstate); +} + static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) { int max_state, turbo_max, min_freq, max_freq, ret; @@ -3032,6 +3076,8 @@ static int __init intel_pstate_init(void intel_pstate.attr = hwp_cpufreq_attrs; intel_cpufreq.attr = hwp_cpufreq_attrs; intel_cpufreq.flags |= CPUFREQ_NEED_UPDATE_LIMITS; + intel_cpufreq.fast_switch = NULL; + intel_cpufreq.adjust_perf = intel_cpufreq_adjust_perf; if (!default_driver) default_driver = &intel_pstate;