-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Fix two deficiencies in the CPU frequency scaling subsystem #98459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix two deficiencies in the CPU frequency scaling subsystem #98459
Conversation
9a06255 to
ac294e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catches. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for docs
|
@kartben Should this be added to 4.3 release? Is there a label that must be added? |
subsys/cpu_freq/cpu_freq.c
Outdated
| */ | ||
|
|
||
| target_cpus = (num_cpus == 32U) ? 0xFFFFFFFF : (1U << num_cpus) - 1U; | ||
| target_cpus ^= (1U << _current_cpu->id), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typo?
| target_cpus ^= (1U << _current_cpu->id), | |
| target_cpus ^= (1U << _current_cpu->id); |
| uint32_t target_cpus; | ||
| int ret; | ||
|
|
||
| __ASSERT(num_cpus <= 32U, "Too many CPUs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outside PR scope: maybe the Kconfig for CPUFreq should impose range 1 32 to CONFIG_MP_MAX_NUM_CPUS instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be more appropriate to create a separate PR for a global update.
doc/services/cpu_freq/index.rst
Outdated
| The SoC supporting CPU Frequency Scaling must uphold Zephyr's requirement that the system timer remains | ||
| constant over the lifetime of the program. See :ref:`Kernel Timing <kernel_timing>` for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quoting the part of the Kernel Timing page which I think this is referring (emphasis mine):
The frequency of [the system timer] counter is required to be steady over time
Proposal:
| The SoC supporting CPU Frequency Scaling must uphold Zephyr's requirement that the system timer remains | |
| constant over the lifetime of the program. See :ref:`Kernel Timing <kernel_timing>` for more information. | |
| The SoC supporting CPU Frequency Scaling must uphold Zephyr's requirement that the system timer frequency | |
| remains steady over the lifetime of the program. See :ref:`Kernel Timing <kernel_timing>` for more information. |
In the current code, 'target_cpus ^= (1U << _current_cpu->id)' is first used to remove the current core. Then, k_ipi_work_add performs 'target_cpus ^ (1U << _current_cpu->id)' again when passing parameters. This will add the current core to the mask again, causing the current core to receive IPI and directly call cpu_freq_next_pstate() at the end, which may lead to duplicate execution. This commit changed 'target_cpus ^ (1U << _current_cpu->id)' to 'target_cpus' in k_ipi_work_add to avoid the second XOR. Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
The current code calls cpu_freq_policy_reset() once within the SMP branch of the cpu_freq_timer_handler function, and then calls it again at the beginning of cpu_freq_next_pstate(). This causes repeated resets of 'pstate_best' and 'num_unprocessed_cpus', which prevents the 'last core' from being reached. The initiating core should perform a reset before broadcasting, and other cores should not reset again. Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Improve cpu_freq documentation. Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
8341cf1
ac294e3 to
8341cf1
Compare
|



Three changes in this PR:
k_ipi_work_addIn the current code,
target_cpus ^= (1U << _current_cpu->id)is first used to remove the current core. Then,k_ipi_work_addperformstarget_cpus ^ (1U << _current_cpu->id)again when passing parameters. This will add the current core to the mask again, causing the current core to receive IPI and directly callcpu_freq_next_pstate()at the end, which may lead to duplicate execution. This first change is to changetarget_cpus ^ (1U << _current_cpu->id)totarget_cpusink_ipi_work_addto avoid the second XOR.cpu_freq_policy_reset()The current code calls
cpu_freq_policy_reset()once within the SMP branch of thecpu_freq_timer_handlerfunction, and then calls it again at the beginning ofcpu_freq_next_pstate(). This causes repeated resets ofpstate_bestandnum_unprocessed_cpus, which prevents the 'last core' from being reached. The initiating core should perform a reset before broadcasting, and other cores should not reset again.cpu_freqdocumentation.