Re: [PATCH 4/5] cpufreq: loongson3: Use global physical CPU ID in get/target callbacks
Huacai Chen <[email protected]>
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm,org.kernel.vger.stable |
|---|---|
| Message-ID | <CAAhV-H4BRGeZ48PMJcYNR_Nn2-=Emec=pXsD041ZwWzJ5vo8nQ@mail.gmail.com> |
Hi, Zhongqiu, On Thu, Aug 20, 2026 at 8:24 PM Zhongqiu Han <[email protected]> wrote: > > On 8/18/2026 8:39 PM, Huacai Chen wrote: > > Our server productions (e.g. Loongson-3D6000/3E6000) can have discrete > > global physical CPU IDs while the core ID inside the packages are always > > continuous. In these cases we should use global physical CPU IDs to get > > and set frequencies. > > > > Cc: [email protected] > > Signed-off-by: Hongliang Wang <[email protected]> > > Signed-off-by: Huacai Chen <[email protected]> > > --- > > drivers/cpufreq/loongson3_cpufreq.c | 20 +++++++++++--------- > > 1 file changed, 11 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/cpufreq/loongson3_cpufreq.c b/drivers/cpufreq/loongson3_cpufreq.c > > index e3cd78a5ab18..c75c0e30e881 100644 > > --- a/drivers/cpufreq/loongson3_cpufreq.c > > +++ b/drivers/cpufreq/loongson3_cpufreq.c > > @@ -219,38 +219,40 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext > > > > static unsigned int loongson3_cpufreq_get(unsigned int cpu) > > { > > - int ret; > > + int ret, core = cpu_logical_map(cpu); > > > > - ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0); > > + ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0); > > As patch 5/5 changelog: > > "However, IOCSR read/write can only perform on the current node, while > sometimes we want to perform on other nodes" > > However, patch 4/5 starts passing the global CPU number without updating > do_service_request(), which is only changed in patch 5/5. Doesn't that > mean patch 4/5 is broken on its own? Cross-node accesses need the whole of this series. So: For single node machines, with or without this patch are both correct. For multi-nodes machines, this patch cannot solve all problems, but doesn't make things worse. > > > > > return ret * KILO; > > } > > > > A separate issue, do_service_request() can return errno such as -EPERM, > it will cause .get() func return a large unsigned integer value. Yes, we need "return (ret < 0) ? 0 : ret * KILO" here. Huacai > > > > static int loongson3_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) > > { > > - int ret; > > + int ret, core = cpu_logical_map(policy->cpu); > > > > - ret = do_service_request(cpu_data[policy->cpu].core, > > - FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO, index, 0); > > + ret = do_service_request(core, FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO, > > + index, 0); > > > > return (ret >= 0) ? 0 : ret; > > } > > > > static int configure_freq_table(int cpu) > > { > > - int i, ret, boost_level, max_level, freq_level; > > + int i, ret, core, boost_level, max_level, freq_level; > > struct platform_device *pdev = cpufreq_get_driver_data(); > > struct loongson3_freq_data *data; > > > > if (per_cpu(freq_data, cpu)) > > return 0; > > > > - ret = do_service_request(cpu, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0); > > + core = cpu_logical_map(cpu); > > + > > + ret = do_service_request(core, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0); > > if (ret < 0) > > return ret; > > max_level = ret; > > > > - ret = do_service_request(cpu, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0); > > + ret = do_service_request(core, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0); > > if (ret < 0) > > return ret; > > boost_level = ret; > > @@ -263,7 +265,7 @@ static int configure_freq_table(int cpu) > > data->def_freq_level = boost_level - 1; > > > > for (i = 0; i < freq_level; i++) { > > - ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0); > > + ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0); > > if (ret < 0) { > > devm_kfree(&pdev->dev, data); > > return ret; > > > -- > Thx and BRs, > Zhongqiu Han >