Skip to content

Commit c7f5d77

Browse files
lixianglaigregkh
authored andcommitted
LoongArch: Add cpuhotplug hooks to fix high cpu usage of vCPU threads
[ Upstream commit 8ef7f31 ] When the CPU is offline, the timer of LoongArch is not correctly closed. This is harmless for real machines, but resulting in an excessively high cpu usage rate of the offline vCPU thread in the virtual machines. To correctly close the timer, we have made the following modifications: Register the cpu hotplug event (CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING) for LoongArch. This event's hooks will be called to close the timer when the CPU is offline. Clear the timer interrupt when the timer is turned off. Since before the timer is turned off, there may be a timer interrupt that has already been in the pending state due to the interruption of the disabled, which also affects the halt state of the offline vCPU. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent b7c715b commit c7f5d77

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

arch/loongarch/kernel/time.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
66
*/
77
#include <linux/clockchips.h>
8+
#include <linux/cpuhotplug.h>
89
#include <linux/delay.h>
910
#include <linux/export.h>
1011
#include <linux/init.h>
@@ -102,6 +103,23 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev
102103
return 0;
103104
}
104105

106+
static int arch_timer_starting(unsigned int cpu)
107+
{
108+
set_csr_ecfg(ECFGF_TIMER);
109+
110+
return 0;
111+
}
112+
113+
static int arch_timer_dying(unsigned int cpu)
114+
{
115+
constant_set_state_shutdown(this_cpu_ptr(&constant_clockevent_device));
116+
117+
/* Clear Timer Interrupt */
118+
write_csr_tintclear(CSR_TINTCLR_TI);
119+
120+
return 0;
121+
}
122+
105123
static unsigned long get_loops_per_jiffy(void)
106124
{
107125
unsigned long lpj = (unsigned long)const_clock_freq;
@@ -172,6 +190,10 @@ int constant_clockevent_init(void)
172190
lpj_fine = get_loops_per_jiffy();
173191
pr_info("Constant clock event device register\n");
174192

193+
cpuhp_setup_state(CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING,
194+
"clockevents/loongarch/timer:starting",
195+
arch_timer_starting, arch_timer_dying);
196+
175197
return 0;
176198
}
177199

include/linux/cpuhotplug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ enum cpuhp_state {
169169
CPUHP_AP_QCOM_TIMER_STARTING,
170170
CPUHP_AP_TEGRA_TIMER_STARTING,
171171
CPUHP_AP_ARMADA_TIMER_STARTING,
172+
CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING,
172173
CPUHP_AP_MIPS_GIC_TIMER_STARTING,
173174
CPUHP_AP_ARC_TIMER_STARTING,
174175
CPUHP_AP_REALTEK_TIMER_STARTING,

0 commit comments

Comments
 (0)