From: Andi Kleen Fix a few issues on x86-64 for 2.6.4rc1. The 32bit emulation used 4GB/3 for the mmap break. This actually gave programs less sbrk space than with a standard 32bit kernel. Move the 32bit mmap break to 0xc5000000. Uses the correct gcc option to optimize for Prescott now (requires a very new mainline gcc) Also merge the i386 sched_clock(). I hope this will fix some interactivity problems with the scheduler. - Change initializer to new style (Arnd Bergmann) - Remove 2 sibling limit in HT support (from i386) - Always log RIP in MCE records even when not exact - Move 32bit program task break up to 0xc5000000 by default - Use -march=prescott for Prescott optimized kernel if possible - Don't divide by zero with report_lost_ticks on and HPET off - Merge preempt/smp/debug_pagealloc oops printing from i386 - Add pfn_to_nid() - Merge more accurate sched_clock from i386 - Remove traces of debugging code in mce.c - Update defconfig --- arch/x86_64/Makefile | 2 +- arch/x86_64/defconfig | 14 ++++++++------ arch/x86_64/kernel/i8259.c | 2 +- arch/x86_64/kernel/mce.c | 6 ++++-- arch/x86_64/kernel/setup.c | 3 +-- arch/x86_64/kernel/time.c | 30 +++++++++++++++++++++++------- arch/x86_64/kernel/traps.c | 15 +++++++++++++++ include/asm-x86_64/mmzone.h | 2 ++ include/asm-x86_64/processor.h | 2 +- 9 files changed, 56 insertions(+), 20 deletions(-) diff -puN arch/x86_64/defconfig~x86_64-update arch/x86_64/defconfig --- 25/arch/x86_64/defconfig~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/defconfig 2004-02-28 16:54:54.000000000 -0800 @@ -27,6 +27,7 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=18 +# CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set @@ -106,6 +107,7 @@ CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y # CONFIG_ACPI_RELAXED_AML is not set +# CONFIG_X86_PM_TIMER is not set # # CPU Frequency scaling @@ -119,7 +121,6 @@ CONFIG_PCI=y CONFIG_PCI_DIRECT=y # CONFIG_PCI_LEGACY_PROC is not set # CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set # # Executable file formats / Emulations @@ -168,6 +169,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y CONFIG_LBD=y +# CONFIG_DCSSBLK is not set # # ATA/ATAPI/MFM/RLL support @@ -306,7 +308,7 @@ CONFIG_FUSION_MAX_SGE=40 # CONFIG_FUSION_CTL is not set # -# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# IEEE 1394 (FireWire) support # # CONFIG_IEEE1394 is not set @@ -489,7 +491,7 @@ CONFIG_TIGON3=y # # ISDN subsystem # -# CONFIG_ISDN_BOOL is not set +# CONFIG_ISDN is not set # # Telephony Support @@ -562,7 +564,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # Mice @@ -718,7 +721,6 @@ CONFIG_ISO9660_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_HUGETLBFS=y @@ -731,6 +733,7 @@ CONFIG_RAMFS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -761,7 +764,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # diff -puN arch/x86_64/kernel/i8259.c~x86_64-update arch/x86_64/kernel/i8259.c --- 25/arch/x86_64/kernel/i8259.c~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/i8259.c 2004-02-28 16:54:54.000000000 -0800 @@ -423,7 +423,7 @@ static struct sysdev_class timer_sysclas static struct sys_device device_timer = { .id = 0, - .cls &timer_sysclass, + .cls = &timer_sysclass, }; static int __init init_timer_sysfs(void) diff -puN arch/x86_64/kernel/mce.c~x86_64-update arch/x86_64/kernel/mce.c --- 25/arch/x86_64/kernel/mce.c~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/mce.c 2004-02-28 16:54:54.000000000 -0800 @@ -73,7 +73,9 @@ static void print_mce(struct mce *m) printk("CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", m->cpu, m->mcgstatus, m->bank, m->status); if (m->rip) { - printk("RIP %02x:<%016Lx> ", m->cs, m->rip); + printk("RIP%s %02x:<%016Lx> ", + !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", + m->cs, m->rip); if (m->cs == __KERNEL_CS) print_symbol("{%s}", m->rip); printk("\n"); @@ -133,7 +135,7 @@ void do_machine_check(struct pt_regs * r return; if (!(m.mcgstatus & MCG_STATUS_RIPV)) kill_it = 1; - if (regs && (m.mcgstatus & MCG_STATUS_EIPV)) { + if (regs) { m.rip = regs->rip; m.cs = regs->cs; } diff -puN arch/x86_64/kernel/setup.c~x86_64-update arch/x86_64/kernel/setup.c --- 25/arch/x86_64/kernel/setup.c~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/setup.c 2004-02-28 16:54:54.000000000 -0800 @@ -610,8 +610,7 @@ static void __init detect_ht(void) * At this point we only support two siblings per * processor package. */ -#define NR_SIBLINGS 2 - if (smp_num_siblings != NR_SIBLINGS) { + if (smp_num_siblings > NR_CPUS) { printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); smp_num_siblings = 1; return; diff -puN arch/x86_64/kernel/time.c~x86_64-update arch/x86_64/kernel/time.c --- 25/arch/x86_64/kernel/time.c~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/time.c 2004-02-28 16:54:54.000000000 -0800 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -353,11 +354,11 @@ static irqreturn_t timer_interrupt(int i } if (lost) { - if (report_lost_ticks) + if (report_lost_ticks) { printk(KERN_WARNING "time.c: Lost %ld timer " - "tick(s)! (rip %016lx)\n", - (offset - vxtime.last) / hpet_tick - 1, - regs->rip); + "tick(s)! ", lost); + print_symbol("rip %s)\n", regs->rip); + } jiffies += lost; } @@ -399,8 +400,19 @@ static irqreturn_t timer_interrupt(int i return IRQ_HANDLED; } -/* RED-PEN: calculation is done in 32bits with multiply for performance - and could overflow, it may be better (but slower)to use an 64bit division. */ +static unsigned int cyc2ns_scale; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_mhz) +{ + cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + unsigned long long sched_clock(void) { unsigned long a = 0; @@ -420,7 +432,7 @@ unsigned long long sched_clock(void) purposes. */ rdtscll(a); - return (a * vxtime.tsc_quot) >> 32; + return cycles_2_ns(a); } unsigned long get_cmos_time(void) @@ -527,6 +539,8 @@ static int time_cpufreq_notifier(struct vxtime.tsc_quot = (1000L << 32) / cpu_khz; } + set_cyc2ns_scale(cpu_khz_ref / 1000); + return 0; } @@ -725,6 +739,8 @@ void __init time_init(void) rdtscll_sync(&vxtime.last_tsc); setup_irq(0, &irq0); + set_cyc2ns_scale(cpu_khz / 1000); + #ifdef CONFIG_CPU_FREQ cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); diff -puN arch/x86_64/kernel/traps.c~x86_64-update arch/x86_64/kernel/traps.c --- 25/arch/x86_64/kernel/traps.c~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/traps.c 2004-02-28 16:54:54.000000000 -0800 @@ -354,9 +354,24 @@ void oops_end(void) void __die(const char * str, struct pt_regs * regs, long err) { + int nl = 0; static int die_counter; printk(KERN_EMERG "%s: %04lx [%u]\n", str, err & 0xffff,++die_counter); notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); + nl = 1; +#endif +#ifdef CONFIG_SMP + printk("SMP "); + nl = 1; +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); + nl = 1; +#endif + if (nl) + printk("\n"); show_registers(regs); /* Executive summary in case the oops scrolled away */ printk("RIP "); diff -puN arch/x86_64/Makefile~x86_64-update arch/x86_64/Makefile --- 25/arch/x86_64/Makefile~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/arch/x86_64/Makefile 2004-02-28 16:54:54.000000000 -0800 @@ -38,7 +38,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .c LDFLAGS_vmlinux := -e stext cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,) -cflags-$(CONFIG_MPSC) += $(call check_gcc,-march=pentium4,) +cflags-$(CONFIG_MPSC) += $(call check_gcc,-march=prescott,) CFLAGS += $(cflags-y) CFLAGS += -mno-red-zone diff -puN include/asm-x86_64/mmzone.h~x86_64-update include/asm-x86_64/mmzone.h --- 25/include/asm-x86_64/mmzone.h~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/include/asm-x86_64/mmzone.h 2004-02-28 16:54:54.000000000 -0800 @@ -31,6 +31,8 @@ static inline __attribute__((pure)) int return nid; } +#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT) + #define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr)) #define NODE_DATA(nid) (node_data[nid]) diff -puN include/asm-x86_64/processor.h~x86_64-update include/asm-x86_64/processor.h --- 25/include/asm-x86_64/processor.h~x86_64-update 2004-02-28 16:54:54.000000000 -0800 +++ 25-akpm/include/asm-x86_64/processor.h 2004-02-28 16:54:54.000000000 -0800 @@ -173,7 +173,7 @@ static inline void clear_in_cr4 (unsigne * space during mmap's. */ #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) -#define TASK_UNMAPPED_32 (PAGE_ALIGN(IA32_PAGE_OFFSET / 3)) +#define TASK_UNMAPPED_32 (PAGE_ALIGN(0xc5000000)) #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) #define TASK_UNMAPPED_BASE \ (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) _