Commit 247b8dd6 authored by Li Hua's avatar Li Hua Committed by Zheng Zengkai
Browse files

sched/idle: Optimize the loop time algorithm to reduce multicore disturb

hulk inclusion
category: bugfix
bugzilla: 180841 https://gitee.com/openeuler/kernel/issues/I4DDEL



The idle cpu will call ktime_get frequently. The smp_rmb() will influence the
share cache, especially arm a15 share L2 cache. The performance drop will enlarge
when the loop time is millisecond level.

Signed-off-by: default avatarLi Hua <hucool.lihua@huawei.com>
Reviewed-by: default avatarChen Hui <judy.chenhui@huawei.com>
Signed-off-by: default avatarChen Jun <chenjun102@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent fd954cee
Loading
Loading
Loading
Loading
+23 −7
Original line number Diff line number Diff line
@@ -61,22 +61,38 @@ __setup("hlt", cpu_idle_nopoll_setup);
#endif

#ifdef CONFIG_IAS_SMART_IDLE
static void smart_idle_poll(void)
/* looping 2000 times is probably microsecond level for 2GHZ CPU*/
#define MICRO_LEVEL_COUNT 2000
static inline void delay_relax(unsigned long delay_max)
{
	unsigned long delay_count = 0;

	delay_max = (delay_max < MICRO_LEVEL_COUNT) ? delay_max : MICRO_LEVEL_COUNT;
	while (unlikely(!tif_need_resched()) && delay_count < delay_max) {
		barrier();
		__asm__ __volatile__("nop;");
		delay_count++;
	}
}

static inline void smart_idle_poll(void)
{
	unsigned long poll_duration = poll_threshold_ns;
	ktime_t cur, stop;

	if (!poll_duration)
	if (likely(!poll_duration))
		return;

	stop = ktime_add_ns(ktime_get(), poll_duration);

	do {
		cpu_relax();
		if (tif_need_resched())
	while (true) {
		delay_relax(poll_duration);
		if (likely(tif_need_resched()))
			break;
		cur = ktime_get();
	} while (ktime_before(cur, stop));
		if (likely(!ktime_before(cur, stop)))
			break;
		poll_duration = ktime_sub_ns(stop, cur);
	}
}
#endif