From: "Yufan Dou" <douyufan@picoheart.com>
To: "Sunil V L" <sunilvl@ventanamicro.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
"Len Brown" <lenb@kernel.org>, "Paul Walmsley" <pjw@kernel.org>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>, <linux-acpi@vger.kernel.org>,
<linux-riscv@lists.infradead.org>,
<linux-kernel@vger.kernel.org>
Cc: <yuchao.46@picoheart.com>, <zhanjie9@hisilicon.com>,
<yang.yicong@picoheart.com>, <geshijian@picoheart.com>
Subject: [PATCH] ACPI: RISC-V: CPPC: Implement cpc_read_ffh_fb_ctrs()
Date: Wed, 2 Sep 2026 16:34:50 +0800 [thread overview]
Message-ID: <20260902083450.2348-1-douyufan@picoheart.com> (raw)
On RISC-V, each cpc_read_ffh() for a CSR-type FFH register sends a
separate IPI to the target hart via smp_call_function_single().
cppc_get_perf_ctrs() therefore samples the delivered and reference
counters in two separate IPIs, at two different instants. The skew
between the two sampling points distorts the delivered/reference
ratio and thus the frequency reported by cpufreq.
Implement the cpc_read_ffh_fb_ctrs() hook to read both CSR counters
back-to-back in a single IPI, which narrows the sampling window to a
few instructions and halves the number of cross-CPU calls. This
improves the accuracy of the reported frequency in the same way as
the arm64 implementation of the hook, which reads both AMU counters
in a single counters_read_on_cpu() call.
SBI-type FFH registers still fall back to individual reads, since
pairing them would not reduce the number of SBI calls on the target
hart.
Testing was performed while CPU1 was kept busy with:
# stress-ng --cpu 1 --taskset 1
On a CPU with cpuinfo_max_freq of 3000000 kHz:
Before:
Maximum observed cpuinfo_cur_freq: 3201369 kHz
Maximum observed error: +201369 kHz (+6.71%)
After:
Maximum observed cpuinfo_cur_freq: 3009646 kHz
Maximum observed error: +9646 kHz (+0.32%)
The maximum observed error is reduced by 95.2%.
Signed-off-by: Yufan Dou <douyufan@picoheart.com>
---
drivers/acpi/riscv/cppc.c | 47 +++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/acpi/riscv/cppc.c b/drivers/acpi/riscv/cppc.c
index 42c1a9052470..2ca98fa69e9a 100644
--- a/drivers/acpi/riscv/cppc.c
+++ b/drivers/acpi/riscv/cppc.c
@@ -85,6 +85,20 @@ static void cppc_ffh_csr_write(void *write_data)
data->ret.error = -EINVAL;
}
+struct sbi_cppc_fb_ctrs_data {
+ struct sbi_cppc_data first;
+ struct sbi_cppc_data second;
+};
+
+static void cppc_ffh_csr_read_fb_ctrs(void *read_data)
+{
+ struct sbi_cppc_fb_ctrs_data *data = read_data;
+
+ cppc_ffh_csr_read(&data->first);
+ if (!data->first.ret.error)
+ cppc_ffh_csr_read(&data->second);
+}
+
/*
* Refer to drivers/acpi/cppc_acpi.c for the description of the functions
* below.
@@ -125,6 +139,39 @@ int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val)
return -EINVAL;
}
+int cpc_read_ffh_fb_ctrs(int cpu, struct cpc_reg *reg1, u64 *val1,
+ struct cpc_reg *reg2, u64 *val2)
+{
+ struct sbi_cppc_fb_ctrs_data data;
+ int ret;
+
+ if (WARN_ON_ONCE(irqs_disabled()))
+ return -EPERM;
+
+ /* Only CSR counters can be paired within a single IPI. */
+ if (FFH_CPPC_TYPE(reg1->address) != FFH_CPPC_CSR ||
+ FFH_CPPC_TYPE(reg2->address) != FFH_CPPC_CSR)
+ return -EOPNOTSUPP;
+
+ data.first.reg = FFH_CPPC_CSR_NUM(reg1->address);
+ data.second.reg = FFH_CPPC_CSR_NUM(reg2->address);
+
+ ret = smp_call_function_single(cpu, cppc_ffh_csr_read_fb_ctrs,
+ &data, 1);
+ if (ret)
+ return ret;
+
+ if (data.first.ret.error)
+ return data.first.ret.error;
+ if (data.second.ret.error)
+ return data.second.ret.error;
+
+ *val1 = data.first.ret.value;
+ *val2 = data.second.ret.value;
+
+ return 0;
+}
+
int cpc_write_ffh(int cpu, struct cpc_reg *reg, u64 val)
{
struct sbi_cppc_data data;
base-commit: 89a312991dc6e638a36adc43ccb91dbc25504c04
--
2.34.1
next reply other threads:[~2026-09-02 8:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 8:34 Yufan Dou [this message]
2026-09-03 5:11 ` Sunil V L
2026-09-07 11:29 ` Jie Zhan
2026-09-07 13:17 ` Yicong Yang
2026-09-07 13:38 ` Jie Zhan
2026-09-09 7:15 ` [PATCH v2] " Yufan Dou
2026-09-17 9:11 ` Jie Zhan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902083450.2348-1-douyufan@picoheart.com \
--to=douyufan@picoheart.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=geshijian@picoheart.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=rafael@kernel.org \
--cc=sunilvl@ventanamicro.com \
--cc=yang.yicong@picoheart.com \
--cc=yuchao.46@picoheart.com \
--cc=zhanjie9@hisilicon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®