Second batch of x86 patches for .23
Subsystems (16)
cover Second batch of x86 patches for .23
[repost to linux-kernel because I messed up the email address first time]
- Controversal change: extend the unhandled signals logging to i386
* all flames to Masoud Asgharifard Sharbiani <[email protected]> please
- NUMA fallback handling for AMD Fam10h/11h (Joachim Deguara)
- Second try at registering HPET in resources
- Various AMD Geode fixes
- Better OOM handling -- kill all threads
- Better HPET sanity checking
- Fix PCI mmconfig on some systems
- kprobes/alternative handling now works with DEBUG_RODATA again
- Allow KVM on non PAE kernels again
- Mostly various small leanups and fixes
Please review. I plan to send them off relatively quickly because I'm very late with this merge.
-Andi
PATCH 1/48 i386: pgd_{c,d}tor() static
From: Adrian Bunk <[email protected]>
pgd_{c,d}tor() can now become static.
---
arch/i386/mm/pgtable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/i386/mm/pgtable.c +3 -3
@@ -235,7 +235,7 @@ static inline void pgd_list_del(pgd_t *p#if (PTRS_PER_PMD ==1 )/* Non-PAE pgd constructor */ -void pgd_ctor (void *pgd) +static void pgd_ctor (void *pgd) {unsigned long flags;
@@ -257,7 +257,7 @@ void pgd_ctor(void *pgd) }#else /* PTRS_PER_PMD > 1 */ /* PAE pgd constructor */ -void pgd_ctor (void *pgd) +static void pgd_ctor (void *pgd) {/* PAE, kernel PMD may be shared */
@@ -276,7 +276,7 @@ void pgd_ctor(void *pgd) }#endif /* PTRS_PER_PMD */ -void pgd_dtor (void *pgd) +static void pgd_dtor (void *pgd) {unsigned long flags;/* can be called from interrupt context */
PATCH 2/48 i386: fix section mismatch warning in intel_cacheinfo
In reply to Andi KleenFrom: Sam Ravnborg <[email protected]>
Fix following warning:
WARNING: arch/i386/kernel/built-in.o(.init.text+0x3818): Section mismatch: reference to .exit.text:cache_remove_dev (between 'cacheinfo_cpu_callback' and 'cache_sysfs_init')
It points out that a function marked __cpuexit is calling a function marked __cpuinit => oops.
The call happens only in an error-condition which may explain why we have not seen it before.
The offending function was not used anywhere else - so marked it __cpuexit.
Note: This warning triggers only with a local copy of modpost
but that version will soon be pushed out.
---
arch/i386/kernel/cpu/intel_cacheinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/i386/kernel/cpu/intel_cacheinfo.c +1 -1
@@ -746,7 +746,7 @@ static int __cpuinit cache_add_dev(strucreturn retval; } -static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) +static void __cpuinit cache_remove_dev (struct sys_device * sys_dev) {unsigned int cpu = sys_dev->id;unsigned long i;
PATCH 3/48 i386: do not restore reserved memory after hibernation
In reply to Andi KleenFrom: Rafael J. Wysocki <[email protected]>
On some systems the ACPI NVS area is located in the first 1 MB of RAM and it is overwritten by the i386 code during the restore after hibernation. This confuses the ACPI platform firmware that doesn't update the AC adapter status appropriately as a result
(http://bugzilla.kernel.org/show_bug.cgi?id=7995).
The solution is to register the reserved memory in the first 1 MB as 'nosave', so that swsusp doesn't touch it during the restore. Also, this has been done on x86_64 for a long time now, so this patch makes the i386 restore code behave like the x86_64 one.
---
arch/i386/kernel/e820.c | 32 ++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 1 + include/asm-i386/e820.h | 8 ++++++++ 3 files changed, 41 insertions(+)
arch/i386/kernel/e820.c +32 -0
@@ -10,6 +10,7 @@#include <linux/efi.h> #include <linux/pfn.h> #include <linux/uaccess.h> +#include <linux/suspend.h> #include <asm/pgtable.h> #include <asm/page.h>
@@ -320,6 +321,37 @@ static int __init request_standard_resousubsys_initcall (request_standard_resources); +#if defined(CONFIG_PM ) && defined(CONFIG_SOFTWARE_SUSPEND ) +/** +* e820_mark_nosave_regions - Find the ranges of physical addresses that do not +* correspond to e820 RAM areas and mark the corresponding pages as nosave for +* hibernation. +* +* This function requires the e820 map to be sorted and without any +* overlapping entries and assumes the first e820 area to be RAM. +*/ +void __init e820_mark_nosave_regions (void ) +{ +int i; +unsigned long pfn; + + pfn =PFN_DOWN (e820.map[0 ].addr + e820.map[0 ].size); +for (i =1 ; i < e820.nr_map; i++) { +struct e820entry *ei = &e820.map[i]; + +if (pfn <PFN_UP (ei->addr)) +register_nosave_region (pfn,PFN_UP (ei->addr)); + + pfn =PFN_DOWN (ei->addr + ei->size); +if (ei->type !=E820_RAM ) +register_nosave_region (PFN_UP (ei->addr), pfn); + +if (pfn >= max_low_pfn) +break ; + } +} +#endif +void __init add_memory_region (unsigned long long start,unsigned long long size,int type) {
arch/i386/kernel/setup.c +1 -0
@@ -640,6 +640,7 @@ void __init setup_arch(char **cmdline_p)#endif e820_register_memory (); +e820_mark_nosave_regions ();#ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE )
include/asm-i386/e820.h +8 -0
@@ -47,6 +47,14 @@ extern void e820_register_memory(void);extern void limit_regions (unsigned long long size);extern void print_memory_map (char *who); +#if defined(CONFIG_PM ) && defined(CONFIG_SOFTWARE_SUSPEND ) +extern void e820_mark_nosave_regions (void ); +#else +static inline void e820_mark_nosave_regions (void ) +{ +} +#endif +#endif /*!__ASSEMBLY__*/ #endif /*__E820_HEADER*/
PATCH 4/48 i386: DMI_MATCH patch in reboot.c for SFF Dell OptiPlex 745 - fixes hang on reboot
In reply to Andi KleenFrom: James Jarvis <[email protected]>
The following patch enables reboot through BIOS on the Dell Optiplex 745 Small Form Factor base, on which reboot hangs. The larger form factor does not require this, hence the match on DMI_BOARD_NAME.
---
arch/i386/kernel/reboot.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/i386/kernel/reboot.c +9 -0
@@ -113,6 +113,15 @@ static struct dmi_system_id __initdata r DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), }, }, + { /* Handle problems with rebooting on Dell Optiplex 745's SFF*/ + .callback = set_bios_reboot, + .ident = "Dell OptiPlex 745", + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"OptiPlex 745" ), + DMI_MATCH(DMI_BOARD_NAME, "0WF810"), + }, + }, { /* Handle problems with rebooting on Dell 2400's */ .callback = set_bios_reboot, .ident = "Dell PowerEdge 2400",
PATCH 5/48 i386: HPET, check if the counter works
In reply to Andi KleenFrom: Thomas Gleixner <[email protected]>
Some systems have a HPET which is not incrementing, which leads to a complete hang. Detect it during HPET setup.
---
arch/i386/kernel/hpet.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
arch/i386/kernel/hpet.c +23 -1
@@ -226,7 +226,8 @@ int __init hpet_enable(void) {unsigned long id;uint64_t hpet_freq; -u64 tmp; +u64 tmp, start, now; +cycle_t t1;if (!is_hpet_capable ())return 0 ;
@@ -273,6 +274,27 @@ int __init hpet_enable(void)/* Start the counter */ hpet_start_counter (); +/* Verify whether hpet counter works */ + t1 =read_hpet (); +rdtscll (start); + +/* +* We don't know the TSC frequency yet, but waiting for +* 200000 TSC cycles is safe: +* 4 GHz == 50us +* 1 GHz == 200us +*/ +do { +rep_nop (); +rdtscll (now); + }while ((now - start) <200000UL ); + +if (t1 ==read_hpet ()) { +printk (KERN_WARNING +"HPET counter not counting. HPET disabled\n" ); + goto out_nohpet; + } +/* Initialize and register HPET clocksource * * hpet period is in femto seconds per cycle
PATCH 6/48 x86: trim memory not covered by WB MTRRs
In reply to Andi KleenFrom: Jesse Barnes <[email protected]>
On some machines, buggy BIOSes don't properly setup WB MTRRs to cover all available RAM, meaning the last few megs (or even gigs) of memory will be marked uncached. Since Linux tends to allocate from high memory addresses first, this causes the machine to be unusably slow as soon as the kernel starts really using memory (i.e. right around init time).
This patch works around the problem by scanning the MTRRs at boot and figuring out whether the current end_pfn value (setup by early e820 code) goes beyond the highest WB MTRR range, and if so, trimming it to match. A fairly obnoxious KERN_WARNING is printed too, letting the user know that not all of their memory is available due to a likely BIOS bug.
Something similar could be done on i386 if needed, but the boot ordering would be slightly different, since the MTRR code on i386 depends on the boot_cpu_data structure being setup.
This patch fixes a bug in the last patch that caused the code to run on non-Intel machines (AMD machines apparently don't need it and it's untested on other non-Intel machines, so best keep it off).
---
Documentation/kernel-parameters.txt | 6 ++ arch/i386/kernel/cpu/mtrr/generic.c | 8 --- arch/i386/kernel/cpu/mtrr/if.c | 8 --- arch/i386/kernel/cpu/mtrr/main.c | 85 +++++++++++++++++++++++++++--------- arch/i386/kernel/cpu/mtrr/mtrr.h | 3 + arch/x86_64/kernel/bugs.c | 1 arch/x86_64/kernel/setup.c | 4 + include/asm-x86_64/mtrr.h | 5 +- 8 files changed, 84 insertions(+), 36 deletions(-)
Documentation/kernel-parameters.txt +6 -0
@@ -537,6 +537,12 @@ and is between 256 and 4096 characters. See drivers/char/README.epca and Documentation/digiepca.txt. + disable_mtrr_trim [X86-64, Intel only] + By default the kernel will trim any uncacheable + memory out of your available memory pool based on + MTRR settings. This parameter disables that behavior, + possibly causing your machine to run very slowly. + dmascc= [HW,AX25,SERIAL] AX.25 Z80SCC driver with DMA support available. Format: <io_dev0>[,<io_dev1>[,..<io_dev32>]]
arch/i386/kernel/cpu/mtrr/generic.c +1 -7
@@ -13,7 +13,7 @@#include "mtrr.h" struct mtrr_state { -struct mtrr_var_range *var_ranges; +struct mtrr_var_range var_ranges[MAX_VAR_RANGES ];mtrr_type fixed_ranges[NUM_FIXED_RANGES ];unsigned char enabled;unsigned char have_fixed;
@@ -85,12 +85,6 @@ void __init get_mtrr_state(void)struct mtrr_var_range *vrs;unsigned lo, dummy; -if (!mtrr_state.var_ranges) { - mtrr_state.var_ranges =kmalloc (num_var_ranges *sizeof (struct mtrr_var_range ), -GFP_KERNEL ); -if (!mtrr_state.var_ranges) -return ; - } vrs = mtrr_state.var_ranges;rdmsr (MTRRcap_MSR, lo, dummy);
arch/i386/kernel/cpu/mtrr/if.c +2 -6
@@ -11,10 +11,6 @@#include <asm/mtrr.h> #include "mtrr.h" -/* RED-PEN: this is accessed without any locking */ -extern unsigned int *usage_table; - -#define FILE_FCOUNT (f) (((struct seq_file *)((f)->private_data))->private) static const char *const mtrr_strings[MTRR_NUM_TYPES] =
@@ -396,7 +392,7 @@ static int mtrr_seq_show(struct seq_filefor (i =0 ; i < max; i++) { mtrr_if->get (i, &base, &size, &type);if (size ==0 ) - usage_table[i] =0 ; + mtrr_usage_table[i] =0 ;else {if (size < (0x100000 >>PAGE_SHIFT )) {/* less than 1MB */
@@ -410,7 +406,7 @@ static int mtrr_seq_show(struct seq_file len +=seq_printf (seq,"reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n" , i, base, base >> (20 -PAGE_SHIFT ), size, factor, -mtrr_attrib_to_str (type), usage_table[i]); +mtrr_attrib_to_str (type), mtrr_usage_table[i]); } }return 0 ;
arch/i386/kernel/cpu/mtrr/main.c +64 -21
151 lines not on this page · raw message
arch/i386/kernel/cpu/mtrr/mtrr.h +3 -0
@@ -14,6 +14,7 @@#define MTRRphysMask_MSR (reg) (0x200 + 2 * (reg) + 1)#define NUM_FIXED_RANGES 88 +#define MAX_VAR_RANGES 256#define MTRRfix64K_00000_MSR 0x250#define MTRRfix16K_80000_MSR 0x258#define MTRRfix16K_A0000_MSR 0x259
@@ -34,6 +35,8 @@an 8 bit field: */ typedef u8 mtrr_type ; +extern unsigned int mtrr_usage_table[MAX_VAR_RANGES ]; +struct mtrr_ops {u32 vendor;u32 use_intel_if;
arch/x86_64/kernel/bugs.c +0 -1
@@ -14,7 +14,6 @@void __init check_bugs (void ) {identify_cpu (&boot_cpu_data); -mtrr_bp_init ();#if !defined(CONFIG_SMP )printk ("CPU: " );print_cpu_info (&boot_cpu_data);
arch/x86_64/kernel/setup.c +4 -0
@@ -266,6 +266,10 @@ void __init setup_arch(char **cmdline_p)* we are rounding upwards: */ end_pfn =e820_end_of_ram (); +/* Trim memory not covered by WB MTRRs */ +mtrr_bp_init (); +mtrr_trim_uncached_memory (); + num_physpages = end_pfn;check_efer ();
include/asm-x86_64/mtrr.h +4 -1
@@ -78,6 +78,7 @@ extern int mtrr_add_page (unsigned long unsigned int type, char increment);extern int mtrr_del (int reg,unsigned long base,unsigned long size);extern int mtrr_del_page (int reg,unsigned long base,unsigned long size); +extern void mtrr_trim_uncached_memory (void );# else static __inline__int mtrr_add (unsigned long base,unsigned long size,unsigned int type,char increment)
@@ -99,7 +100,9 @@ static __inline__ int mtrr_del_page (int {return -ENODEV ; } - +static __inline__void mtrr_trim_uncached_memory (void ) +{ +}#endif /* CONFIG_MTRR */ #ifdef CONFIG_COMPAT
PATCH 7/48 i386: divorce CONFIG_X86_PAE from CONFIG_HIGHMEM64G
In reply to Andi KleenFrom: William Lee Irwin III <[email protected]>
PAE is useful for more than supporting more than 4GB RAM. It supports expanded swapspace and NX executable protections. Some users may want NX or expanded swapspace support without the overhead or instability of highmem. For these reasons, the following patch divorces CONFIG_X86_PAE from CONFIG_HIGHMEM64G.
---
arch/i386/Kconfig | 16 +++++++++++----- arch/i386/kernel/setup.c | 8 ++++---- 2 files changed, 15 insertions(+), 9 deletions(-)
arch/i386/Kconfig +11 -5
@@ -544,6 +544,7 @@ config HIGHMEM4G config HIGHMEM64G bool "64GB" depends on !M386 && !M486 + select X86_PAE help Select this if you have a 32-bit processor and more than 4 gigabytes of physical RAM.
@@ -573,12 +574,12 @@ choice config VMSPLIT_3G bool "3G/1G user/kernel split" config VMSPLIT_3G_OPT - depends on !HIGHMEM + depends on !X86_PAE bool "3G/1G user/kernel split (for full 1G low memory)" config VMSPLIT_2G bool "2G/2G user/kernel split" config VMSPLIT_2G_OPT - depends on !HIGHMEM + depends on !X86_PAE bool "2G/2G user/kernel split (for full 2G low memory)" config VMSPLIT_1G bool "1G/3G user/kernel split"
@@ -598,10 +599,15 @@ config HIGHMEM default y config X86_PAE - bool - depends on HIGHMEM64G - default y + bool "PAE (Physical Address Extension) Support" + default n + depends on !HIGHMEM4G select RESOURCES_64BIT + help + PAE is required for NX support, and furthermore enables + larger swapspace support for non-overcommit purposes. It + has the cost of more pagetable lookup overhead, and also + consumes more pagetable space per process. # Common NUMA Features config NUMA
arch/i386/kernel/setup.c +4 -4
@@ -273,18 +273,18 @@ unsigned long __init find_max_low_pfn(voprintk (KERN_WARNING "Warning only %ldMB will be used.\n" ,MAXMEM >>20 );if (max_pfn >MAX_NONPAE_PFN ) -printk (KERN_WARNING "Use a PAE enabled kernel.\n" ); +printk (KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n" );else printk (KERN_WARNING "Use a HIGHMEM enabled kernel.\n" ); max_pfn =MAXMEM_PFN ;#else /* !CONFIG_HIGHMEM */ -#ifndef CONFIG_X86_PAE +#ifndef CONFIG_HIGHMEM64G if (max_pfn >MAX_NONPAE_PFN ) { max_pfn =MAX_NONPAE_PFN ;printk (KERN_WARNING "Warning only 4GB will be used.\n" ); -printk (KERN_WARNING "Use a PAE enabled kernel.\n" ); +printk (KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n" ); } -#endif /* !CONFIG_X86_PAE */ +#endif /* !CONFIG_HIGHMEM64G */ #endif /* !CONFIG_HIGHMEM */ }else {if (highmem_pages ==-1 )
Re: [PATCH for review] [7/48] i386: divorce CONFIG_X86_PAE from CONFIG_HIGHMEM64G
Quoted 3 lines · Andi Kleen
Some users may want NX
or expanded swapspace support without the overhead or instability of highmem.
NX is still going to need the larger PTEs, so I don't see how this change removes any 'overhead' or potential 'instability'. I'm not necessarily disagreeing with the change, but this part of the changelog seems to be false advertising.
Dave
Signature · 1 line
http://www.codemonkey.org.uk
Re: [PATCH for review] [7/48] i386: divorce CONFIG_X86_PAE from CONFIG_HIGHMEM64G
Quoted 1 line · On Thursday 19 July 2007 16:46:31 Dave Jones wrote:
On Thu, Jul 19, 2007 at 03:48:36PM +0200, Andi Kleen wrote:
I didn't. If you guys really want to have a thread to criticize the changelog (which seems quite bogus, after all we're interested in code here, not changelogs) then please at least get your attributions right.
Regarding highmem instability: there are still known ways to drive systems with larger highmem ratios to early OOM or deadlock, although they are relatively obscure.
-Andi
Quoted 12 lines
Quoted 4 lines
Some users may want NX
or expanded swapspace support without the overhead or instability of highmem.NX is still going to need the larger PTEs, so I don't see how this change removes any 'overhead' or potential 'instability'. I'm not necessarily disagreeing with the change, but this part of the changelog seems to be false advertising.
Dave
Re: [PATCH for review] [7/48] i386: divorce CONFIG_X86_PAE from CONFIG_HIGHMEM64G
In reply to Andi KleenQuoted 8 lines · Andi Kleen
From: William Lee Irwin III <[email protected]>
PAE is useful for more than supporting more than 4GB RAM. It supports expanded swapspace and NX executable protections. Some users may want NX or expanded swapspace support without the overhead or instability of highmem. For these reasons, the following patch divorces
CONFIG_X86_PAEfromCONFIG_HIGHMEM64G.
What overhead of instability of highmem? Sorry folks but this is utter bollocks. Back in the Caldera days we did a lot of measurement on highmem overhead, and CONFIG_HIGHMEM has no measurable overhead at all on a system that doesn't use it. CONFIG_HIGHMEM64G on the other hand has a quite visible overhead on small systems, but that's entirely due to the bigger page table entries that you need for NX.
Re: [PATCH for review] [7/48] i386: divorce CONFIG_X86_PAE from CONFIG_HIGHMEM64G
From: William Lee Irwin III <[email protected]>
Quoted 5 lines
Quoted 5 lines
PAE is useful for more than supporting more than 4GB RAM. It supports expanded swapspace and NX executable protections. Some users may want NX or expanded swapspace support without the overhead or instability of highmem. For these reasons, the following patch divorces
CONFIG_X86_PAEfromCONFIG_HIGHMEM64G.
Quoted 6 lines · Christoph Hellwig
What overhead of instability of highmem? Sorry folks but this is utter bollocks. Back in the Caldera days we did a lot of measurement on highmem overhead, and
CONFIG_HIGHMEMhas no measurable overhead at all on a system that doesn't use it.CONFIG_HIGHMEM64Gon the other hand has a quite visible overhead on small systems, but that's entirely due to the bigger page table entries that you need for NX.
The missing context here is CONFIG_VMSPLIT on laptops.
Laptop users, who frequently use CONFIG_VMSPLIT options to avoid highmem, wanted to turn on NX. Prior to the patch, those options were barred for all highmem configurations. In response to those requests, I produced the patch.
The overhead and instability derived from tiny zones as opposed to kmap()/kunmap(), or at least such was the case historically.
-- wli
PATCH 8/48 i386: Remove unneeded test of 'task' in dump_trace()
In reply to Andi KleenFrom: Jesper Juhl <[email protected]>
Remove unneeded test of task != NULL from
arch/i386/kernel/traps.c::dump_trace()
At the start of the function we have this test:
if (!task)
task = current;so further down there's no need to test 'task'.
---
arch/i386/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/i386/kernel/traps.c +1 -1
@@ -148,7 +148,7 @@ void dump_trace(struct task_struct *taskif (!stack) {unsigned long dummy; stack = &dummy; -if (task && task != current) +if (task != current) stack = (unsigned long *)task->thread.esp; }
PATCH 9/48 i386: move the kernel to 16MB for NUMA-Q
In reply to Andi KleenFrom: Andy Whitcroft <[email protected]>
We are seeing corruption of the decompressed kernel. It is suspected that this is platform specific as it has yet to be seen on any other x86. Move the kernel to the 16MB boundary.
---
arch/i386/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/i386/Kconfig +1 -0
@@ -823,6 +823,7 @@ config CRASH_DUMP config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) + default "0x1000000" if X86_NUMAQ default "0x100000" help This gives the physical address where the kernel is loaded.
PATCH 10/48 x86_64: Move functions declarations to header file
In reply to Andi KleenFrom: Glauber de Oliveira Costa <[email protected]>
Some interrupt entry points are currently defined in i8259.c They probably belong in a header. Right now, their only user is init_IRQ, justifying their declaration in-file. But when virtualization comes in, we may be interested in using that functions in late initializations.
---
arch/x86_64/kernel/i8259.c | 18 ------------------ include/asm-x86_64/hw_irq.h | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 18 deletions(-)
arch/x86_64/kernel/i8259.c +0 -18
@@ -444,24 +444,6 @@ void __init init_ISA_irqs (void) } } -void apic_timer_interrupt (void ); -void spurious_interrupt (void ); -void error_interrupt (void ); -void reschedule_interrupt (void ); -void call_function_interrupt (void ); -void irq_move_cleanup_interrupt (void ); -void invalidate_interrupt0 (void ); -void invalidate_interrupt1 (void ); -void invalidate_interrupt2 (void ); -void invalidate_interrupt3 (void ); -void invalidate_interrupt4 (void ); -void invalidate_interrupt5 (void ); -void invalidate_interrupt6 (void ); -void invalidate_interrupt7 (void ); -void thermal_interrupt (void ); -void threshold_interrupt (void ); -void i8254_timer_resume (void ); -static void setup_timer_hardware (void ) {outb_p (0x34 ,0x43 );/* binary, mode 2, LSB/MSB, ch 0 */
include/asm-x86_64/hw_irq.h +20 -0
@@ -95,6 +95,26 @@#ifndef __ASSEMBLY__ + +/* Interrupt handlers registered during init_IRQ */ +void apic_timer_interrupt (void ); +void spurious_interrupt (void ); +void error_interrupt (void ); +void reschedule_interrupt (void ); +void call_function_interrupt (void ); +void irq_move_cleanup_interrupt (void ); +void invalidate_interrupt0 (void ); +void invalidate_interrupt1 (void ); +void invalidate_interrupt2 (void ); +void invalidate_interrupt3 (void ); +void invalidate_interrupt4 (void ); +void invalidate_interrupt5 (void ); +void invalidate_interrupt6 (void ); +void invalidate_interrupt7 (void ); +void thermal_interrupt (void ); +void threshold_interrupt (void ); +void i8254_timer_resume (void ); +typedef int vector_irq_t [NR_VECTORS ];DECLARE_PER_CPU (vector_irq_t, vector_irq);extern void __setup_vector_irq (int cpu);
PATCH 11/48 x86_64: During VM oom condition, kill all threads in process group
In reply to Andi KleenFrom: Will Schmidt <[email protected]>
During a VM oom condition, kill all threads in the process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM: out_of_memory condition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or otherwise handled, and makes it very obvious that something has gone wrong.
This change allows the entire process group to be taken down, rather than just the one thread.
---
arch/x86_64/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/mm/fault.c +1 -1
@@ -569,7 +569,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (error_code &4 ) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
Re: [PATCH for review] [11/48] x86_64: During VM oom condition, kill all threads in process group
Quoted 8 lines · Andi Kleen
From: Will Schmidt <[email protected]>
During a VM oom condition, kill all threads in the process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.
Quoted 7 lines
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or otherwise handled, and makes it very obvious that something has gone wrong.
This change allows the entire process group to be taken down, rather than just the one thread.
Shouldn't we have one patc hthat does this for every architecture instead of going through arch maintainers and probably losing half of them?
Quoted 13 lines
Index:
linux/arch/x86_64/mm/fault.c
===================================================================arch/x86_64/mm/fault.c +1
-1@@ -569,7 +569,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (error_code &4 ) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
Geert Uytterhoeven
maintainerRe: [PATCH for review] [11/48] x86_64: During VM oom condition, kill all threads in process group
Quoted 13 lines · Christoph Hellwig
Quoted 12 lines · Andi Kleen
From: Will Schmidt <[email protected]>
During a VM oom condition, kill all threads in the process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or otherwise handled, and makes it very obvious that something has gone wrong.
Quoted 5 lines
Quoted 2 lines
This change allows the entire process group to be taken down, rather than just the one thread.
Shouldn't we have one patc hthat does this for every architecture instead of going through arch maintainers and probably losing half of them?
Yes, please ;-)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
return -EMAINTAINER_TOO_BUSY
Re: [PATCH for review] [11/48] x86_64: During VM oom condition, kill all threads in process group
Quoted 14 lines · Geert Uytterhoeven
Quoted 13 lines · Christoph Hellwig
Quoted 12 lines · Andi Kleen
From: Will Schmidt <[email protected]>
During a VM oom condition, kill all threads in the process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or otherwise handled, and makes it very obvious that something has gone wrong.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
This change allows the entire process group to be taken down, rather than just the one thread.
Shouldn't we have one patc hthat does this for every architecture instead of going through arch maintainers and probably losing half of them?
Yes, please ;-)
Ok, i'm convinced. :-) I'll spin up an all-arch encompassing patch
in the next day or so.
-Will
Quoted 9 lines
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]return -EMAINTAINER_TOO_BUSY
PATCH 1/1 During VM oom condition, kill all threads in process group
In reply to Geert UytterhoevenDuring VM oom condition, kill all threads in process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM: out_of_memory condition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong.
This change allows the entire process group to be taken down, rather than just the one thread.
---
This patch hits all arches except for x86_64 and powerpc; those arches
have already been updated with this change.
arch/alpha/mm/fault.c +1 -1
@@ -197,7 +197,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, current->comm, current->pid);if (!user_mode (regs)) goto no_context; -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); do_sigbus:/* Send a sigbus, regardless of whether we were in kernel
arch/arm/mm/fault.c +1 -1
@@ -266,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)* the page fault gracefully. */ printk ("VM: killing process %s\n" , tsk->comm); -do_exit (SIGKILL ); +do_group_exit (SIGKILL );return 0 ; }if (fault &VM_FAULT_SIGBUS ) {
arch/arm26/mm/fault.c +1 -1
@@ -246,7 +246,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)* us that made us unable to handle the page fault gracefully. */ printk ("VM: killing process %s\n" , tsk->comm); -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); }else {__do_user_fault (tsk, addr, fsr, fault ==-1 ?SEGV_ACCERR :SEGV_MAPERR , regs);
arch/avr32/mm/fault.c +1 -1
@@ -216,7 +216,7 @@ out_of_memory: }printk ("VM: Killing process %s\n" , tsk->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/cris/mm/fault.c +1 -1
@@ -360,7 +360,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,up_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , tsk->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/frv/mm/fault.c +1 -1
@@ -259,7 +259,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long earup_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , current->comm);if (user_mode (__frame)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/i386/mm/fault.c +1 -1
@@ -597,7 +597,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (error_code &4 ) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/ia64/mm/fault.c +1 -1
@@ -273,6 +273,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re }printk (KERN_CRIT "VM: killing process %s\n" , current->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; }
arch/m32r/mm/fault.c +1 -1
@@ -278,7 +278,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (error_code &ACE_USERMODE ) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/m68k/mm/fault.c +1 -1
@@ -188,7 +188,7 @@ out_of_memory:printk ("VM: killing process %s\n" , current->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); no_context: current->thread.signo =SIGBUS ;
arch/mips/mm/fault.c +1 -1
@@ -180,7 +180,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/parisc/mm/fault.c +1 -1
@@ -263,6 +263,6 @@ no_context:up_read (&mm->mmap_sem);printk (KERN_CRIT "VM: killing process %s\n" , current->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; }
arch/ppc/mm/fault.c +1 -1
@@ -297,7 +297,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , current->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL );return SIGKILL ; do_sigbus:
arch/s390/mm/fault.c +1 -1
@@ -218,7 +218,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code, }printk ("VM: killing process %s\n" , tsk->comm);if (regs->psw.mask &PSW_MASK_PSTATE ) -do_exit (SIGKILL ); +do_group_exit (SIGKILL );do_no_context (regs, error_code, address);return 0 ; }
arch/sh/mm/fault.c +1 -1
@@ -215,7 +215,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/sh64/mm/fault.c +1 -1
@@ -334,7 +334,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , tsk->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/sparc/mm/fault.c +1 -1
@@ -369,7 +369,7 @@ out_of_memory:up_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , tsk->comm);if (from_user) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto no_context; do_sigbus:
arch/sparc64/mm/fault.c +1 -1
@@ -466,7 +466,7 @@ out_of_memory:up_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , current->comm);if (!(regs->tstate &TSTATE_PRIV )) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto handle_kernel_fault; intr_or_no_mm:
arch/xtensa/mm/fault.c +1 -1
@@ -150,7 +150,7 @@ out_of_memory: }printk ("VM: killing process %s\n" , current->comm);if (user_mode (regs)) -do_exit (SIGKILL ); +do_group_exit (SIGKILL );bad_page_fault (regs, address,SIGKILL );return ;
Andrew Morton
maintainerRe: [PATCH respin, was PATCH for review] During VM oom condition, kill all threads in process group
Quoted 10 lines · On Mon, 23 Jul 2007 13:09:45 -0500 Will Schmidt <[email protected]>…
During VM oom condition, kill all threads in process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong.
Quoted 2 lines
This change allows the entire process group to be taken down, rather than just the one thread.
Just checking...
blackfin
h8300
m68knommu
uml
v850
were not changed. Intentional?
Re: [PATCH respin, was PATCH for review] During VM oom condition, kill all threads in process group
Quoted 18 lines · Andrew Morton
Quoted 10 lines · On Mon, 23 Jul 2007 13:09:45 -0500 Will Schmidt <[email protected]>…
During VM oom condition, kill all threads in process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong.Quoted 2 lines
This change allows the entire process group to be taken down, rather than just the one thread.
Just checking...
Quoted 7 lines
blackfin
h8300
m68knommu
uml
v850were not changed. Intentional?
Yes. Those arch's don't have the VM oom code that I could see. There
is an occasional do_exit() reference elsewhere in the fault handler code, for reasons other than VM oom, so I deliberately didn't touch those either.
Re: [PATCH respin, was PATCH for review] During VM oom condition, kill all threads in process group
Quoted 8 lines · Will Schmidt
Quoted 8 lines
Just checking...
blackfin
h8300
m68knommu
uml
v850
Quoted 6 lines
Quoted 1 line
were not changed. Intentional?
Yes. Those arch's don't have the VM oom code that I could see. There
is an occasionaldo_exit()reference elsewhere in the fault handler code, for reasons other than VM oom, so I deliberately didn't touch those either.
Except for uml these are the !CONFIG_MMU only architectures, so that makes a lot of sense.
Re: [PATCH respin, was PATCH for review] During VM oom condition, kill all threads in process group
In reply to Will SchmidtHi!
Quoted 21 lines
During VM oom condition, kill all threads in process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong.This change allows the entire process group to be taken down, rather than just the one thread.
Signed-off-by Will Schmidt <[email protected]>arch/sparc64/mm/fault.c +0
-0
arch/sparc64/mm/fault.c out_of_memory: · line 472
Quoted 8 lines
arch/sparc64/mm/fault.c +1
-1@@ -466,7 +466,7 @@ out_of_memory:up_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , current->comm);if (!(regs->tstate &TSTATE_PRIV )) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto handle_kernel_fault; intr_or_no_mm:
is the printk still accurate (does it kill more than one process now)? Why does it print when it will not really kill the process?
I see similar code across all the archs... would it make sense to create common helper... or is the helper too trivial?
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH respin, was PATCH for review] During VM oom condition, kill all threads in process group
Quoted 30 lines · Pavel Machek
Hi!
Quoted 28 lines
During VM oom condition, kill all threads in process group.
We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM:
out_of_memorycondition.
Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong.This change allows the entire process group to be taken down, rather than just the one thread.
Signed-off-by Will Schmidt <[email protected]>arch/sparc64/mm/fault.c +1
-1@@ -466,7 +466,7 @@ out_of_memory:up_read (&mm->mmap_sem);printk ("VM: killing process %s\n" , current->comm);if (!(regs->tstate &TSTATE_PRIV )) -do_exit (SIGKILL ); +do_group_exit (SIGKILL ); goto handle_kernel_fault;
Quoted 3 lines
arch/sparc64/mm/fault.c out_of_memory: · line 472
Quoted 1 line
arch/sparc64/mm/fault.c +0
-0intr_or_no_mm:is the printk still accurate (does it kill more than one process now)?
I was going to double-check this morning.. but don't see where current->comm is copied into a new task_struct. I thought that all processes within the group had the same current->comm value, so figure this is OK.
Quoted 1 line
Why does it print when it will not really kill the process?
no idea..
Quoted 2 lines
I see similar code across all the archs... would it make sense to create common helper... or is the helper too trivial?
The checks blocking flow into do_group_exit, like (regs->tstate & TSTATE_PRIV) for sparc64, or (user_mode(regs)) for powerpc, do vary
across the arch's. The code could be rearranged to have a helper
containing just the printk and the do_group_exit() call; but I'm not sure that would be an improvement.
maybe a do_group_sigkill_if(condition); helper :-)
-Will
Quoted 1 line
Pavel
PATCH 12/48 x86_64: use the global PIT lock
In reply to Andi KleenFrom: Thomas Gleixner <[email protected]>
Replace the pcspkr private PIT lock by the global PIT lock to serialize the PIT access all over the place.
---
arch/x86_64/kernel/time.c | 2 ++ drivers/input/misc/pcspkr.c | 11 ++++++++--- include/asm-x86_64/i8253.h | 6 ++++++ 3 files changed, 16 insertions(+), 3 deletions(-)
arch/x86_64/kernel/time.c +2 -0
@@ -33,6 +33,7 @@#include <acpi/acpi_bus.h> #endif #include <asm/8253pit.h> +#include <asm/i8253.h> #include <asm/pgtable.h> #include <asm/vsyscall.h> #include <asm/timex.h>
@@ -51,6 +52,7 @@ static char *timename = NULL;DEFINE_SPINLOCK (rtc_lock);EXPORT_SYMBOL (rtc_lock);DEFINE_SPINLOCK (i8253_lock); +EXPORT_SYMBOL (i8253_lock);volatile unsigned long __jiffies __section_jiffies =INITIAL_JIFFIES ;
drivers/input/misc/pcspkr.c +8 -3
@@ -24,7 +24,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@uMODULE_DESCRIPTION ("PC Speaker beeper driver" );MODULE_LICENSE ("GPL" ); -static DEFINE_SPINLOCK (i8253_beep_lock); +#ifdef CONFIG_X86 +/* Use the global PIT lock ! */ +#include <asm/i8253.h> +#else +static DEFINE_SPINLOCK (i8253_lock); +#endif static int pcspkr_event (struct input_dev *dev,unsigned int type,unsigned int code,int value) {
@@ -43,7 +48,7 @@ static int pcspkr_event(struct input_devif (value >20 && value <32767 ) count =PIT_TICK_RATE / value; -spin_lock_irqsave (&i8253_beep_lock, flags); +spin_lock_irqsave (&i8253_lock, flags);if (count) {/* enable counter 2 */
@@ -58,7 +63,7 @@ static int pcspkr_event(struct input_devoutb (inb_p (0x61 ) &0xFC ,0x61 ); } -spin_unlock_irqrestore (&i8253_beep_lock, flags); +spin_unlock_irqrestore (&i8253_lock, flags);return 0 ; }
include/asm-x86_64/i8253.h new file +6 -0
@@ -0,0 +1,6 @@ +#ifndef __ASM_I8253_H__ +#define __ASM_I8253_H__ + +extern spinlock_t i8253_lock; + +#endif /* __ASM_I8253_H__ */
Dmitry Torokhov
maintainerRe: [PATCH for review] [12/48] x86_64: use the global PIT lock
Hi Andi,
Quoted 6 lines · Andi Kleen
From: Thomas Gleixner <[email protected]>
Replace the pcspkr private PIT lock by the global PIT lock to serialize the PIT access all over the place.
Like I said before I'd be more happy if spinlock was attached to a platform device that pcspkr binds to so the arch code would control wehther we use a private spinlock or a global one (I sent a patch to that effect earlier). However I am OK with Thomas's patch as well.
Signature · 1 line
Dmitry
Re: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 6 lines · On Thursday 19 July 2007 17:22:38 Dmitry Torokhov wrote:
Hi Andi,
Quoted 3 lines · Andi Kleen
From: Thomas Gleixner <[email protected]>
Quoted 8 lines
Quoted 3 lines
Replace the pcspkr private PIT lock by the global PIT lock to serialize the PIT access all over the place.
Like I said before I'd be more happy if spinlock was attached to a platform device that pcspkr binds to so the arch code would control wehther we use a private spinlock or a global one (I sent a patch to that effect earlier).
Not sure that flexibility is needed. Why would an architecture ever want to have more than one lock for this? And we normally don't need sysdevs for locks, they seem to be quite unrelated.
AFAIK sysdevs are just for suspend/resume, and even for that they seem to get obsoleted now.
-Andi
Dmitry Torokhov
maintainerRe: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 11 lines · Andi Kleen
Quoted 10 lines · On Thursday 19 July 2007 17:22:38 Dmitry Torokhov wrote:
Hi Andi,
Quoted 6 lines · Andi Kleen
From: Thomas Gleixner <[email protected]>
Replace the pcspkr private PIT lock by the global PIT lock to serialize the PIT access all over the place.
Quoted 9 lines
Quoted 4 lines
Like I said before I'd be more happy if spinlock was attached to a platform device that pcspkr binds to so the arch code would control wehther we use a private spinlock or a global one (I sent a patch to that effect earlier).
Not sure that flexibility is needed. Why would an architecture ever want to have more than one lock for this? And we normally don't need sysdevs for locks, they seem to be quite unrelated.
I was not talking about sysdevs. I was talking about platform devices that are already being created for pcspkr by arch code. Now I want arch code to provide a spinlock for pcspkr driver to use when accessing PIT. What it does it allows to remove arch specific knowledge (i.e. #ifdef CONFIG_X86...) from the pcspkr driver.
Signature · 1 line
Dmitry
Re: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 7 lines
I was not talking about sysdevs. I was talking about platform devices that are already being created for pcspkr by arch code. Now I want arch code to provide a spinlock for pcspkr driver to use when accessing PIT. What it does it allows to remove arch specific knowledge (i.e. #ifdef
CONFIG_X86...) from the pcspkr driver.
Ok please send a patch.
-Andi
Re: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 8 lines · Andi Kleen
Quoted 7 lines
I was not talking about sysdevs. I was talking about platform devices that are already being created for pcspkr by arch code. Now I want arch code to provide a spinlock for pcspkr driver to use when accessing PIT. What it does it allows to remove arch specific knowledge (i.e. #ifdef
CONFIG_X86...) from the pcspkr driver.
Quoted 4 lines
Ok please send a patch.
-Andi
Here it is...
Signature · 356 lines
Dmitry Subject: Input: pcspkr - use proper lock From: Dmitry Torokhov <[email protected]> On i386 and x86_64 the access to the PIT is serialized by a lock in the architecture code. The separate locking in the PC-speaker code ignores the global lock and creates a nasty race between the PC-speaker and the PIT clock source/events code on SMP machines. To fix this we architecture code attaches proper lock to the pcspkr platform device and the driver uses it instead of it's own private lock. Noticed by Thomas Gleixner <[email protected]> Also resore uevent generation for pcspkr devices so that the driver can be loaded automatically by udev. Signed-off-by: Dmitry Torokhov <[email protected]> --- arch/i386/kernel/pcspeaker.c | 20 ------------------- arch/alpha/kernel/setup.c | 9 +++++++- arch/i386/kernel/Makefile | 1 arch/i386/kernel/i8253.c | 23 ++++++++++++++++++++++ arch/mips/kernel/pcspeaker.c | 9 +++++++- arch/powerpc/kernel/setup-common.c | 9 +++++++- arch/x86_64/kernel/Makefile | 2 - arch/x86_64/kernel/time.c | 38 +++++++++++++++++++++++++++++-------- drivers/input/misc/pcspkr.c | 10 +++++---- 9 files changed, 83 insertions(+), 38 deletions(-) Index: work/arch/alpha/kernel/setup.c =================================================================== --- work.orig/arch/alpha/kernel/setup.c +++ work/arch/alpha/kernel/setup.c @@ -1492,6 +1492,8 @@ alpha_panic_event(struct notifier_block return NOTIFY_DONE; } +static DEFINE_SPINLOCK(i8253_lock); + static __init int add_pcspkr(void) { struct platform_device *pd; @@ -1501,9 +1503,14 @@ static __init int add_pcspkr(void) if (!pd) return -ENOMEM; + pd->dev.platform_data = &i8253_lock; + pd->dev.uevent_suppress = 0; + ret = platform_device_add(pd); - if (ret) + if (ret) { + pd->dev.platform_data = NULL; /* so we don't try to free it */ platform_device_put(pd); + } return ret; } Index: work/arch/mips/kernel/pcspeaker.c =================================================================== --- work.orig/arch/mips/kernel/pcspeaker.c +++ work/arch/mips/kernel/pcspeaker.c @@ -10,6 +10,8 @@ #include <linux/platform_device.h> +static DEFINE_SPINLOCK(i8253_lock); + static __init int add_pcspkr(void) { struct platform_device *pd; @@ -19,9 +21,14 @@ static __init int add_pcspkr(void) if (!pd) return -ENOMEM; + pd->dev.platform_data = &i8253_lock; + pd->dev.uevent_suppress = 0; + ret = platform_device_add(pd); - if (ret) + if (ret) { + pd->dev.platform_data = NULL; /* so we don't try to free it */ platform_device_put(pd); + } return ret; } Index: work/arch/x86_64/kernel/time.c =================================================================== --- work.orig/arch/x86_64/kernel/time.c +++ work/arch/x86_64/kernel/time.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/sysdev.h> +#include <linux/platform_device.h> #include <linux/bcd.h> #include <linux/notifier.h> #include <linux/cpu.h> @@ -185,7 +186,7 @@ void main_timer_handler(void) set_rtc_mmss(xtime.tv_sec); rtc_update = xtime.tv_sec + 660; } - + write_sequnlock(&xtime_lock); } @@ -226,7 +227,7 @@ static unsigned long get_cmos_time(void) /* * We know that x86-64 always uses BCD format, no need to check the * config register. - */ + */ BCD_TO_BIN(sec); BCD_TO_BIN(min); @@ -239,11 +240,11 @@ static unsigned long get_cmos_time(void) BCD_TO_BIN(century); year += century * 100; printk(KERN_INFO "Extended CMOS year: %d\n", century * 100); - } else { + } else { /* * x86-64 systems only exists since 2002. * This will work up to Dec 31, 2100 - */ + */ year += 2000; } @@ -321,7 +322,7 @@ static unsigned int __init pit_calibrate end = get_cycles_sync(); spin_unlock_irqrestore(&i8253_lock, flags); - + return (end - start) / 50; } @@ -366,7 +367,7 @@ static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_IRQPOLL, .mask = CPU_MASK_NONE, - .name = "timer" + .name = "timer" }; void __init time_init(void) @@ -384,7 +385,7 @@ void __init time_init(void) if (hpet_use_timer) { /* set tick_nsec to use the proper rate for HPET */ - tick_nsec = TICK_NSEC_HPET; + tick_nsec = TICK_NSEC_HPET; tsc_khz = hpet_calibrate_tsc(); timename = "HPET"; } else { @@ -485,5 +486,26 @@ static int time_init_device(void) error = sysdev_register(&device_timer); return error; } - device_initcall(time_init_device); + +static __init int add_pcspkr(void) +{ + struct platform_device *pd; + int ret; + + pd = platform_device_alloc("pcspkr", -1); + if (!pd) + return -ENOMEM; + + pd->dev.platform_data = &i8253_lock; + pd->dev.uevent_suppress = 0; + + ret = platform_device_add(pd); + if (ret) { + pd->dev.platform_data = NULL; /* so we don't try to free it */ + platform_device_put(pd); + } + + return ret; +} +device_initcall(add_pcspkr); Index: work/arch/i386/kernel/i8253.c =================================================================== --- work.orig/arch/i386/kernel/i8253.c +++ work/arch/i386/kernel/i8253.c @@ -6,6 +6,7 @@ #include <linux/spinlock.h> #include <linux/jiffies.h> #include <linux/sysdev.h> +#include <linux/platform_device.h> #include <linux/module.h> #include <linux/init.h> @@ -204,3 +205,25 @@ static int __init init_pit_clocksource(v return clocksource_register(&clocksource_pit); } arch_initcall(init_pit_clocksource); + +static __init int add_pcspkr(void) +{ + struct platform_device *pd; + int ret; + + pd = platform_device_alloc("pcspkr", -1); + if (!pd) + return -ENOMEM; + + pd->dev.platform_data = &i8253_lock; + pd->dev.uevent_suppress = 0; + + ret = platform_device_add(pd); + if (ret) { + pd->dev.platform_data = NULL; /* so we don't try to free it */ + platform_device_put(pd); + } + + return ret; +} +device_initcall(add_pcspkr); Index: work/arch/x86_64/kernel/Makefile =================================================================== --- work.orig/arch/x86_64/kernel/Makefile +++ work/arch/x86_64/kernel/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_PCI) += early-quirks.o obj-y += topology.o obj-y += intel_cacheinfo.o obj-y += addon_cpuid_features.o -obj-y += pcspeaker.o CFLAGS_vsyscall.o := $(PROFILING) -g0 @@ -61,5 +60,4 @@ quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o alternative-y += ../../i386/kernel/alternative.o -pcspeaker-y += ../../i386/kernel/pcspeaker.o perfctr-watchdog-y += ../../i386/kernel/cpu/perfctr-watchdog.o Index: work/arch/i386/kernel/Makefile =================================================================== --- work.orig/arch/i386/kernel/Makefile +++ work/arch/i386/kernel/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_K8_NB) += k8.o obj-$(CONFIG_VMI) += vmi.o vmiclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o -obj-y += pcspeaker.o obj-$(CONFIG_SCx200) += scx200.o Index: work/arch/i386/kernel/pcspeaker.c =================================================================== --- work.orig/arch/i386/kernel/pcspeaker.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <linux/platform_device.h> -#include <linux/errno.h> -#include <linux/init.h> - -static __init int add_pcspkr(void) -{ - struct platform_device *pd; - int ret; - - pd = platform_device_alloc("pcspkr", -1); - if (!pd) - return -ENOMEM; - - ret = platform_device_add(pd); - if (ret) - platform_device_put(pd); - - return ret; -} -device_initcall(add_pcspkr); Index: work/drivers/input/misc/pcspkr.c =================================================================== --- work.orig/drivers/input/misc/pcspkr.c +++ work/drivers/input/misc/pcspkr.c @@ -24,10 +24,10 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@u MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); -static DEFINE_SPINLOCK(i8253_beep_lock); - static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct platform_device *pdev = input_get_drvdata(dev); + spinlock_t *i8253_lock = pdev->dev.platform_data; unsigned int count = 0; unsigned long flags; @@ -43,7 +43,7 @@ static int pcspkr_event(struct input_dev if (value > 20 && value < 32767) count = PIT_TICK_RATE / value; - spin_lock_irqsave(&i8253_beep_lock, flags); + spin_lock_irqsave(i8253_lock, flags); if (count) { /* enable counter 2 */ @@ -58,7 +58,7 @@ static int pcspkr_event(struct input_dev outb(inb_p(0x61) & 0xFC, 0x61); } - spin_unlock_irqrestore(&i8253_beep_lock, flags); + spin_unlock_irqrestore(i8253_lock, flags); return 0; } @@ -84,6 +84,8 @@ static int __devinit pcspkr_probe(struct pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); pcspkr_dev->event = pcspkr_event; + input_set_drvdata(pcspkr_dev, dev); + err = input_register_device(pcspkr_dev); if (err) { input_free_device(pcspkr_dev); Index: work/arch/powerpc/kernel/setup-common.c =================================================================== --- work.orig/arch/powerpc/kernel/setup-common.c +++ work/arch/powerpc/kernel/setup-common.c @@ -425,6 +425,8 @@ void __init smp_setup_cpu_maps(void) } #endif /* CONFIG_SMP */ +static DEFINE_SPINLOCK(i8253_lock); + static __init int add_pcspkr(void) { struct device_node *np; @@ -440,9 +442,14 @@ static __init int add_pcspkr(void) if (!pd) return -ENOMEM; + pd->dev.platform_data = &i8253_lock; + pd->dev.uevent_suppress = 0; + ret = platform_device_add(pd); - if (ret) + if (ret) { + pd->dev.platform_data = NULL; /* so we don't try to free it */ platform_device_put(pd); + } return ret; }
Re: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 11 lines
(quoted diff) +2
-0+static DEFINE_SPINLOCK(i8253_lock); +static
__initintadd_pcspkr(void)
{
structplatform_device*pd;(quoted diff) +0
-0@@ -1501,9 +1503,14 @@ static __init int add_pcspkr(void) if (!pd) return -ENOMEM;
+ pd->dev.platform_data =&i8253_lock;
That seems pretty ugly to pass spinlocks around in void * pointers. Also out of general memory bloat reasons i don't like allocating big data structures just for this.
Wouldn't it be better to just define i8253_lock weakly in the pcspkr code and let the architecture override it?
Quoted 13 lines
Index:
work/arch/x86_64/kernel/time.c
===================================================================arch/x86_64/kernel/time.c +1
-0@@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/sysdev.h> +#include <linux/platform_device.h> #include <linux/bcd.h> #include <linux/notifier.h> #include <linux/cpu.h>
arch/x86_64/kernel/time.c void main_timer_handler(void) · line 191
Quoted 7 lines
arch/x86_64/kernel/time.c +1
-1@@ -185,7 +186,7 @@ void main_timer_handler(void) set_rtc_mmss(xtime.tv_sec); rtc_update = xtime.tv_sec + 660; } - + write_sequnlock(&xtime_lock); }
No random white space changes in patches, multiple occurrences ?!?
-Andi
Dmitry Torokhov
maintainerRe: [PATCH for review] [12/48] x86_64: use the global PIT lock
Quoted 10 lines · Andi Kleen
Quoted 10 lines
(quoted diff) +2
-0+static DEFINE_SPINLOCK(i8253_lock); +static
__initintadd_pcspkr(void)
{
structplatform_device*pd;(quoted diff) +0
-0@@ -1501,9 +1503,14 @@ static __init int add_pcspkr(void) if (!pd) return -ENOMEM;
Quoted 3 lines
Review static __init int add_pcspkr(void) · line 1506
Quoted 1 line
(quoted diff) +1
-0+pd->dev.platform_data = &i8253_lock;That seems pretty ugly to pass spinlocks around in void * pointers.
That spinlock _is_ platform data. We could define
struct pcspkr_platform_data {
spinlock_t *lock;
};and pass around this as the rest of platform code does but then we'd need a header file and it would add a level of indirection but if you like this better I can change it. Otherwise spinlock is another data structure and we pass them around all teh time.
Quoted 4 lines
Also
out of general memory bloat reasons i don't like allocating big data structures just for this.
I am not sure where you see new data structure allocation... If you look at your box you should see that /sys/bus/platform/devices/pcspkr device is already there. We already create it so that pcspkr driver can bind to it.
Quoted 2 lines
Wouldn't it be better to just define
i8253_lockweakly in the pcspkr code and let the architecture override it?
Yes, it probably is btetter.
Quoted 15 lines
Quoted 15 lines
Index:
work/arch/x86_64/kernel/time.c
===================================================================arch/x86_64/kernel/time.c +1
-0@@ -23,6 +23,7 @@#include <linux/module.h> #include <linux/device.h> #include <linux/sysdev.h> +#include <linux/platform_device.h> #include <linux/bcd.h> #include <linux/notifier.h> #include <linux/cpu.h> @@ -185,7 +186,7 @@ void main_timer_handler(void)set_rtc_mmss (xtime.tv_sec);
Quoted 9 lines
arch/x86_64/kernel/time.c void main_timer_handler(void) · line 191
Quoted 6 lines
arch/x86_64/kernel/time.c +1
-1rtc_update = xtime.tv_sec +660 ; } - +write_sequnlock (&xtime_lock); }No random white space changes in patches, multiple occurrences ?!?
By bad, sorry.
Signature · 1 line
Dmitry
PATCH 13/48 x86_64: fix typo in acpi_pm.c
In reply to Andi KleenFrom: Alessio Igor Bogani <[email protected]>
---
drivers/clocksource/acpi_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/acpi_pm.c +1 -1
@@ -71,7 +71,7 @@ static struct clocksource clocksource_ac .rating = 200, .read = acpi_pm_read, .mask = (cycle_t)ACPI_PM_MASK, - .mult = 0, /*to be caluclated*/ + .mult = 0, /*to be calculated*/ .shift = 22, .flags = CLOCK_SOURCE_IS_CONTINUOUS,
PATCH 14/48 x86_64: lower printk severity
In reply to Andi KleenFrom: Dan Aloni <[email protected]>
---
arch/x86_64/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/kernel/process.c +1 -1
@@ -279,7 +279,7 @@ void __cpuinit select_idle_routine(const*/ if (!pm_idle) {if (!printed) { -printk ("using mwait in idle threads.\n" ); +printk (KERN_INFO "using mwait in idle threads.\n" ); printed =1 ; } pm_idle = mwait_idle;
PATCH 15/48 x86_64: fix wrong comment regarding set_fixmap()
In reply to Andi KleenFrom: Jiri Kosina <[email protected]>
The function name is set_fixmap(), not fixmap_set() as stated in the comment.
Also fix a typo, punctuation and lower/uppercase a bit.
---
include/asm-x86_64/fixmap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/asm-x86_64/fixmap.h +3 -3
@@ -22,9 +22,9 @@* compile time, but to set the physical address only * in the boot process. * -* these 'compile-time allocated' memory buffers are -* fixed-size 4k pages. (or larger if used with an increment -* highger than 1) use fixmap_set(idx,phys) to associate +* These 'compile-time allocated' memory buffers are +* fixed-size 4k pages (or larger if used with an increment +* higher than 1). Use set_fixmap(idx,phys) to associate * physical memory with fixmap indices. * * TLB entries of such buffers will not be flushed across
PATCH 16/48 x86_64: Geode HW Random Number Generator depends on X86_32
In reply to Andi KleenFrom: Yinghai Lu <[email protected]>
---
drivers/char/hw_random/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/hw_random/Kconfig +1 -1
@@ -41,7 +41,7 @@ config HW_RANDOM_AMD config HW_RANDOM_GEODE tristate "AMD Geode HW Random Number Generator support" - depends on HW_RANDOM && X86 && PCI + depends on HW_RANDOM && X86_32 && PCI default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number
PATCH 17/48 x86_64: change _map_single to static in pci_gart.c etc
In reply to Andi KleenFrom: Yinghai Lu <[email protected]>
This function is called via dma_ops->.., so change it to static
---
arch/x86_64/kernel/pci-gart.c | 6 +++--- arch/x86_64/kernel/pci-nommu.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-)
arch/x86_64/kernel/pci-gart.c +3 -3
@@ -235,7 +235,7 @@ static dma_addr_t gart_map_simple(struct }/* Map a single area into the IOMMU */ -dma_addr_t gart_map_single (struct device *dev,void *addr,size_t size,int dir) +static dma_addr_t gart_map_single (struct device *dev,void *addr,size_t size,int dir) {unsigned long phys_mem, bus;
@@ -253,7 +253,7 @@ dma_addr_t gart_map_single(struct device/* * Free a DMA mapping. */ -void gart_unmap_single (struct device *dev,dma_addr_t dma_addr, +static void gart_unmap_single (struct device *dev,dma_addr_t dma_addr,size_t size,int direction) {unsigned long iommu_page;
@@ -275,7 +275,7 @@ void gart_unmap_single(struct device *de/* * Wrapper for pci_unmap_single working with scatterlists. */ -void gart_unmap_sg (struct device *dev,struct scatterlist *sg,int nents,int dir) +static void gart_unmap_sg (struct device *dev,struct scatterlist *sg,int nents,int dir) {int i;
arch/x86_64/kernel/pci-nommu.c +3 -3
@@ -34,7 +34,7 @@ nommu_map_single(struct device *hwdev, vreturn bus; } -void nommu_unmap_single (struct device *dev,dma_addr_t addr,size_t size, +static void nommu_unmap_single (struct device *dev,dma_addr_t addr,size_t size,int direction) { }
@@ -54,7 +54,7 @@ void nommu_unmap_single(struct device *d* Device ownership issues as mentioned above for pci_map_single are * the same here. */ -int nommu_map_sg (struct device *hwdev,struct scatterlist *sg, +static int nommu_map_sg (struct device *hwdev,struct scatterlist *sg,int nents,int direction) {int i;
@@ -74,7 +74,7 @@ int nommu_map_sg(struct device *hwdev, s* Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -void nommu_unmap_sg (struct device *dev,struct scatterlist *sg, +static void nommu_unmap_sg (struct device *dev,struct scatterlist *sg,int nents,int dir) { }
PATCH 18/48 x86_64: flush_tlb_kernel_range() warning fix
In reply to Andi KleenFrom: Andrew Morton <[email protected]>
mm/vmalloc.c: In function 'unmap_kernel_range':mm/vmalloc.c:75: warning: unused variable 'start'
make it a C function so that the compiler thinks it used its arguments.
---
include/asm-x86_64/tlbflush.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
include/asm-x86_64/tlbflush.h +5 -1
@@ -92,7 +92,11 @@ static inline void flush_tlb_range(struc#endif -#define flush_tlb_kernel_range (start, end) flush_tlb_all() +static inline void flush_tlb_kernel_range (unsigned long start, +unsigned long end) +{ +flush_tlb_all (); +}static inline void flush_tlb_pgtables (struct mm_struct *mm,unsigned long start,unsigned long end)
PATCH 19/48 i386: add cpu_relax() to cmos_lock()
In reply to Andi KleenFrom: Andreas Mohr <[email protected]>
Add cpu_relax() to cmos_lock() inline function for faster operation on SMT CPUs and less power consumption on others in case of lock contention (which probably doesn't happen too often, so admittedly this patch is not too exciting).
---
include/asm-i386/mc146818rtc.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/asm-i386/mc146818rtc.h +4 -1
@@ -6,6 +6,7 @@#include <asm/io.h> #include <asm/system.h> +#include <asm/processor.h> #include <linux/mc146818rtc.h> #ifndef RTC_PORT
@@ -43,8 +44,10 @@ static inline void lock_cmos(unsigned chunsigned long new; new = ((smp_processor_id ()+1 ) <<8 ) | reg;for (;;) { -if (cmos_lock) +if (cmos_lock) { +cpu_relax ();continue ; + }if (__cmpxchg (&cmos_lock,0 , new,sizeof (cmos_lock)) ==0 )return ; }
PATCH 20/48 i386: replace hard-coded constant with appropriate macro from kernel.h
In reply to Andi KleenFrom: "Robert P. J. Day" <[email protected]>
---
include/asm-i386/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-i386/uaccess.h +1 -1
@@ -581,7 +581,7 @@ long __must_check __strncpy_from_user(ch* If there is a limit on the length of a valid string, you may wish to * consider using strnlen_user() instead. */ -#define strlen_user (str) strnlen_user(str, ~0UL >> 1) +#define strlen_user (str) strnlen_user(str, LONG_MAX)long strnlen_user (const char __user *str,long n);unsigned long __must_check clear_user (void __user *mem,unsigned long len);
PATCH 21/48 x86_64: disable the GART in shutdown
In reply to Andi KleenFrom: Yinghai Lu <[email protected]>
For K8 system: 4G RAM with memory hole remapping enabled, or more than 4G RAM installed. when using kexec to load second kernel. In the second kernel, when mem is allocated for GART, it will do the memset for clear, it will cause restart, because some device still used that for dma. solution will be:
in second kernel: disable that at first before we try to allocate mem for it. or in the first kernel: do disable that before shutdown. Andi/Eric/Alan prefer to second one for clean shutdown in first kernel. Andi also point out need to consider to AGP enable but mem less 4G case too.
---
arch/x86_64/kernel/pci-dma.c | 5 +++++ arch/x86_64/kernel/pci-gart.c | 20 ++++++++++++++++++++ arch/x86_64/kernel/reboot.c | 4 ++++ include/asm-x86_64/proto.h | 7 +++++++ 4 files changed, 36 insertions(+)
arch/x86_64/kernel/pci-dma.c +5 -0
@@ -321,6 +321,11 @@ static int __init pci_iommu_init(void)return 0 ; } +void pci_iommu_shutdown (void ) +{ +gart_iommu_shutdown (); +} +#ifdef CONFIG_PCI /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
arch/x86_64/kernel/pci-gart.c +20 -0
@@ -571,6 +571,26 @@ static const struct dma_mapping_ops gart .unmap_sg = gart_unmap_sg, }; +void gart_iommu_shutdown (void ) +{ +struct pci_dev *dev; +int i; + +if (no_agp && (dma_ops != &gart_dma_ops)) +return ; + +for (i =0 ; i < num_k8_northbridges; i++) { +u32 ctl; + + dev = k8_northbridges[i]; +pci_read_config_dword (dev,0x90 , &ctl); + + ctl &= ~1 ; + +pci_write_config_dword (dev,0x90 , ctl); + } +} +void __init gart_iommu_init (void ) {struct agp_kern_info info;
arch/x86_64/kernel/reboot.c +4 -0
@@ -16,6 +16,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <asm/apic.h> +#include <asm/proto.h> /* * Power off function, if any
@@ -81,6 +82,7 @@ static inline void kb_wait(void)void machine_shutdown (void ) {unsigned long flags; +/* Stop the cpus and apics */ #ifdef CONFIG_SMP int reboot_cpu_id;
@@ -111,6 +113,8 @@ void machine_shutdown(void)disable_IO_APIC ();local_irq_restore (flags); + +pci_iommu_shutdown (); }void machine_emergency_restart (void )
include/asm-x86_64/proto.h +7 -0
@@ -85,11 +85,13 @@ extern int exception_trace;extern unsigned cpu_khz;extern unsigned tsc_khz; +extern void pci_iommu_shutdown (void );extern void no_iommu_init (void );extern int force_iommu, no_iommu;extern int iommu_detected;#ifdef CONFIG_IOMMU extern void gart_iommu_init (void ); +extern void gart_iommu_shutdown (void );extern void __init gart_parse_options (char *);extern void iommu_hole_init (void );extern int fallback_aper_order;
@@ -101,6 +103,11 @@ extern int fix_aperture;#else #define iommu_aperture 0#define iommu_aperture_allowed 0 + +static inline void gart_iommu_shutdown (void ) +{ +} +#endif extern int reboot_force;
PATCH 22/48 x86_64: fix e820_hole_size based on address ranges
In reply to Andi KleenFrom: David Rientjes <[email protected]>
e820_hole_size() now uses the newly extracted helper function, e820_find_active_region(), to determine the size of usable RAM in a range of PFN's.
This was previously broken because of two reasons:
- The start and end PFN's of each e820 entry were not properly rounded prior to excluding those entries in the range, and
- Entries smaller than a page were not properly excluded from being accumulated.
This resulted in emulated nodes being incorrectly mapped to ranges that were completely reserved and not candidates for being registered as active ranges.
---
arch/x86_64/kernel/e820.c | 54 +++++++++++++++++++--------------------------- arch/x86_64/mm/numa.c | 8 +----- 2 files changed, 25 insertions(+), 37 deletions(-)
arch/x86_64/kernel/e820.c +23 -31
@@ -194,37 +194,6 @@ unsigned long __init e820_end_of_ram(voi }/* -* Find the hole size in the range. -*/ -unsigned long __init e820_hole_size (unsigned long start,unsigned long end) -{ -unsigned long ram =0 ; -int i; - -for (i =0 ; i < e820.nr_map; i++) { -struct e820entry *ei = &e820.map[i]; -unsigned long last, addr; - -if (ei->type !=E820_RAM || - ei->addr+ei->size <= start || - ei->addr >= end) -continue ; - - addr =round_up (ei->addr,PAGE_SIZE ); -if (addr < start) - addr = start; - - last =round_down (ei->addr + ei->size,PAGE_SIZE ); -if (last >= end) - last = end; - -if (last > addr) - ram += last - addr; - } -return ((end - start) - ram); -} - -/* * Mark e820 reserved areas as busy for the resource manager. */ void __init e820_reserve_resources (void )
@@ -364,6 +333,29 @@ void __init add_memory_region(unsigned l e820.nr_map++; } +/* +* Find the hole size (in bytes) in the memory range. +* @start: starting address of the memory range to scan +* @end: ending address of the memory range to scan +*/ +unsigned long __init e820_hole_size (unsigned long start,unsigned long end) +{ +unsigned long start_pfn = start >>PAGE_SHIFT ; +unsigned long end_pfn = end >>PAGE_SHIFT ; +unsigned long ei_startpfn; +unsigned long ei_endpfn; +unsigned long ram =0 ; +int i; + +for (i =0 ; i < e820.nr_map; i++) { +if (e820_find_active_region (&e820.map[i], + start_pfn, end_pfn, + &ei_startpfn, &ei_endpfn)) + ram += ei_endpfn - ei_startpfn; + } +return end - start - (ram <<PAGE_SHIFT ); +} +void __init e820_print_map (char *who) {int i;
arch/x86_64/mm/numa.c +2 -6
@@ -273,9 +273,6 @@ void __init numa_init_array(void)#ifdef CONFIG_NUMA_EMU /* Numa emulation */ -#define E820_ADDR_HOLE_SIZE (start, end) \ - (e820_hole_size((start) >> PAGE_SHIFT, (end) >> PAGE_SHIFT) << \ - PAGE_SHIFT)char *cmdline__initdata ;/*
@@ -319,7 +316,7 @@ static int __init split_nodes_equally(streturn -1 ;if (num_nodes >MAX_NUMNODES ) num_nodes =MAX_NUMNODES ; - size = (max_addr - *addr -E820_ADDR_HOLE_SIZE (*addr, max_addr)) / + size = (max_addr - *addr -e820_hole_size (*addr, max_addr)) / num_nodes;/* * Calculate the number of big nodes that can be allocated as a result
@@ -347,7 +344,7 @@ static int __init split_nodes_equally(stif (i == num_nodes + node_start -1 ) end = max_addr;else -while (end - *addr -E820_ADDR_HOLE_SIZE (*addr, end) < +while (end - *addr -e820_hole_size (*addr, end) < size) { end +=FAKE_NODE_MIN_SIZE ;if (end > max_addr) {
@@ -488,7 +485,6 @@ out:numa_init_array (); return 0; } -#undef E820_ADDR_HOLE_SIZE#endif /* CONFIG_NUMA_EMU */ void __init numa_initmem_init (unsigned long start_pfn,unsigned long end_pfn)
PATCH 23/48 x86_64: disable srat when numa emulation succeeds
In reply to Andi KleenFrom: David Rientjes <[email protected]>
When NUMA emulation succeeds, acpi_numa needs to be set to -1 so that srat_disabled() will always return true. We won't be calling acpi_scan_nodes() or registering the true nodes we've found.
---
arch/x86_64/mm/numa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86_64/mm/numa.c +5 -1
@@ -473,9 +473,13 @@ out:/* * We need to vacate all active ranges that may have been registered by -* SRAT. +* SRAT and set acpi_numa to -1 so that srat_disabled() always returns +* true. NUMA emulation has succeeded so we will not scan ACPI nodes. */ remove_all_active_ranges (); +#ifdef CONFIG_ACPI_NUMA + acpi_numa =-1 ; +#endif for_each_node_mask (i, node_possible_map) {e820_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , nodes[i].end >>PAGE_SHIFT );
PATCH 24/48 x86_64: move iommu declaration from proto to iommu.h
In reply to Andi KleenFrom: Yinghai Lu <[email protected]>
---
arch/x86_64/kernel/aperture.c | 2 +- arch/x86_64/kernel/early-quirks.c | 1 + arch/x86_64/kernel/pci-calgary.c | 2 +- arch/x86_64/kernel/pci-dma.c | 2 +- arch/x86_64/kernel/pci-gart.c | 1 + arch/x86_64/kernel/pci-nommu.c | 2 +- arch/x86_64/kernel/pci-swiotlb.c | 2 +- arch/x86_64/kernel/reboot.c | 2 +- include/asm-x86_64/iommu.h | 29 +++++++++++++++++++++++++++++ include/asm-x86_64/proto.h | 25 ------------------------- 10 files changed, 37 insertions(+), 31 deletions(-)
arch/x86_64/kernel/aperture.c +1 -1
@@ -20,7 +20,7 @@#include <linux/ioport.h> #include <asm/e820.h> #include <asm/io.h> -#include <asm/proto.h> +#include <asm/iommu.h> #include <asm/pci-direct.h> #include <asm/dma.h> #include <asm/k8.h>
arch/x86_64/kernel/early-quirks.c +1 -0
@@ -14,6 +14,7 @@#include <linux/pci_ids.h> #include <asm/pci-direct.h> #include <asm/proto.h> +#include <asm/iommu.h> #include <asm/dma.h> static void __init via_bugs (void )
arch/x86_64/kernel/pci-calgary.c +1 -1
@@ -35,7 +35,7 @@#include <linux/pci_ids.h> #include <linux/pci.h> #include <linux/delay.h> -#include <asm/proto.h> +#include <asm/iommu.h> #include <asm/calgary.h> #include <asm/tce.h> #include <asm/pci-direct.h>
arch/x86_64/kernel/pci-dma.c +1 -1
@@ -8,7 +8,7 @@#include <linux/pci.h> #include <linux/module.h> #include <asm/io.h> -#include <asm/proto.h> +#include <asm/iommu.h> #include <asm/calgary.h> int iommu_merge__read_mostly =0 ;
arch/x86_64/kernel/pci-gart.c +1 -0
@@ -28,6 +28,7 @@#include <asm/mtrr.h> #include <asm/pgtable.h> #include <asm/proto.h> +#include <asm/iommu.h> #include <asm/cacheflush.h> #include <asm/swiotlb.h> #include <asm/dma.h>
arch/x86_64/kernel/pci-nommu.c +1 -1
@@ -6,7 +6,7 @@#include <linux/string.h> #include <linux/dma-mapping.h> -#include <asm/proto.h> +#include <asm/iommu.h> #include <asm/processor.h> #include <asm/dma.h>
arch/x86_64/kernel/pci-swiotlb.c +1 -1
@@ -5,7 +5,7 @@#include <linux/module.h> #include <linux/dma-mapping.h> -#include <asm/proto.h> +#include <asm/iommu.h> #include <asm/swiotlb.h> #include <asm/dma.h>
arch/x86_64/kernel/reboot.c +1 -1
@@ -16,7 +16,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <asm/apic.h> -#include <asm/proto.h> +#include <asm/iommu.h> /* * Power off function, if any
include/asm-x86_64/iommu.h new file +29 -0
@@ -0,0 +1,29 @@ +#ifndef _ASM_X8664_IOMMU_H +#define _ASM_X8664_IOMMU_H 1 + +extern void pci_iommu_shutdown (void ); +extern void no_iommu_init (void ); +extern int force_iommu, no_iommu; +extern int iommu_detected; +#ifdef CONFIG_IOMMU +extern void gart_iommu_init (void ); +extern void gart_iommu_shutdown (void ); +extern void __init gart_parse_options (char *); +extern void iommu_hole_init (void ); +extern int fallback_aper_order; +extern int fallback_aper_force; +extern int iommu_aperture; +extern int iommu_aperture_allowed; +extern int iommu_aperture_disabled; +extern int fix_aperture; +#else +#define iommu_aperture 0 +#define iommu_aperture_allowed 0 + +static inline void gart_iommu_shutdown (void ) +{ +} + +#endif + +#endif
include/asm-x86_64/proto.h +0 -25
@@ -85,31 +85,6 @@ extern int exception_trace;extern unsigned cpu_khz;extern unsigned tsc_khz; -extern void pci_iommu_shutdown (void ); -extern void no_iommu_init (void ); -extern int force_iommu, no_iommu; -extern int iommu_detected; -#ifdef CONFIG_IOMMU -extern void gart_iommu_init (void ); -extern void gart_iommu_shutdown (void ); -extern void __init gart_parse_options (char *); -extern void iommu_hole_init (void ); -extern int fallback_aper_order; -extern int fallback_aper_force; -extern int iommu_aperture; -extern int iommu_aperture_allowed; -extern int iommu_aperture_disabled; -extern int fix_aperture; -#else -#define iommu_aperture 0 -#define iommu_aperture_allowed 0 - -static inline void gart_iommu_shutdown (void ) -{ -} - -#endif -extern int reboot_force;extern int notsc_setup (char *);
PATCH 25/48 i386: remove volatile in apic.c
In reply to Andi KleenFrom: Thomas Gleixner <[email protected]>
Remove the volatile in apic. We have a cpu_relax() in the wait loop. Fix a coding style issue while at it.
---
arch/i386/kernel/apic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/i386/kernel/apic.c +2 -2
@@ -315,7 +315,7 @@ static void __devinit setup_APIC_timer(v#define LAPIC_CAL_LOOPS (HZ/10) -static __initdata volatile int lapic_cal_loops =-1 ; +static __initdata int lapic_cal_loops =-1 ;static __initdata long lapic_cal_t1, lapic_cal_t2;static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2;
@@ -485,7 +485,7 @@ void __init setup_boot_APIC_clock(void)/* Let the interrupts run */ local_irq_enable (); -while (lapic_cal_loops <=LAPIC_CAL_LOOPS ) +while (lapic_cal_loops <=LAPIC_CAL_LOOPS )cpu_relax ();local_irq_disable ();
PATCH 26/48 i386: hpet assumes boot cpu is 0
In reply to Andi KleenFrom: Chris Wright <[email protected]>
I fixed this in x86_64. Looks like the kind of thing that will break voyager on i386.
---
arch/i386/kernel/hpet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/i386/kernel/hpet.c +1 -1
@@ -321,7 +321,7 @@ int __init hpet_enable(void)* Start hpet with the boot cpu mask and make it * global after the IO_APIC has been initialized. */ - hpet_clockevent.cpumask =cpumask_of_cpu (0 ); + hpet_clockevent.cpumask =cpumask_of_cpu (smp_processor_id ());clockevents_register_device (&hpet_clockevent); global_clock_event = &hpet_clockevent;return 1 ;
Re: [PATCH for review] [26/48] i386: hpet assumes boot cpu is 0
Quoted 5 lines · Andi Kleen
From: Chris Wright <[email protected]>
I fixed this in
x86_64. Looks like the kind of thing that will break voyager on i386.
All those Voyagers with hpet?
J
PATCH 27/48 i386: move PIT function declarations and constants to correct header file
In reply to Andi KleenFrom: Thomas Gleixner <[email protected]>
setup_pit_timer is declared in asm-i386/timer.h. Move it to the pit header file, so it can be used by x86_64 as well.
Move also the PIT constants.
---
arch/i386/kernel/i8253.c | 2 -- arch/i386/kernel/vmiclock.c | 1 + include/asm-i386/i8253.h | 7 +++++++ include/asm-i386/mach-default/io_ports.h | 5 ----- include/asm-i386/timer.h | 1 - 5 files changed, 8 insertions(+), 8 deletions(-)
arch/i386/kernel/i8253.c +0 -2
@@ -15,8 +15,6 @@#include <asm/io.h> #include <asm/timer.h> -#include "io_ports.h" -DEFINE_SPINLOCK (i8253_lock);EXPORT_SYMBOL (i8253_lock);
arch/i386/kernel/vmiclock.c +1 -0
@@ -32,6 +32,7 @@#include <asm/apicdef.h> #include <asm/apic.h> #include <asm/timer.h> +#include <asm/i8253.h> #include <irq_vectors.h> #include "io_ports.h"
include/asm-i386/i8253.h +7 -0
@@ -3,8 +3,15 @@#include <linux/clockchips.h> +/* i8253A PIT registers */ +#define PIT_MODE 0x43 +#define PIT_CH0 0x40 +#define PIT_CH2 0x42 +extern spinlock_t i8253_lock;extern struct clock_event_device *global_clock_event; +extern void setup_pit_timer (void ); +#endif /* __ASM_I8253_H__ */
include/asm-i386/mach-default/io_ports.h +0 -5
@@ -7,11 +7,6 @@#ifndef _MACH_IO_PORTS_H#define _MACH_IO_PORTS_H -/* i8253A PIT registers */ -#define PIT_MODE 0x43 -#define PIT_CH0 0x40 -#define PIT_CH2 0x42 -/* i8259A PIC registers */ #define PIC_MASTER_CMD 0x20#define PIC_MASTER_IMR 0x21
include/asm-i386/timer.h +0 -1
@@ -5,7 +5,6 @@#define TICK_SIZE (tick_nsec / 1000) -void setup_pit_timer (void );unsigned long native_calculate_cpu_khz (void );extern int timer_ack;
PATCH 28/48 i386: fix iounmap's use of vm_struct's size field
In reply to Andi KleenFrom: Jeremy Fitzhardinge <[email protected]>
get_vm_area always returns an area with an adjacent guard page. That guard page is included in vm_struct.size. iounmap uses vm_struct.size to determine how much address space needs to have change_page_attr applied to it, which will BUG if applied to the guard page.
This patch adds a helper function - get_vm_area_size() in linux/vmalloc.h - to return the actual size of a vm area, and uses it to make iounmap do the right thing. There are probably other places which should be using get_vm_area_size().
Thanks to Dave Young <[email protected]> for debugging the problem.
[ Andi, it wasn't clear to me whether x86_64 needs the same fix. ]
---
arch/i386/mm/ioremap.c | 2 +- include/linux/vmalloc.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
arch/i386/mm/ioremap.c +1 -1
@@ -196,7 +196,7 @@ void iounmap(volatile void __iomem *addr/* Reset the direct mapping. Can block */ if ((p->flags >>20 ) && p->phys_addr <virt_to_phys (high_memory) -1 ) {change_page_attr (virt_to_page (__va (p->phys_addr)), - p->size >>PAGE_SHIFT , +get_vm_area_size (p) >>PAGE_SHIFT ,PAGE_KERNEL );global_flush_tlb (); }
include/linux/vmalloc.h +7 -0
@@ -58,6 +58,13 @@ void vmalloc_sync_all(void);/* * Lowlevel-APIs (not for driver use!) */ + +static inline size_t get_vm_area_size (const struct vm_struct *area) +{ +/* return actual size without guard page */ +return area->size -PAGE_SIZE ; +} +extern struct vm_struct *get_vm_area (unsigned long size,unsigned long flags);extern struct vm_struct *__get_vm_area (unsigned long size,unsigned long flags,unsigned long start,unsigned long end);
PATCH 29/48 x86_64: arch/x86_64/kernel/aperture.c lower printk severity
In reply to Andi KleenFrom: Dan Aloni <[email protected]>
Users that use kernel log filtering (e.g. via syslogd or a proprietry method) wouldn't like to see warning prints that are not really warnings.
---
arch/x86_64/kernel/aperture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/kernel/aperture.c +1 -1
@@ -214,7 +214,7 @@ void __init iommu_hole_init(void)if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed ())return ; -printk ("Checking aperture...\n" ); +printk (KERN_INFO "Checking aperture...\n" ); fix =0 ;for (num =24 ; num <32 ; num++) {
PATCH 30/48 x86_64: arch/x86_64/kernel/e820.c lower printk severity
In reply to Andi KleenFrom: Dan Aloni <[email protected]>
---
arch/x86_64/kernel/e820.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/kernel/e820.c +1 -1
@@ -361,7 +361,7 @@ void __init e820_print_map(char *who)int i;for (i =0 ; i < e820.nr_map; i++) { -printk (" %s: %016Lx - %016Lx " , who, +printk (KERN_INFO " %s: %016Lx - %016Lx " , who, (unsigned long long ) e820.map[i].addr, (unsigned long long ) (e820.map[i].addr + e820.map[i].size));switch (e820.map[i].type) {
PATCH 31/48 i386: basic infrastructure support for AMD geode-class machines
In reply to Andi KleenFrom: Andres Salomon <[email protected]>
This builds upon the existing geode infrastructure, but adds southbridge support, some GPIO functions, and a header file (asm-i386/geode.h) with some useful GX/LX detection tests.
The majority of this code was written by Jordan Crouse.
---
arch/i386/kernel/Makefile | 1 arch/i386/kernel/geode.c | 155 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-i386/geode.h | 159 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 315 insertions(+)
arch/i386/kernel/Makefile +1 -0
@@ -41,6 +41,7 @@ obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o +obj-$(CONFIG_MGEODE_LX) += geode.o obj-$(CONFIG_VMI) += vmi.o vmiclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o
arch/i386/kernel/geode.c new file +155 -0
155 lines not on this page · raw message
include/asm-i386/geode.h new file +159 -0
159 lines not on this page · raw message
PATCH 32/48 i386: insert HPET firmware resource after PCI enumeration has completed
In reply to Andi KleenFrom: Aaron Durbin <[email protected]>
Insert HPET resources after pci probing has been completed in order to avoid resource conflicts with PCI resource reservation. With this change the HPET firmware resources will be identified, but it should also not cause issues when the HPET address falls on a BAR in a PCI device, and the PCI enumeration cannot reserve the resources.
---
arch/i386/kernel/acpi/boot.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
arch/i386/kernel/acpi/boot.c +36 -0
@@ -618,6 +618,8 @@ static int __init acpi_parse_sbf(struct#ifdef CONFIG_HPET_TIMER #include <asm/hpet.h> +static struct __initdata resource *hpet_res; +static int __init acpi_parse_hpet (struct acpi_table_header *table) {struct acpi_table_hpet *hpet_tbl;
@@ -638,8 +640,42 @@ static int __init acpi_parse_hpet(struct printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); +/* +* Allocate and initialize the HPET firmware resource for adding into +* the resource tree during the lateinit timeframe. +*/ +#define HPET_RESOURCE_NAME_SIZE 9 + hpet_res =alloc_bootmem (sizeof (*hpet_res) +HPET_RESOURCE_NAME_SIZE ); + +if (!hpet_res) +return 0 ; + +memset (hpet_res,0 ,sizeof (*hpet_res)); + hpet_res->name = (void *)&hpet_res[1 ]; + hpet_res->flags =IORESOURCE_MEM ; +snprintf ((char *)hpet_res->name,HPET_RESOURCE_NAME_SIZE ,"HPET %u" , + hpet_tbl->sequence); + + hpet_res->start = hpet_address; + hpet_res->end = hpet_address + (1 *1024 ) -1 ; + return 0; } + +/* +* hpet_insert_resource inserts the HPET resources used into the resource +* tree. +*/ +static __init int hpet_insert_resource (void ) +{ +if (!hpet_res) +return 1 ; + +return insert_resource (&iomem_resource, hpet_res); +} + +late_initcall (hpet_insert_resource); +#else #define acpi_parse_hpet NULL#endif
PATCH 33/48 i386: remove old IRQ balancing debug cruft
In reply to Andi KleenFrom: Stefan Richter <[email protected]>
Dead or misnamed CONFIG_BALANCED_IRQ_DEBUG found by Robert P. J. Day. It's not a Kconfig variable.
Since this debug code is ancient, I suggest to get rid of this misleading CONFIG_ macro by deleting all of this debug code.
---
arch/i386/kernel/io_apic.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-)
arch/i386/kernel/io_apic.c +2 -22
@@ -353,14 +353,6 @@ static void set_ioapic_affinity_irq(unsi# include <linux/slab.h> /* kmalloc() */ # include <linux/timer.h> /* time_after() */ -#ifdef CONFIG_BALANCED_IRQ_DEBUG -# define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) -# define Dprintk(x...) do { TDprintk(x); } while (0) -# else -# define TDprintk(x...) -# define Dprintk(x...) -# endif -#define IRQBALANCE_CHECK_ARCH -999#define MAX_BALANCED_IRQ_INTERVAL (5*HZ)#define MIN_BALANCED_IRQ_INTERVAL (HZ/2)
@@ -443,7 +435,7 @@ static inline void balance_irq(int cpu,static inline void rotate_irqs_among_cpus (unsigned long useful_load_threshold) {int i, j; -Dprintk ("Rotating IRQs among CPUs.\n" ); +for_each_online_cpu (i) {for (j =0 ; j <NR_IRQS ; j++) {if (!irq_desc[j].action)
@@ -560,19 +552,11 @@ tryanothercpu: max_loaded = tmp_loaded;/* processor */ imbalance = (max_cpu_irq - min_cpu_irq) /2 ; -Dprintk ("max_loaded cpu = %d\n" , max_loaded); -Dprintk ("min_loaded cpu = %d\n" , min_loaded); -Dprintk ("max_cpu_irq load = %ld\n" , max_cpu_irq); -Dprintk ("min_cpu_irq load = %ld\n" , min_cpu_irq); -Dprintk ("load imbalance = %lu\n" , imbalance); -/* if imbalance is less than approx 10% of max load, then * observe diminishing returns action. - quit */ -if (imbalance < (max_cpu_irq >>3 )) { -Dprintk ("Imbalance too trivial\n" ); +if (imbalance < (max_cpu_irq >>3 )) goto not_worth_the_effort; - } tryanotherirq:/* if we select an IRQ to move that can't go where we want, then
@@ -629,9 +613,6 @@ tryanotherirq:cpus_and (tmp, target_cpu_mask, allowed_mask);if (!cpus_empty (tmp)) { - -Dprintk ("irq = %d moved to cpu = %d\n" , - selected_irq, min_loaded);/* mark for change destination */ set_pending_irq (selected_irq,cpumask_of_cpu (min_loaded));
@@ -651,7 +632,6 @@ not_worth_the_effort:*/ balanced_irq_interval =min ((long )MAX_BALANCED_IRQ_INTERVAL , balanced_irq_interval +BALANCED_IRQ_MORE_DELTA ); -Dprintk ("IRQ worth rotating not found\n" );return ; }
PATCH 34/48 i386: Update alignment when 4K stacks are used.
In reply to Andi KleenFrom: "Robert P. J. Day" <[email protected]>
---
it's not clear from MAINTAINERS who's responsible for something this
generic.
--- arch/i386/kernel/irq.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
arch/i386/kernel/irq.c +2 -6
@@ -149,15 +149,11 @@ fastcall unsigned int do_IRQ(struct pt_r#ifdef CONFIG_4KSTACKS -/* -* These should really be __section__(".bss.page_aligned") as well, but -* gcc's 3.0 and earlier don't handle that correctly. -*/ static char softirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); + __attribute__((__section__(".bss.page_aligned"))); static char hardirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); + __attribute__((__section__(".bss.page_aligned")));/* * allocate per-cpu stacks for hardirq and for softirq processing
PATCH 35/48 x86_64: remove __smp_alt* sections
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
Leftovers from the removal of the more general (but abandoned) SMP alternatives.
arch/x86_64/kernel/vmlinux.lds.S | 9 --------- 1 file changed, 9 deletions(-)
arch/x86_64/kernel/vmlinux.lds.S +0 -9
@@ -141,20 +141,11 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); __smp_alt_begin = .; - __smp_alt_instructions = .; - .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { - *(.smp_altinstructions) - } - __smp_alt_instructions_end = .; - . = ALIGN(8); __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { *(.smp_locks) } __smp_locks_end = .; - .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { - *(.smp_altinstr_replacement) - } . = ALIGN(4096); __smp_alt_end = .;
PATCH 36/48 x86_64: k8topology add family 10h and 11h PCI IDs
In reply to Andi KleenFrom: "Joachim Deguara" <[email protected]>
This just adds the PCI IDs of AMD's family 10h and 11h CPU's northbridges to k8topology discovery.
--
--- arch/x86_64/mm/k8topology.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/x86_64/mm/k8topology.c +6 -2
@@ -28,11 +28,15 @@ static __init int find_northbridge(void)u32 header; header =read_pci_config (0 , num,0 ,0x00 ); -if (header != (PCI_VENDOR_ID_AMD | (0x1100 <<16 ))) +if (header != (PCI_VENDOR_ID_AMD | (0x1100 <<16 )) && + header != (PCI_VENDOR_ID_AMD | (0x1200 <<16 )) && + header != (PCI_VENDOR_ID_AMD | (0x1300 <<16 )) )continue ; header =read_pci_config (0 , num,1 ,0x00 ); -if (header != (PCI_VENDOR_ID_AMD | (0x1101 <<16 ))) +if (header != (PCI_VENDOR_ID_AMD | (0x1101 <<16 )) && + header != (PCI_VENDOR_ID_AMD | (0x1201 <<16 )) && + header != (PCI_VENDOR_ID_AMD | (0x1301 <<16 )) )continue ;return num; }
PATCH 37/48 x86_64: make k8topology multi-core aware
In reply to Andi KleenFrom: "Joachim Deguara" <[email protected]>
This makes k8topology multicore aware instead of limited to signle- and dual-core CPUs. It uses the CPUID to be more future proof.
--
--- arch/x86_64/mm/k8topology.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
arch/x86_64/mm/k8topology.c +7 -6
@@ -48,12 +48,12 @@ int __init k8_scan_nodes(unsigned long s {unsigned long prevbase;struct bootnode nodes[8 ]; -int nodeid, i, nb; +int nodeid, i, j, nb;unsigned char nodeids[8 ];int found =0 ;u32 reg;unsigned numnodes; -unsigned dualcore =0 ; +unsigned num_cores;if (!early_pci_allowed ())return -1 ;
@@ -64,6 +64,9 @@ int __init k8_scan_nodes(unsigned long sprintk (KERN_INFO "Scanning NUMA topology in Northbridge %d\n" , nb); + num_cores = (cpuid_ecx (0x80000008 ) &0xff ) +1 ; +printk (KERN_INFO "CPU has %d num_cores\n" , num_cores); + reg =read_pci_config (0 , nb,0 ,0x60 ); numnodes = ((reg >>4 ) &0xF ) +1 ;if (numnodes <=1 )
@@ -77,8 +80,6 @@ int __init k8_scan_nodes(unsigned long sunsigned long base,limit;u32 nodeid; -/* Undefined before E stepping, but hopefully 0 */ - dualcore |= ((read_pci_config (0 , nb,3 ,0xe8 ) >>12 ) &3 ) ==1 ; base =read_pci_config (0 , nb,1 ,0x40 + i*8 ); limit =read_pci_config (0 , nb,1 ,0x44 + i*8 );
@@ -174,8 +175,8 @@ int __init k8_scan_nodes(unsigned long sfor (i =0 ; i <8 ; i++) {if (nodes[i].start != nodes[i].end) { nodeid = nodeids[i]; - apicid_to_node[nodeid << dualcore] = i; - apicid_to_node[(nodeid << dualcore) + dualcore] = i; +for (j =0 ; j < num_cores; j++) + apicid_to_node[(nodeid * num_cores) + j] = i;setup_node_bootmem (i, nodes[i].start, nodes[i].end); } }
PATCH 38/48 x86_64: Put allocated ELF notes in read-only data segment
In reply to Andi KleenFrom: Roland McGrath <[email protected]>
This changes the x86_64 linker script to use the asm-generic NOTES macro so that ELF note sections with SHF_ALLOC set are linked into the kernel image along with other read-only data. The PT_NOTE also points to their location.
This paves the way for putting useful build-time information into ELF notes that can be found easily later in a kernel memory dump.
--- arch/x86_64/kernel/vmlinux.lds.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86_64/kernel/vmlinux.lds.S +3 -1
@@ -48,7 +48,9 @@ SECTIONS __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } __stop___ex_table = .; - BUG_TABLE + NOTES :text :note + + BUG_TABLE :text RODATA