Message ID | 20231025093847.3740104-3-zengheng4@huawei.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce89:0:b0:403:3b70:6f57 with SMTP id p9csp2475130vqx; Wed, 25 Oct 2023 02:34:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFvSLJ1fUQUkh6RxTQKyuoIRD6/33gjNsxtpegAvKn/2cMUyvxIFDj/h6/KtaB/rQ/92lk/ X-Received: by 2002:a81:834a:0:b0:59b:ce0b:7829 with SMTP id t71-20020a81834a000000b0059bce0b7829mr15312244ywf.35.1698226457722; Wed, 25 Oct 2023 02:34:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698226457; cv=none; d=google.com; s=arc-20160816; b=MtlLHOeesNkiKRBm86q21xdoNXRgzxi6M1j/ErNKGOGYz9jmfIw71HHRECM0AXqzm3 m7kMyrLoLvEK3Xtjz9eda5t/lnZL4bLeNrNiPSlPQG3+aqBv6gLfx3iKIliS6UsA4rrF ORywaseu8rf94bhKhkoc3jFUvEATTUN/7Ixm9RR9A/XBKPp/4+EYCJJ0uLsamY787hP5 WbgZnxpBopQcnDfgD8Eyap/ltt2Mfk5zPPqLUan9Nwj2fTRK0bMX0hVtNg91KRjEKZqQ wHjf5G1gwegaXYe6brZWtfWXrVoVqQuMqj+1EqBpWB+iLap2uBDm7Cy99R7tqj1o6Jcs pHgQ== 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=U+egVtAxddwCyS34iAMjTcm4d658tB2OimmidtL3ohE=; fh=4OYJ3K2D0ofBlGhh3O4YuBicy23CNIUxbo78mZx4uJc=; b=owldYA+UzTuVY2Qz/qgHoCjcF0C6wa0pxZauYh465pdIYRhqHUdBUvf/BE8DUonf8D fU+Zft2hpYtGYVbI/uMe3fPRrAhudPupV/gt0QYkuDgO/AOEnqNonp8ZtVnxvaZtOJ6v AAIEZUjz0heNMQXwIOA5Zkkq9ju/PzmfdTENEyS74aRvjqKNPg3ZsRp/XbfMQzHjFtN0 rrzpj676xX+CW96EDYxLM7zuSus7KkDvG7Ntqrn8Mb5Q22woYn2FjaYQqw/oUcSg9ZGL 44teVSSoHlazAMdcdzvooSJ+TM6qHX+meH24o2QnSceMWtZkFB5qlXuuXcNxP4c0C7Na /3XA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id x62-20020a0dd541000000b0059f57c89016si10843911ywd.119.2023.10.25.02.34.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Oct 2023 02:34:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id E9DFA8029237; Wed, 25 Oct 2023 02:34:14 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234456AbjJYJds (ORCPT <rfc822;aposhian.dev@gmail.com> + 26 others); Wed, 25 Oct 2023 05:33:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232808AbjJYJdp (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 25 Oct 2023 05:33:45 -0400 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37311CE; Wed, 25 Oct 2023 02:33:43 -0700 (PDT) Received: from kwepemi500024.china.huawei.com (unknown [172.30.72.56]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4SFkF46rL7z15NKS; Wed, 25 Oct 2023 17:30:48 +0800 (CST) Received: from huawei.com (10.175.103.91) by kwepemi500024.china.huawei.com (7.221.188.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Wed, 25 Oct 2023 17:33:39 +0800 From: Zeng Heng <zengheng4@huawei.com> To: <broonie@kernel.org>, <joey.gouly@arm.com>, <will@kernel.org>, <amit.kachhap@arm.com>, <rafael@kernel.org>, <catalin.marinas@arm.com>, <james.morse@arm.com>, <mark.rutland@arm.com>, <maz@kernel.org>, <viresh.kumar@linaro.org>, <sumitg@nvidia.com>, <yang@os.amperecomputing.com> CC: <linux-kernel@vger.kernel.org>, <linux-pm@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <wangxiongfeng2@huawei.com>, <xiexiuqi@huawei.com> Subject: [PATCH 2/3] cpufreq: CPPC: Keep the target core awake when reading its cpufreq rate Date: Wed, 25 Oct 2023 17:38:46 +0800 Message-ID: <20231025093847.3740104-3-zengheng4@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231025093847.3740104-1-zengheng4@huawei.com> References: <20231025093847.3740104-1-zengheng4@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.103.91] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemi500024.china.huawei.com (7.221.188.100) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Wed, 25 Oct 2023 02:34:15 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780719506449251055 X-GMAIL-MSGID: 1780719506449251055 |
Series |
Make the cpuinfo_cur_freq interface read correctly
|
|
Commit Message
Zeng Heng
Oct. 25, 2023, 9:38 a.m. UTC
As ARM AMU's document says, all counters are subject to any changes
in clock frequency, including clock stopping caused by the WFI and WFE
instructions.
Therefore, using smp_call_on_cpu() to trigger target CPU to
read self's AMU counters, which ensures the counters are working
properly while cstate feature is enabled.
Reported-by: Sumit Gupta <sumitg@nvidia.com>
Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 9 deletions(-)
Comments
[adding Ionela] On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: > As ARM AMU's document says, all counters are subject to any changes > in clock frequency, including clock stopping caused by the WFI and WFE > instructions. > > Therefore, using smp_call_on_cpu() to trigger target CPU to > read self's AMU counters, which ensures the counters are working > properly while cstate feature is enabled. IIUC there's a pretty deliberate split with all the actual reading of the AMU living in arch/arm64/kernel/topolgy.c, and the driver code being (relatively) generic. We already have code in arch/arm64/kernel/topolgy.c to read counters on a specific CPU; why can't e reuse that (and avoid exporting cpu_has_amu_feat())? Mark. > > Reported-by: Sumit Gupta <sumitg@nvidia.com> > Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ > Signed-off-by: Zeng Heng <zengheng4@huawei.com> > --- > drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- > 1 file changed, 30 insertions(+), 9 deletions(-) > > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c > index fe08ca419b3d..321a9dc9484d 100644 > --- a/drivers/cpufreq/cppc_cpufreq.c > +++ b/drivers/cpufreq/cppc_cpufreq.c > @@ -90,6 +90,12 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, > struct cppc_perf_fb_ctrs *fb_ctrs_t0, > struct cppc_perf_fb_ctrs *fb_ctrs_t1); > > +struct fb_ctr_pair { > + u32 cpu; > + struct cppc_perf_fb_ctrs fb_ctrs_t0; > + struct cppc_perf_fb_ctrs fb_ctrs_t1; > +}; > + > /** > * cppc_scale_freq_workfn - CPPC arch_freq_scale updater for frequency invariance > * @work: The work item. > @@ -840,9 +846,24 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, > return (reference_perf * delta_delivered) / delta_reference; > } > > +static int cppc_get_perf_ctrs_pair(void *val) > +{ > + struct fb_ctr_pair *fb_ctrs = val; > + int cpu = fb_ctrs->cpu; > + int ret; > + > + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); > + if (ret) > + return ret; > + > + udelay(2); /* 2usec delay between sampling */ > + > + return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); > +} > + > static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > { > - struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; > + struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; > struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); > struct cppc_cpudata *cpu_data = policy->driver_data; > u64 delivered_perf; > @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > > cpufreq_cpu_put(policy); > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); > - if (ret) > - return 0; > - > - udelay(2); /* 2usec delay between sampling */ > + if (cpu_has_amu_feat(cpu)) > + ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, > + &fb_ctrs, false); > + else > + ret = cppc_get_perf_ctrs_pair(&fb_ctrs); > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1); > if (ret) > return 0; > > - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, > - &fb_ctrs_t1); > + delivered_perf = cppc_perf_from_fbctrs(cpu_data, > + &fb_ctrs.fb_ctrs_t0, > + &fb_ctrs.fb_ctrs_t1); > > return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); > } > -- > 2.25.1 >
On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: > As ARM AMU's document says, all counters are subject to any changes > in clock frequency, including clock stopping caused by the WFI and WFE > instructions. > > Therefore, using smp_call_on_cpu() to trigger target CPU to > read self's AMU counters, which ensures the counters are working > properly while cstate feature is enabled. > > Reported-by: Sumit Gupta <sumitg@nvidia.com> > Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ > Signed-off-by: Zeng Heng <zengheng4@huawei.com> > --- > drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- > 1 file changed, 30 insertions(+), 9 deletions(-) > > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c > index fe08ca419b3d..321a9dc9484d 100644 > --- a/drivers/cpufreq/cppc_cpufreq.c > +++ b/drivers/cpufreq/cppc_cpufreq.c [...] > @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > > cpufreq_cpu_put(policy); > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); > - if (ret) > - return 0; > - > - udelay(2); /* 2usec delay between sampling */ > + if (cpu_has_amu_feat(cpu)) Have you compiled this on x86 ? Even if you have somehow managed to, this is not the right place to check the presence of AMU feature on the CPU. If AMU registers are used in CPPC, they must be using FFH GAS, in which case the interpretation of FFH is architecture dependent code. -- Regards, Sudeep
> [adding Ionela] > > On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: >> As ARM AMU's document says, all counters are subject to any changes >> in clock frequency, including clock stopping caused by the WFI and WFE >> instructions. >> >> Therefore, using smp_call_on_cpu() to trigger target CPU to >> read self's AMU counters, which ensures the counters are working >> properly while cstate feature is enabled. > > IIUC there's a pretty deliberate split with all the actual reading of the AMU > living in arch/arm64/kernel/topolgy.c, and the driver code being (relatively) > generic. > > We already have code in arch/arm64/kernel/topolgy.c to read counters on a > specific CPU; why can't e reuse that (and avoid exporting cpu_has_amu_feat())? This patch seems mostly based on my previous patch [1] and discussed here [2] already. Beata [CCed] shared an alternate approach [3] leveraging existing code from 'topology.c' to get the average freq for last tick period. Beata, Could you share v2 of [3] with the request to merge. We can try to solve the issue with CPU IDLE case later on top? Additionally, also please include the fix in [4] if it looks fine. Best Regards, Sumit Gupta [1] https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ [2] https://lore.kernel.org/lkml/cde1d8a9-3a21-e82b-7895-40603a14d898@nvidia.com/T/#m2174305de4706006e0bd9c103a0e5ff61cea7a12 [3] https://lore.kernel.org/lkml/20230606155754.245998-1-beata.michalska@arm.com/ [4] https://lore.kernel.org/lkml/6a5710f6-bfbb-5dfd-11cd-0cd02220cee7@nvidia.com/ >> >> Reported-by: Sumit Gupta <sumitg@nvidia.com> >> Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ >> Signed-off-by: Zeng Heng <zengheng4@huawei.com> >> --- >> drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- >> 1 file changed, 30 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c >> index fe08ca419b3d..321a9dc9484d 100644 >> --- a/drivers/cpufreq/cppc_cpufreq.c >> +++ b/drivers/cpufreq/cppc_cpufreq.c >> @@ -90,6 +90,12 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, >> struct cppc_perf_fb_ctrs *fb_ctrs_t0, >> struct cppc_perf_fb_ctrs *fb_ctrs_t1); >> >> +struct fb_ctr_pair { >> + u32 cpu; >> + struct cppc_perf_fb_ctrs fb_ctrs_t0; >> + struct cppc_perf_fb_ctrs fb_ctrs_t1; >> +}; >> + >> /** >> * cppc_scale_freq_workfn - CPPC arch_freq_scale updater for frequency invariance >> * @work: The work item. >> @@ -840,9 +846,24 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, >> return (reference_perf * delta_delivered) / delta_reference; >> } >> >> +static int cppc_get_perf_ctrs_pair(void *val) >> +{ >> + struct fb_ctr_pair *fb_ctrs = val; >> + int cpu = fb_ctrs->cpu; >> + int ret; >> + >> + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); >> + if (ret) >> + return ret; >> + >> + udelay(2); /* 2usec delay between sampling */ >> + >> + return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); >> +} >> + >> static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >> { >> - struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; >> + struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; >> struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); >> struct cppc_cpudata *cpu_data = policy->driver_data; >> u64 delivered_perf; >> @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >> >> cpufreq_cpu_put(policy); >> >> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); >> - if (ret) >> - return 0; >> - >> - udelay(2); /* 2usec delay between sampling */ >> + if (cpu_has_amu_feat(cpu)) >> + ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, >> + &fb_ctrs, false); >> + else >> + ret = cppc_get_perf_ctrs_pair(&fb_ctrs); >> >> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1); >> if (ret) >> return 0; >> >> - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, >> - &fb_ctrs_t1); >> + delivered_perf = cppc_perf_from_fbctrs(cpu_data, >> + &fb_ctrs.fb_ctrs_t0, >> + &fb_ctrs.fb_ctrs_t1); >> >> return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); >> } >> -- >> 2.25.1 >>
在 2023/10/25 19:13, Sudeep Holla 写道: > On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: >> As ARM AMU's document says, all counters are subject to any changes >> in clock frequency, including clock stopping caused by the WFI and WFE >> instructions. >> >> Therefore, using smp_call_on_cpu() to trigger target CPU to >> read self's AMU counters, which ensures the counters are working >> properly while cstate feature is enabled. >> >> Reported-by: Sumit Gupta <sumitg@nvidia.com> >> Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ >> Signed-off-by: Zeng Heng <zengheng4@huawei.com> >> --- >> drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- >> 1 file changed, 30 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c >> index fe08ca419b3d..321a9dc9484d 100644 >> --- a/drivers/cpufreq/cppc_cpufreq.c >> +++ b/drivers/cpufreq/cppc_cpufreq.c > [...] > >> @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >> >> cpufreq_cpu_put(policy); >> >> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); >> - if (ret) >> - return 0; >> - >> - udelay(2); /* 2usec delay between sampling */ >> + if (cpu_has_amu_feat(cpu)) > Have you compiled this on x86 ? Even if you have somehow managed to, > this is not the right place to check the presence of AMU feature on > the CPU. > If AMU registers are used in CPPC, they must be using FFH GAS, in which > case the interpretation of FFH is architecture dependent code. According to drivers/cpufreq/Makefile, cppc_cpufreq.c is only compiled with ARM architecture. But here, I would change cpu_has_amu_feat() with cpc_ffh_supported(), which belongs to FFH APIs. Thanks for the suggestion. Thanks again, Zeng Heng > -- > Regards, > Sudeep >
在 2023/10/25 18:54, Mark Rutland 写道: > [adding Ionela] > > On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: >> As ARM AMU's document says, all counters are subject to any changes >> in clock frequency, including clock stopping caused by the WFI and WFE >> instructions. >> >> Therefore, using smp_call_on_cpu() to trigger target CPU to >> read self's AMU counters, which ensures the counters are working >> properly while cstate feature is enabled. > IIUC there's a pretty deliberate split with all the actual reading of the AMU > living in arch/arm64/kernel/topolgy.c, and the driver code being (relatively) > generic. > > We already have code in arch/arm64/kernel/topolgy.c to read counters on a > specific CPU; why can't e reuse that (and avoid exporting cpu_has_amu_feat())? > > Mark. In this scenario, both topology.c and cppc_acpi.c do not provide an API to keep the AMU online during the whole sampling period. Just using cpc_read_ffh at the start and end of the sampling period is not enough. However, I can propose cpc_ffh_supported() function to replace the cpu_has_amu_feat() as v2 if you think this patch set is still valuable. Thanks, Zeng Heng >> Reported-by: Sumit Gupta <sumitg@nvidia.com> >> Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ >> Signed-off-by: Zeng Heng <zengheng4@huawei.com> >> --- >> drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- >> 1 file changed, 30 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c >> index fe08ca419b3d..321a9dc9484d 100644 >> --- a/drivers/cpufreq/cppc_cpufreq.c >> +++ b/drivers/cpufreq/cppc_cpufreq.c >> @@ -90,6 +90,12 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, >> struct cppc_perf_fb_ctrs *fb_ctrs_t0, >> struct cppc_perf_fb_ctrs *fb_ctrs_t1); >> >> +struct fb_ctr_pair { >> + u32 cpu; >> + struct cppc_perf_fb_ctrs fb_ctrs_t0; >> + struct cppc_perf_fb_ctrs fb_ctrs_t1; >> +}; >> + >> /** >> * cppc_scale_freq_workfn - CPPC arch_freq_scale updater for frequency invariance >> * @work: The work item. >> @@ -840,9 +846,24 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, >> return (reference_perf * delta_delivered) / delta_reference; >> } >> >> +static int cppc_get_perf_ctrs_pair(void *val) >> +{ >> + struct fb_ctr_pair *fb_ctrs = val; >> + int cpu = fb_ctrs->cpu; >> + int ret; >> + >> + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); >> + if (ret) >> + return ret; >> + >> + udelay(2); /* 2usec delay between sampling */ >> + >> + return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); >> +} >> + >> static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >> { >> - struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; >> + struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; >> struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); >> struct cppc_cpudata *cpu_data = policy->driver_data; >> u64 delivered_perf; >> @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >> >> cpufreq_cpu_put(policy); >> >> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); >> - if (ret) >> - return 0; >> - >> - udelay(2); /* 2usec delay between sampling */ >> + if (cpu_has_amu_feat(cpu)) >> + ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, >> + &fb_ctrs, false); >> + else >> + ret = cppc_get_perf_ctrs_pair(&fb_ctrs); >> >> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1); >> if (ret) >> return 0; >> >> - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, >> - &fb_ctrs_t1); >> + delivered_perf = cppc_perf_from_fbctrs(cpu_data, >> + &fb_ctrs.fb_ctrs_t0, >> + &fb_ctrs.fb_ctrs_t1); >> >> return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); >> } >> -- >> 2.25.1 >>
On Thu, Oct 26, 2023 at 10:24:54AM +0800, Zeng Heng wrote: > > 在 2023/10/25 19:13, Sudeep Holla 写道: > > On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: > > > As ARM AMU's document says, all counters are subject to any changes > > > in clock frequency, including clock stopping caused by the WFI and WFE > > > instructions. > > > > > > Therefore, using smp_call_on_cpu() to trigger target CPU to > > > read self's AMU counters, which ensures the counters are working > > > properly while cstate feature is enabled. > > > > > > Reported-by: Sumit Gupta <sumitg@nvidia.com> > > > Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ > > > Signed-off-by: Zeng Heng <zengheng4@huawei.com> > > > --- > > > drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- > > > 1 file changed, 30 insertions(+), 9 deletions(-) > > > > > > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c > > > index fe08ca419b3d..321a9dc9484d 100644 > > > --- a/drivers/cpufreq/cppc_cpufreq.c > > > +++ b/drivers/cpufreq/cppc_cpufreq.c > > [...] > > > > > @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > > > cpufreq_cpu_put(policy); > > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); > > > - if (ret) > > > - return 0; > > > - > > > - udelay(2); /* 2usec delay between sampling */ > > > + if (cpu_has_amu_feat(cpu)) > > Have you compiled this on x86 ? Even if you have somehow managed to, > > this is not the right place to check the presence of AMU feature on > > the CPU. > > If AMU registers are used in CPPC, they must be using FFH GAS, in which > > case the interpretation of FFH is architecture dependent code. > > According to drivers/cpufreq/Makefile, cppc_cpufreq.c is only compiled with > ARM architecture. > Well that's true but this change doesn't belong to cppc_cpufreq.c, it must be part of drivers/acpi/cppc_acpi.c IMO and sorry I assumed that without explicitly mentioning that here. > But here, I would change cpu_has_amu_feat() with cpc_ffh_supported(), which > belongs to FFH APIs. > It is not like that. cppc_acpi.c will know the GAS is FFH based so no need to check anything there. I see counters_read_on_cpu() called from cpc_ffh_read() already takes care of reading the AMUs on the right CPU. What exactly is the issue you are seeing ? I don't if this change is needed at all. -- Regards, Sudeep
在 2023/10/26 16:53, Sudeep Holla 写道: > On Thu, Oct 26, 2023 at 10:24:54AM +0800, Zeng Heng wrote: >> 在 2023/10/25 19:13, Sudeep Holla 写道: >>> On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: >>>> As ARM AMU's document says, all counters are subject to any changes >>>> in clock frequency, including clock stopping caused by the WFI and WFE >>>> instructions. >>>> >>>> Therefore, using smp_call_on_cpu() to trigger target CPU to >>>> read self's AMU counters, which ensures the counters are working >>>> properly while cstate feature is enabled. >>>> >>>> Reported-by: Sumit Gupta <sumitg@nvidia.com> >>>> Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ >>>> Signed-off-by: Zeng Heng <zengheng4@huawei.com> >>>> --- >>>> drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- >>>> 1 file changed, 30 insertions(+), 9 deletions(-) >>>> >>>> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c >>>> index fe08ca419b3d..321a9dc9484d 100644 >>>> --- a/drivers/cpufreq/cppc_cpufreq.c >>>> +++ b/drivers/cpufreq/cppc_cpufreq.c >>> [...] >>> >>>> @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) >>>> cpufreq_cpu_put(policy); >>>> - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); >>>> - if (ret) >>>> - return 0; >>>> - >>>> - udelay(2); /* 2usec delay between sampling */ >>>> + if (cpu_has_amu_feat(cpu)) >>> Have you compiled this on x86 ? Even if you have somehow managed to, >>> this is not the right place to check the presence of AMU feature on >>> the CPU. >>> If AMU registers are used in CPPC, they must be using FFH GAS, in which >>> case the interpretation of FFH is architecture dependent code. >> According to drivers/cpufreq/Makefile, cppc_cpufreq.c is only compiled with >> ARM architecture. >> > Well that's true but this change doesn't belong to cppc_cpufreq.c, it must > be part of drivers/acpi/cppc_acpi.c IMO and sorry I assumed that without > explicitly mentioning that here. > >> But here, I would change cpu_has_amu_feat() with cpc_ffh_supported(), which >> belongs to FFH APIs. >> > It is not like that. cppc_acpi.c will know the GAS is FFH based so no need to > check anything there. I see counters_read_on_cpu() called from cpc_ffh_read() > already takes care of reading the AMUs on the right CPU. What exactly is > the issue you are seeing ? I don't if this change is needed at all. > > -- > Regards, > Sudeep In this scenario, both topology.c and cppc_acpi.c do not provide an API to keep the AMU online during the whole sampling period. Just using cpc_read_ffh() at the start and end of the sampling period is not enough. Zeng Heng
On Wed, Oct 25, 2023 at 08:27:23PM +0530, Sumit Gupta wrote: > > > > > [adding Ionela] > > > > On Wed, Oct 25, 2023 at 05:38:46PM +0800, Zeng Heng wrote: > > > As ARM AMU's document says, all counters are subject to any changes > > > in clock frequency, including clock stopping caused by the WFI and WFE > > > instructions. > > > > > > Therefore, using smp_call_on_cpu() to trigger target CPU to > > > read self's AMU counters, which ensures the counters are working > > > properly while cstate feature is enabled. > > > > IIUC there's a pretty deliberate split with all the actual reading of the AMU > > living in arch/arm64/kernel/topolgy.c, and the driver code being (relatively) > > generic. > > > > We already have code in arch/arm64/kernel/topolgy.c to read counters on a > > specific CPU; why can't e reuse that (and avoid exporting cpu_has_amu_feat())? > > > This patch seems mostly based on my previous patch [1] and discussed here > [2] already. Beata [CCed] shared an alternate approach [3] leveraging > existing code from 'topology.c' to get the average freq for last tick > period. > > > Beata, > > Could you share v2 of [3] with the request to merge. We can try to solve the > issue with CPU IDLE case later on top? > Will do (same for the below request if feasible) --- BR B. > Additionally, also please include the fix in [4] if it looks fine. > > Best Regards, > Sumit Gupta > > [1] https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ > [2] https://lore.kernel.org/lkml/cde1d8a9-3a21-e82b-7895-40603a14d898@nvidia.com/T/#m2174305de4706006e0bd9c103a0e5ff61cea7a12 > [3] > https://lore.kernel.org/lkml/20230606155754.245998-1-beata.michalska@arm.com/ > [4] > https://lore.kernel.org/lkml/6a5710f6-bfbb-5dfd-11cd-0cd02220cee7@nvidia.com/ > > > > > > > > Reported-by: Sumit Gupta <sumitg@nvidia.com> > > > Link: https://lore.kernel.org/all/20230418113459.12860-7-sumitg@nvidia.com/ > > > Signed-off-by: Zeng Heng <zengheng4@huawei.com> > > > --- > > > drivers/cpufreq/cppc_cpufreq.c | 39 ++++++++++++++++++++++++++-------- > > > 1 file changed, 30 insertions(+), 9 deletions(-) > > > > > > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c > > > index fe08ca419b3d..321a9dc9484d 100644 > > > --- a/drivers/cpufreq/cppc_cpufreq.c > > > +++ b/drivers/cpufreq/cppc_cpufreq.c > > > @@ -90,6 +90,12 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, > > > struct cppc_perf_fb_ctrs *fb_ctrs_t0, > > > struct cppc_perf_fb_ctrs *fb_ctrs_t1); > > > > > > +struct fb_ctr_pair { > > > + u32 cpu; > > > + struct cppc_perf_fb_ctrs fb_ctrs_t0; > > > + struct cppc_perf_fb_ctrs fb_ctrs_t1; > > > +}; > > > + > > > /** > > > * cppc_scale_freq_workfn - CPPC arch_freq_scale updater for frequency invariance > > > * @work: The work item. > > > @@ -840,9 +846,24 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, > > > return (reference_perf * delta_delivered) / delta_reference; > > > } > > > > > > +static int cppc_get_perf_ctrs_pair(void *val) > > > +{ > > > + struct fb_ctr_pair *fb_ctrs = val; > > > + int cpu = fb_ctrs->cpu; > > > + int ret; > > > + > > > + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); > > > + if (ret) > > > + return ret; > > > + > > > + udelay(2); /* 2usec delay between sampling */ > > > + > > > + return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); > > > +} > > > + > > > static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > > > { > > > - struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; > > > + struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; > > > struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); > > > struct cppc_cpudata *cpu_data = policy->driver_data; > > > u64 delivered_perf; > > > @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) > > > > > > cpufreq_cpu_put(policy); > > > > > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); > > > - if (ret) > > > - return 0; > > > - > > > - udelay(2); /* 2usec delay between sampling */ > > > + if (cpu_has_amu_feat(cpu)) > > > + ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, > > > + &fb_ctrs, false); > > > + else > > > + ret = cppc_get_perf_ctrs_pair(&fb_ctrs); > > > > > > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1); > > > if (ret) > > > return 0; > > > > > > - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, > > > - &fb_ctrs_t1); > > > + delivered_perf = cppc_perf_from_fbctrs(cpu_data, > > > + &fb_ctrs.fb_ctrs_t0, > > > + &fb_ctrs.fb_ctrs_t1); > > > > > > return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); > > > } > > > -- > > > 2.25.1 > > >
Hi Zeng, kernel test robot noticed the following build errors: [auto build test ERROR on rafael-pm/linux-next] [also build test ERROR on rafael-pm/acpi-bus arm64/for-next/core linus/master v6.6 next-20231031] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Zeng-Heng/arm64-cpufeature-Export-cpu_has_amu_feat/20231025-173559 base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next patch link: https://lore.kernel.org/r/20231025093847.3740104-3-zengheng4%40huawei.com patch subject: [PATCH 2/3] cpufreq: CPPC: Keep the target core awake when reading its cpufreq rate config: arm64-randconfig-003-20231101 (https://download.01.org/0day-ci/archive/20231101/202311010726.MjF49sPn-lkp@intel.com/config) compiler: aarch64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231101/202311010726.MjF49sPn-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202311010726.MjF49sPn-lkp@intel.com/ All error/warnings (new ones prefixed by >>): drivers/cpufreq/cppc_cpufreq.c: In function 'cppc_get_perf_ctrs_pair': >> drivers/cpufreq/cppc_cpufreq.c:852:26: error: invalid use of undefined type 'struct fb_ctr_pair' 852 | int cpu = fb_ctrs->cpu; | ^~ drivers/cpufreq/cppc_cpufreq.c:855:47: error: invalid use of undefined type 'struct fb_ctr_pair' 855 | ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); | ^~ drivers/cpufreq/cppc_cpufreq.c:861:48: error: invalid use of undefined type 'struct fb_ctr_pair' 861 | return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); | ^~ drivers/cpufreq/cppc_cpufreq.c: In function 'cppc_cpufreq_get_rate': >> drivers/cpufreq/cppc_cpufreq.c:866:16: error: variable 'fb_ctrs' has initializer but incomplete type 866 | struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; | ^~~~~~~~~~~ >> drivers/cpufreq/cppc_cpufreq.c:866:41: error: 'struct fb_ctr_pair' has no member named 'cpu' 866 | struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; | ^~~ >> drivers/cpufreq/cppc_cpufreq.c:866:47: warning: excess elements in struct initializer 866 | struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; | ^~~ drivers/cpufreq/cppc_cpufreq.c:866:47: note: (near initialization for 'fb_ctrs') >> drivers/cpufreq/cppc_cpufreq.c:866:28: error: storage size of 'fb_ctrs' isn't known 866 | struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; | ^~~~~~~ >> drivers/cpufreq/cppc_cpufreq.c:866:28: warning: unused variable 'fb_ctrs' [-Wunused-variable] vim +852 drivers/cpufreq/cppc_cpufreq.c 848 849 static int cppc_get_perf_ctrs_pair(void *val) 850 { 851 struct fb_ctr_pair *fb_ctrs = val; > 852 int cpu = fb_ctrs->cpu; 853 int ret; 854 855 ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); 856 if (ret) 857 return ret; 858 859 udelay(2); /* 2usec delay between sampling */ 860 861 return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); 862 } 863 864 static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) 865 { > 866 struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; 867 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); 868 struct cppc_cpudata *cpu_data = policy->driver_data; 869 u64 delivered_perf; 870 int ret; 871 872 cpufreq_cpu_put(policy); 873 874 if (cpu_has_amu_feat(cpu)) 875 ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, 876 &fb_ctrs, false); 877 else 878 ret = cppc_get_perf_ctrs_pair(&fb_ctrs); 879 880 if (ret) 881 return 0; 882 883 delivered_perf = cppc_perf_from_fbctrs(cpu_data, 884 &fb_ctrs.fb_ctrs_t0, 885 &fb_ctrs.fb_ctrs_t1); 886 887 return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); 888 } 889
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index fe08ca419b3d..321a9dc9484d 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -90,6 +90,12 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, struct cppc_perf_fb_ctrs *fb_ctrs_t0, struct cppc_perf_fb_ctrs *fb_ctrs_t1); +struct fb_ctr_pair { + u32 cpu; + struct cppc_perf_fb_ctrs fb_ctrs_t0; + struct cppc_perf_fb_ctrs fb_ctrs_t1; +}; + /** * cppc_scale_freq_workfn - CPPC arch_freq_scale updater for frequency invariance * @work: The work item. @@ -840,9 +846,24 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, return (reference_perf * delta_delivered) / delta_reference; } +static int cppc_get_perf_ctrs_pair(void *val) +{ + struct fb_ctr_pair *fb_ctrs = val; + int cpu = fb_ctrs->cpu; + int ret; + + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t0); + if (ret) + return ret; + + udelay(2); /* 2usec delay between sampling */ + + return cppc_get_perf_ctrs(cpu, &fb_ctrs->fb_ctrs_t1); +} + static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) { - struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; + struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); struct cppc_cpudata *cpu_data = policy->driver_data; u64 delivered_perf; @@ -850,18 +871,18 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) cpufreq_cpu_put(policy); - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); - if (ret) - return 0; - - udelay(2); /* 2usec delay between sampling */ + if (cpu_has_amu_feat(cpu)) + ret = smp_call_on_cpu(cpu, cppc_get_perf_ctrs_pair, + &fb_ctrs, false); + else + ret = cppc_get_perf_ctrs_pair(&fb_ctrs); - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1); if (ret) return 0; - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, - &fb_ctrs_t1); + delivered_perf = cppc_perf_from_fbctrs(cpu_data, + &fb_ctrs.fb_ctrs_t0, + &fb_ctrs.fb_ctrs_t1); return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); }