Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3491934 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "idle: Implement a per-cpu idle-polling mode"

parents 2492f778 fd40937a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -288,6 +288,7 @@ void cpu_startup_entry(enum cpuhp_state state);
void cpu_idle(void);

void cpu_idle_poll_ctrl(bool enable);
void per_cpu_idle_poll_ctrl(int cpu, bool enable);

void arch_cpu_idle(void);
void arch_cpu_idle_prepare(void);
+25 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/tick.h>
#include <linux/mm.h>
#include <linux/stackprotector.h>
#include <linux/percpu.h>

#include <asm/tlb.h>

@@ -26,6 +27,24 @@ void cpu_idle_poll_ctrl(bool enable)
	mb();
}

static DEFINE_PER_CPU(int, idle_force_poll);

void per_cpu_idle_poll_ctrl(int cpu, bool enable)
{
	if (enable) {
		per_cpu(idle_force_poll, cpu)++;
	} else {
		per_cpu(idle_force_poll, cpu)--;
		WARN_ON_ONCE(per_cpu(idle_force_poll, cpu) < 0);
	}

	/*
	 * Make sure poll mode is entered on the relevant CPU after the flag is
	 * set
	 */
	mb();
}

#ifdef CONFIG_GENERIC_IDLE_POLL_SETUP
static int __init cpu_idle_poll_setup(char *__unused)
{
@@ -47,7 +66,8 @@ static inline int cpu_idle_poll(void)
	rcu_idle_enter();
	trace_cpu_idle_rcuidle(0, smp_processor_id());
	local_irq_enable();
	while (!tif_need_resched() && cpu_idle_force_poll)
	while (!tif_need_resched() && (cpu_idle_force_poll ||
		__get_cpu_var(idle_force_poll)))
		cpu_relax();
	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
	rcu_idle_exit();
@@ -89,7 +109,9 @@ static void cpu_idle_loop(void)
			 * know that the IPI is going to arrive right
			 * away
			 */
			if (cpu_idle_force_poll || tick_check_broadcast_expired()) {
			if (cpu_idle_force_poll ||
			    tick_check_broadcast_expired() ||
			    __get_cpu_var(idle_force_poll)) {
				cpu_idle_poll();
			} else {
				if (!current_clr_polling_and_test()) {
@@ -133,5 +155,6 @@ void cpu_startup_entry(enum cpuhp_state state)
#endif
	__current_set_polling();
	arch_cpu_idle_prepare();
	per_cpu(idle_force_poll, smp_processor_id()) = 0;
	cpu_idle_loop();
}