Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 17966
b: refs/heads/master
c: d25bf7e
h: refs/heads/master
v: v3
  • Loading branch information
Venkatesh Pallipadi authored and Linus Torvalds committed Jan 12, 2006
1 parent 2151ada commit 55ad644
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6eb0a0fd059598ee0d49c6283ce25cccd743e9fc
refs/heads/master: d25bf7e5fe73b5b6d2246ab0be08ae35d718456b
55 changes: 53 additions & 2 deletions trunk/arch/x86_64/kernel/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -38,6 +39,12 @@ int apic_verbosity;

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;

Expand Down Expand Up @@ -656,9 +663,14 @@ void __init init_apic_mappings(void)
static void __setup_APIC_LVTT(unsigned int clocks)
{
unsigned int lvtt_value, tmp_value, ver;
int cpu = smp_processor_id();

ver = GET_APIC_VERSION(apic_read(APIC_LVR));
lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;

if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask))
lvtt_value |= APIC_LVT_MASKED;

apic_write_around(APIC_LVTT, lvtt_value);

/*
Expand Down Expand Up @@ -781,7 +793,7 @@ void __cpuinit setup_secondary_APIC_clock(void)
local_irq_enable();
}

void __cpuinit disable_APIC_timer(void)
void disable_APIC_timer(void)
{
if (using_apic_timer) {
unsigned long v;
Expand All @@ -793,14 +805,53 @@ void __cpuinit disable_APIC_timer(void)

void enable_APIC_timer(void)
{
if (using_apic_timer) {
int cpu = smp_processor_id();

if (using_apic_timer &&
!cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
unsigned long v;

v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
}
}

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)
{
cpumask_t mask;

cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask);
if (!cpus_empty(mask)) {
send_IPI_mask(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;
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/x86_64/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)

write_sequnlock(&xtime_lock);

#ifdef CONFIG_X86_LOCAL_APIC
if (using_apic_timer)
smp_send_timer_broadcast_ipi();
#endif

return IRQ_HANDLED;
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/include/asm-x86_64/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ extern int disable_timer_pin_1;

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;
Expand Down

0 comments on commit 55ad644

Please sign in to comment.