Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp4004903pxb; Tue, 2 Mar 2021 04:28:21 -0800 (PST) X-Google-Smtp-Source: ABdhPJxCkdXu618Tnt3wkmIGZluvPXfaBBx06V6est6NpJFzkGmq2A3FsVcALwF6sbay5d+3Tvi5 X-Received: by 2002:aa7:d316:: with SMTP id p22mr16751115edq.107.1614688101224; Tue, 02 Mar 2021 04:28:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614688101; cv=none; d=google.com; s=arc-20160816; b=oek0PbeHVLyzU968Zh6V6mj3ouKx9yRHyaXuU97NMoIgf8J8lSOkllL8xpLZy9+E1z ggmiiKBJbfyWEjGkjXZmKsWbbzPCVjfRVMNyRi68BhItDfsbOjim9vtpX5/tm13FbTqP 45TyP0HuCckypxtE+q89LJGNYQ6dgVPOB31STZg25FluxHYcRHvBPbB9c5TiRVBeR3f8 cf2GhM6D2JDjsr4eN0tIrKxu31FwzVuUdHTH+GG+gs48WhzDNOUYfQJ77IDedVuLvR5O u1swcvhi+WJaQWlQXfvIwC6Y7QBKvYNUaLKfM8dGhZIS3RiCl0J+A562POMglIFJRPBv Jxsg== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=e1BbLYKhOKolwJdUeazjsXN5uYfyaRfyZQfoxJ303Nw=; b=GnrjS6vyhQHI1CmjYdFH51AiqyrKlyNGC79nBn4sAmzuHgcF3X9L/eVBcwDG6lhZ5U A3lHrDXSRyfDAHOouNfy6BNm/pic/2Gs80fQfm/8iYw2hvfG9Thlysu0Lr4lCqsi3aMO 7B0SJCRkplq7+HAiJbbZQM7sORc13LE7TCTqcOee7QRQDkh/T7UXIFX9/PEFsPhsIaey HES0wuh1LyZXKE1sbD1hzoAhl1KHSYkFfXUwZ2qlunB7aA10kQMNZjrgzLHpEMVEYzpl rYbTk/XuJyGvUq1MOkT5M0AQOYaCWmX+3OdBa+vOacD22zWPC/Q4R5JQE2o1W8JSlTTd KE2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Ctx0kAR3; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g6si13328644ejo.534.2021.03.02.04.27.57; Tue, 02 Mar 2021 04:28:21 -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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Ctx0kAR3; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442779AbhCBCQO (ORCPT + 99 others); Mon, 1 Mar 2021 21:16:14 -0500 Received: from mail.kernel.org ([198.145.29.99]:55158 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242160AbhCAToC (ORCPT ); Mon, 1 Mar 2021 14:44:02 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 88AC264DA8; Mon, 1 Mar 2021 17:25:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614619519; bh=GCJs19DoeLErSfoi8zCGSTzUdP4/oT5e5ZMIaXgKmWk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ctx0kAR3fgSXtxFhrv+r7nHPc7YtPAsUICXgtaqB7H4+qU5g2hFuEV6B5N5gMIwOK 6sPeHq+mQvxDxjSFOQigU+CqsfUbrex63HWdSk9UmvhsgS4vrAFlLDtA+v8TTef6zB GTq6xfCUsl0JT1TeBGN0VZ8uYJsmyEYAqYhJB8iE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Matt McDonald , "Rafael J. Wysocki" , Giovanni Gherdovich , Michael Larabel Subject: [PATCH 5.10 483/663] cpufreq: ACPI: Set cpuinfo.max_freq directly if max boost is known Date: Mon, 1 Mar 2021 17:12:11 +0100 Message-Id: <20210301161205.762419466@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161141.760350206@linuxfoundation.org> References: <20210301161141.760350206@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki commit 538b0188da4653b9f4511a114f014354fb6fb7a5 upstream. Commit 3c55e94c0ade ("cpufreq: ACPI: Extend frequency tables to cover boost frequencies") attempted to address a performance issue involving acpi-cpufreq, the schedutil governor and scale-invariance on x86 by extending the frequency tables created by acpi-cpufreq to cover the entire range of "turbo" (or "boost") frequencies, but that caused frequencies reported via /proc/cpuinfo and the scaling_cur_freq attribute in sysfs to change which may confuse users and monitoring tools. For this reason, revert the part of commit 3c55e94c0ade adding the extra entry to the frequency table and use the observation that in principle cpuinfo.max_freq need not be equal to the maximum frequency listed in the frequency table for the given policy. Namely, modify cpufreq_frequency_table_cpuinfo() to allow cpufreq drivers to set their own cpuinfo.max_freq above that frequency and change acpi-cpufreq to set cpuinfo.max_freq to the maximum boost frequency found via CPPC. This should be sufficient to let all of the cpufreq subsystem know the real maximum frequency of the CPU without changing frequency reporting. Link: https://bugzilla.kernel.org/show_bug.cgi?id=211305 Fixes: 3c55e94c0ade ("cpufreq: ACPI: Extend frequency tables to cover boost frequencies") Reported-by: Matt McDonald Tested-by: Matt McDonald Signed-off-by: Rafael J. Wysocki Tested-by: Giovanni Gherdovich Tested-by: Michael Larabel Cc: 5.11+ # 5.11+ Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/acpi-cpufreq.c | 62 ++++++++++------------------------------- drivers/cpufreq/freq_table.c | 8 ++++- 2 files changed, 23 insertions(+), 47 deletions(-) --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -54,7 +54,6 @@ struct acpi_cpufreq_data { unsigned int resume; unsigned int cpu_feature; unsigned int acpi_perf_cpu; - unsigned int first_perf_state; cpumask_var_t freqdomain_cpus; void (*cpu_freq_write)(struct acpi_pct_register *reg, u32 val); u32 (*cpu_freq_read)(struct acpi_pct_register *reg); @@ -223,10 +222,10 @@ static unsigned extract_msr(struct cpufr perf = to_perf_data(data); - cpufreq_for_each_entry(pos, policy->freq_table + data->first_perf_state) + cpufreq_for_each_entry(pos, policy->freq_table) if (msr == perf->states[pos->driver_data].status) return pos->frequency; - return policy->freq_table[data->first_perf_state].frequency; + return policy->freq_table[0].frequency; } static unsigned extract_freq(struct cpufreq_policy *policy, u32 val) @@ -365,7 +364,6 @@ static unsigned int get_cur_freq_on_cpu( struct cpufreq_policy *policy; unsigned int freq; unsigned int cached_freq; - unsigned int state; pr_debug("%s (%d)\n", __func__, cpu); @@ -377,11 +375,7 @@ static unsigned int get_cur_freq_on_cpu( if (unlikely(!data || !policy->freq_table)) return 0; - state = to_perf_data(data)->state; - if (state < data->first_perf_state) - state = data->first_perf_state; - - cached_freq = policy->freq_table[state].frequency; + cached_freq = policy->freq_table[to_perf_data(data)->state].frequency; freq = extract_freq(policy, get_cur_val(cpumask_of(cpu), data)); if (freq != cached_freq) { /* @@ -680,7 +674,6 @@ static int acpi_cpufreq_cpu_init(struct struct cpuinfo_x86 *c = &cpu_data(cpu); unsigned int valid_states = 0; unsigned int result = 0; - unsigned int state_count; u64 max_boost_ratio; unsigned int i; #ifdef CONFIG_SMP @@ -795,28 +788,8 @@ static int acpi_cpufreq_cpu_init(struct goto err_unreg; } - state_count = perf->state_count + 1; - - max_boost_ratio = get_max_boost_ratio(cpu); - if (max_boost_ratio) { - /* - * Make a room for one more entry to represent the highest - * available "boost" frequency. - */ - state_count++; - valid_states++; - data->first_perf_state = valid_states; - } else { - /* - * If the maximum "boost" frequency is unknown, ask the arch - * scale-invariance code to use the "nominal" performance for - * CPU utilization scaling so as to prevent the schedutil - * governor from selecting inadequate CPU frequencies. - */ - arch_set_max_freq_ratio(true); - } - - freq_table = kcalloc(state_count, sizeof(*freq_table), GFP_KERNEL); + freq_table = kcalloc(perf->state_count + 1, sizeof(*freq_table), + GFP_KERNEL); if (!freq_table) { result = -ENOMEM; goto err_unreg; @@ -851,27 +824,25 @@ static int acpi_cpufreq_cpu_init(struct } freq_table[valid_states].frequency = CPUFREQ_TABLE_END; + max_boost_ratio = get_max_boost_ratio(cpu); if (max_boost_ratio) { - unsigned int state = data->first_perf_state; - unsigned int freq = freq_table[state].frequency; + unsigned int freq = freq_table[0].frequency; /* * Because the loop above sorts the freq_table entries in the * descending order, freq is the maximum frequency in the table. * Assume that it corresponds to the CPPC nominal frequency and - * use it to populate the frequency field of the extra "boost" - * frequency entry. + * use it to set cpuinfo.max_freq. */ - freq_table[0].frequency = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; + policy->cpuinfo.max_freq = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; + } else { /* - * The purpose of the extra "boost" frequency entry is to make - * the rest of cpufreq aware of the real maximum frequency, but - * the way to request it is the same as for the first_perf_state - * entry that is expected to cover the entire range of "boost" - * frequencies of the CPU, so copy the driver_data value from - * that entry. + * If the maximum "boost" frequency is unknown, ask the arch + * scale-invariance code to use the "nominal" performance for + * CPU utilization scaling so as to prevent the schedutil + * governor from selecting inadequate CPU frequencies. */ - freq_table[0].driver_data = freq_table[state].driver_data; + arch_set_max_freq_ratio(true); } policy->freq_table = freq_table; @@ -947,8 +918,7 @@ static void acpi_cpufreq_cpu_ready(struc { struct acpi_processor_performance *perf = per_cpu_ptr(acpi_perf_data, policy->cpu); - struct acpi_cpufreq_data *data = policy->driver_data; - unsigned int freq = policy->freq_table[data->first_perf_state].frequency; + unsigned int freq = policy->freq_table[0].frequency; if (perf->states[0].core_frequency * 1000 != freq) pr_warn(FW_WARN "P-state 0 is not max freq\n"); --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -52,7 +52,13 @@ int cpufreq_frequency_table_cpuinfo(stru } policy->min = policy->cpuinfo.min_freq = min_freq; - policy->max = policy->cpuinfo.max_freq = max_freq; + policy->max = max_freq; + /* + * If the driver has set its own cpuinfo.max_freq above max_freq, leave + * it as is. + */ + if (policy->cpuinfo.max_freq < max_freq) + policy->max = policy->cpuinfo.max_freq = max_freq; if (policy->min == ~0) return -EINVAL;