From 746cddd37d48a166f170165a0df4bd50fde1ea60 Mon Sep 17 00:00:00 2001 From: Weidong Han Date: Fri, 10 Apr 2009 17:17:17 +0800 Subject: x86, intr-remap: fix eoi for interrupt remapping without x2apic To simplify level irq migration in the presence of interrupt-remapping, Suresh used a virtual vector (io-apic pin number) to eliminate io-apic RTE modification. Level triggered interrupt will appear as an edge to the local apic cpu but still as level to the IO-APIC. So in addition to do the local apic EOI, it still needs to do IO-APIC directed EOI to clear the remote IRR bit in the IO-APIC RTE. Pls refer to Suresh's patch for more details (commit 0280f7c416c652a2fd95d166f52b199ae61122c0). Now interrupt remapping is decoupled from x2apic, it also needs to do the directed EOI for apic. Otherwise, apic interrupts won't work correctly. Signed-off-by: Weidong Han Cc: iommu@lists.linux-foundation.org Cc: Weidong Han Cc: suresh.b.siddha@intel.com Cc: dwmw2@infradead.org Cc: allen.m.kay@intel.com LKML-Reference: <1239355037-22856-1-git-send-email-weidong.han@intel.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/io_apic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 767fe7e..a2789e4 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2524,7 +2524,6 @@ static void irq_complete_move(struct irq_desc **descp) static inline void irq_complete_move(struct irq_desc **descp) {} #endif -#ifdef CONFIG_X86_X2APIC static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) { int apic, pin; @@ -2558,6 +2557,7 @@ eoi_ioapic_irq(struct irq_desc *desc) spin_unlock_irqrestore(&ioapic_lock, flags); } +#ifdef CONFIG_X86_X2APIC static void ack_x2apic_level(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); @@ -2634,6 +2634,9 @@ static void ack_apic_level(unsigned int irq) */ ack_APIC_irq(); + if (irq_remapped(irq)) + eoi_ioapic_irq(desc); + /* Now we can move and renable the irq */ if (unlikely(do_unmask_irq)) { /* Only migrate the irq if the ack has been received. -- cgit v1.1 From 575922248c0df490843ddfbcf3bc65b54c4adb08 Mon Sep 17 00:00:00 2001 From: Rakib Mullick Date: Sat, 11 Apr 2009 09:04:59 +0600 Subject: x86: Fix section mismatches in mpparse Impact: fix section mismatch In arch/x86/kernel/mpparse.c, smp_reserve_bootmem() has been called and also refers to a function which is in .init section. Thus causes the first warning. And check_irq_src() also requires an __init, because it refers to an .init section. Signed-off-by: Rakib Mullick Cc: Andrew Morton LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/mpparse.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index dce99dc..70fd7e4 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -679,7 +679,7 @@ void __init get_smp_config(void) __get_smp_config(0); } -static void smp_reserve_bootmem(struct mpf_intel *mpf) +static void __init smp_reserve_bootmem(struct mpf_intel *mpf) { unsigned long size = get_mpc_size(mpf->physptr); #ifdef CONFIG_X86_32 @@ -838,7 +838,7 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; -static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) +static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) { int i; @@ -866,7 +866,8 @@ static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) } } #else /* CONFIG_X86_IO_APIC */ -static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} +static +inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} #endif /* CONFIG_X86_IO_APIC */ static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, -- cgit v1.1 From a30469e7921a6dd2067e9e836d7787cfa0105627 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 10 Apr 2009 15:21:24 -0700 Subject: x86: add linux kernel support for YMM state Impact: save/restore Intel-AVX state properly between tasks Intel Advanced Vector Extensions (AVX) introduce 256-bit vector processing capability. More about AVX at http://software.intel.com/sites/avx Add OS support for YMM state management using xsave/xrstor infrastructure to support AVX. Signed-off-by: Suresh Siddha LKML-Reference: <1239402084.27006.8057.camel@localhost.localdomain> Signed-off-by: Ingo Molnar --- arch/x86/kernel/xsave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 2b54fe0..0a5b04a 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -324,7 +324,7 @@ void __ref xsave_cntxt_init(void) } /* - * for now OS knows only about FP/SSE + * Support only the state known to OS. */ pcntxt_mask = pcntxt_mask & XCNTXT_MASK; xsave_init(); -- cgit v1.1 From 01599fca6758d2cd133e78f87426fc851c9ea725 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 13 Apr 2009 10:27:49 -0700 Subject: cpufreq: use smp_call_function_[single|many]() in acpi-cpufreq.c Atttempting to rid us of the problematic work_on_cpu(). Just use smp_call_fuction_single() here. This repairs a 10% sysbench(oltp)+mysql regression which Mike reported, due to commit 6b44003e5ca66a3fffeb5bc90f40ada2c4340896 Author: Andrew Morton Date: Thu Apr 9 09:50:37 2009 -0600 work_on_cpu(): rewrite it to create a kernel thread on demand It seems that the kernel calls these acpi-cpufreq functions at a quite high frequency. Valdis Kletnieks also reports that this causes 70-90 forks per second on his hardware. Cc: Valdis.Kletnieks@vt.edu Cc: Rusty Russell Cc: Venkatesh Pallipadi Cc: Len Brown Cc: Zhao Yakui Acked-by: Dave Jones Cc: Thomas Gleixner Tested-by: Mike Galbraith Cc: "Zhang, Yanmin" Signed-off-by: Andrew Morton Acked-by: Ingo Molnar [ Made it use smp_call_function_many() instead of looping over cpu's with smp_call_function_single() - Linus ] Signed-off-by: Linus Torvalds --- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 9d3af38..3e3cd3d 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -153,7 +153,8 @@ struct drv_cmd { u32 val; }; -static long do_drv_read(void *_cmd) +/* Called via smp_call_function_single(), on the target CPU */ +static void do_drv_read(void *_cmd) { struct drv_cmd *cmd = _cmd; u32 h; @@ -170,10 +171,10 @@ static long do_drv_read(void *_cmd) default: break; } - return 0; } -static long do_drv_write(void *_cmd) +/* Called via smp_call_function_many(), on the target CPUs */ +static void do_drv_write(void *_cmd) { struct drv_cmd *cmd = _cmd; u32 lo, hi; @@ -192,23 +193,18 @@ static long do_drv_write(void *_cmd) default: break; } - return 0; } static void drv_read(struct drv_cmd *cmd) { cmd->val = 0; - work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); + smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1); } static void drv_write(struct drv_cmd *cmd) { - unsigned int i; - - for_each_cpu(i, cmd->mask) { - work_on_cpu(i, do_drv_write, cmd); - } + smp_call_function_many(cmd->mask, do_drv_write, cmd, 1); } static u32 get_cur_val(const struct cpumask *mask) @@ -252,15 +248,13 @@ struct perf_pair { } aperf, mperf; }; - -static long read_measured_perf_ctrs(void *_cur) +/* Called via smp_call_function_single(), on the target CPU */ +static void read_measured_perf_ctrs(void *_cur) { struct perf_pair *cur = _cur; rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi); rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi); - - return 0; } /* @@ -283,7 +277,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy, unsigned int perf_percent; unsigned int retval; - if (!work_on_cpu(cpu, read_measured_perf_ctrs, &readin)) + if (smp_call_function_single(cpu, read_measured_perf_ctrs, &cur, 1)) return 0; cur.aperf.whole = readin.aperf.whole - -- cgit v1.1