mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC][PATCH 3/3]i386,x86-64 Handle missing local APIC timer interrupts on C3 state
@ 2005-12-09  2:12 Venkatesh Pallipadi
  0 siblings, 0 replies; only message in thread
From: Venkatesh Pallipadi @ 2005-12-09  2:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Linus Torvalds, Andrew Morton, Andi Kleen, Rohit Seth, Len Brown



Whenever we see that a CPU is capable of C3 (during ACPI cstate init), we 
disable local APIC timer and switch to using a broadcast from external timer
interrupt (IRQ 0).

Patch below adds the code for x86_64.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>

Index: linux-2.6.14/arch/x86_64/kernel/apic.c
===================================================================
--- linux-2.6.14.orig/arch/x86_64/kernel/apic.c	2005-12-05 15:15:28.300789192 -0800
+++ linux-2.6.14/arch/x86_64/kernel/apic.c	2005-12-08 09:42:51.929229344 -0800
@@ -25,6 +25,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
+#include <linux/module.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -38,6 +39,12 @@
 
 int disable_apic_timer __initdata;
 
+/*
+ * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
+ * IPIs in place of local APIC timers
+ */
+static cpumask_t timer_interrupt_broadcast_ipi_mask;
+
 /* Using APIC to generate smp_local_timer_interrupt? */
 int using_apic_timer = 0;
 
@@ -781,7 +788,7 @@
 	local_irq_enable();
 }
 
-void __cpuinit disable_APIC_timer(void)
+void disable_APIC_timer(void)
 {
 	if (using_apic_timer) {
 		unsigned long v;
@@ -801,6 +808,40 @@
 	}
 }
 
+void switch_APIC_timer_to_ipi(void *cpumask)
+{
+	cpumask_t mask = *(cpumask_t *)cpumask;
+	int cpu = smp_processor_id();
+
+	if (cpu_isset(cpu, mask) && 
+	    !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
+		disable_APIC_timer();
+		cpu_set(cpu, timer_interrupt_broadcast_ipi_mask);
+	}
+}
+EXPORT_SYMBOL(switch_APIC_timer_to_ipi);
+
+void smp_send_timer_broadcast_ipi(void)
+{
+	if (!cpus_empty(timer_interrupt_broadcast_ipi_mask)) {
+		send_IPI_mask(timer_interrupt_broadcast_ipi_mask,
+		              LOCAL_TIMER_VECTOR);
+	}
+}
+
+void switch_ipi_to_APIC_timer(void *cpumask)
+{
+	cpumask_t mask = *(cpumask_t *)cpumask;
+	int cpu = smp_processor_id();
+
+	if (cpu_isset(cpu, mask) &&
+	    cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
+		cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask);
+		enable_APIC_timer();
+	}
+}
+EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
+
 int setup_profiling_timer(unsigned int multiplier)
 {
 	return -EINVAL;
Index: linux-2.6.14/include/asm-x86_64/apic.h
===================================================================
--- linux-2.6.14.orig/include/asm-x86_64/apic.h	2005-12-05 16:24:35.718285896 -0800
+++ linux-2.6.14/include/asm-x86_64/apic.h	2005-12-05 16:27:36.115861296 -0800
@@ -113,6 +113,12 @@
 
 extern void setup_threshold_lvt(unsigned long lvt_off);
 
+void smp_send_timer_broadcast_ipi(void);
+void switch_APIC_timer_to_ipi(void *cpumask);
+void switch_ipi_to_APIC_timer(void *cpumask);
+
+#define ARCH_APICTIMER_STOPS_ON_C3	1
+
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 extern unsigned boot_cpu_id;
Index: linux-2.6.14/arch/x86_64/kernel/time.c
===================================================================
--- linux-2.6.14.orig/arch/x86_64/kernel/time.c	2005-12-01 18:04:25.878829032 -0800
+++ linux-2.6.14/arch/x86_64/kernel/time.c	2005-12-05 16:26:37.470776704 -0800
@@ -476,6 +476,11 @@
  
 	write_sequnlock(&xtime_lock);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (using_apic_timer)
+		smp_send_timer_broadcast_ipi();
+#endif
+
 	return IRQ_HANDLED;
 }
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-12-09  2:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-09  2:12 [RFC][PATCH 3/3]i386,x86-64 Handle missing local APIC timer interrupts on C3 state Venkatesh Pallipadi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®