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

Commit 495ab9c0 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds
Browse files

[PATCH] i386/x86-64/ia64: Move polling flag into thread_info_status



During some profiling I noticed that default_idle causes a lot of
memory traffic. I think that is caused by the atomic operations
to clear/set the polling flag in thread_info. There is actually
no reason to make this atomic - only the idle thread does it
to itself, other CPUs only read it. So I moved it into ti->status.

Converted i386/x86-64/ia64 for now because that was the easiest
way to fix ACPI which also manipulates these flags in its idle
function.

Cc: Nick Piggin <npiggin@novell.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d9005b52
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -764,9 +764,9 @@ static int apm_do_idle(void)
	int	idled = 0;
	int	polling;

	polling = test_thread_flag(TIF_POLLING_NRFLAG);
	polling = !!(current_thread_info()->status & TS_POLLING);
	if (polling) {
		clear_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status &= ~TS_POLLING;
		smp_mb__after_clear_bit();
	}
	if (!need_resched()) {
@@ -774,7 +774,7 @@ static int apm_do_idle(void)
		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
	}
	if (polling)
		set_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status |= TS_POLLING;

	if (!idled)
		return 0;
+3 −3
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ void default_idle(void)
	local_irq_enable();

	if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
		clear_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status &= ~TS_POLLING;
		smp_mb__after_clear_bit();
		while (!need_resched()) {
			local_irq_disable();
@@ -111,7 +111,7 @@ void default_idle(void)
			else
				local_irq_enable();
		}
		set_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status |= TS_POLLING;
	} else {
		while (!need_resched())
			cpu_relax();
@@ -174,7 +174,7 @@ void cpu_idle(void)
{
	int cpu = smp_processor_id();

	set_thread_flag(TIF_POLLING_NRFLAG);
	current_thread_info()->status |= TS_POLLING;

	/* endless idle loop with no priority at all */
	while (1) {
+2 −2
Original line number Diff line number Diff line
@@ -272,9 +272,9 @@ cpu_idle (void)
	/* endless idle loop with no priority at all */
	while (1) {
		if (can_do_pal_halt)
			clear_thread_flag(TIF_POLLING_NRFLAG);
			current_thread_info()->status &= ~TS_POLLING;
		else
			set_thread_flag(TIF_POLLING_NRFLAG);
			current_thread_info()->status |= TS_POLLING;

		if (!need_resched()) {
			void (*idle)(void);
+3 −4
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ static void default_idle(void)
{
	local_irq_enable();

	clear_thread_flag(TIF_POLLING_NRFLAG);
	current_thread_info()->status &= ~TS_POLLING;
	smp_mb__after_clear_bit();
	while (!need_resched()) {
		local_irq_disable();
@@ -119,7 +119,7 @@ static void default_idle(void)
		else
			local_irq_enable();
	}
	set_thread_flag(TIF_POLLING_NRFLAG);
	current_thread_info()->status |= TS_POLLING;
}

/*
@@ -202,8 +202,7 @@ static inline void play_dead(void)
 */
void cpu_idle (void)
{
	set_thread_flag(TIF_POLLING_NRFLAG);

	current_thread_info()->status |= TS_POLLING;
	/* endless idle loop with no priority at all */
	while (1) {
		while (!need_resched()) {
+6 −6
Original line number Diff line number Diff line
@@ -206,11 +206,11 @@ acpi_processor_power_activate(struct acpi_processor *pr,

static void acpi_safe_halt(void)
{
	clear_thread_flag(TIF_POLLING_NRFLAG);
	current_thread_info()->status &= ~TS_POLLING;
	smp_mb__after_clear_bit();
	if (!need_resched())
		safe_halt();
	set_thread_flag(TIF_POLLING_NRFLAG);
	current_thread_info()->status |= TS_POLLING;
}

static atomic_t c3_cpu_count;
@@ -330,10 +330,10 @@ static void acpi_processor_idle(void)
	 * Invoke the current Cx state to put the processor to sleep.
	 */
	if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
		clear_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status &= ~TS_POLLING;
		smp_mb__after_clear_bit();
		if (need_resched()) {
			set_thread_flag(TIF_POLLING_NRFLAG);
			current_thread_info()->status |= TS_POLLING;
			local_irq_enable();
			return;
		}
@@ -371,7 +371,7 @@ static void acpi_processor_idle(void)
		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
		/* Re-enable interrupts */
		local_irq_enable();
		set_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status |= TS_POLLING;
		/* Compute time (ticks) that we were actually asleep */
		sleep_ticks =
		    ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
@@ -411,7 +411,7 @@ static void acpi_processor_idle(void)

		/* Re-enable interrupts */
		local_irq_enable();
		set_thread_flag(TIF_POLLING_NRFLAG);
		current_thread_info()->status |= TS_POLLING;
		/* Compute time (ticks) that we were actually asleep */
		sleep_ticks =
		    ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
Loading