From: Mark Huang Date: Sun, 12 Sep 2004 03:11:14 +0000 (+0000) Subject: Merge LKCD 2.6 tree at :pserver:anonymous@cvs.sourceforge.net:/cvsroot/lkcd/2.6 as... X-Git-Tag: before-enable-kexec-patch~97 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=4787a2b4442f377fc7a90c965fdbb4e84d3fe8e7;p=linux-2.6.git Merge LKCD 2.6 tree at :pserver:anonymous@cvs.sourceforge.net:/cvsroot/lkcd/2.6 as of 20040910 --- diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d7b81890c..15b003b50 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1249,6 +1249,58 @@ source "arch/i386/oprofile/Kconfig" menu "Kernel hacking" +config CRASH_DUMP + tristate "Crash dump support (EXPERIMENTAL)" + depends on EXPERIMENTAL + default n + ---help--- + Say Y here to enable saving an image of system memory when a panic + or other error occurs. Dumps can also be forced with the SysRq+d + key if MAGIC_SYSRQ is enabled. + +config CRASH_DUMP_BLOCKDEV + tristate "Crash dump block device driver" + depends on CRASH_DUMP + help + Say Y to allow saving crash dumps directly to a disk device. + +config CRASH_DUMP_NETDEV + tristate "Crash dump network device driver" + depends on CRASH_DUMP + help + Say Y to allow saving crash dumps over a network device. + +config CRASH_DUMP_MEMDEV + bool "Crash dump staged memory driver" + depends on CRASH_DUMP + help + Say Y to allow intermediate saving crash dumps in spare + memory pages which would then be written out to disk + later. + +config CRASH_DUMP_SOFTBOOT + bool "Save crash dump across a soft reboot" + depends on CRASH_DUMP_MEMDEV + help + Say Y to allow a crash dump to be preserved in memory + pages across a soft reboot and written out to disk + thereafter. For this to work, CRASH_DUMP must be + configured as part of the kernel (not as a module). + +config CRASH_DUMP_COMPRESS_RLE + tristate "Crash dump RLE compression" + depends on CRASH_DUMP + help + Say Y to allow saving dumps with Run Length Encoding compression. + +config CRASH_DUMP_COMPRESS_GZIP + tristate "Crash dump GZIP compression" + select ZLIB_INFLATE + select ZLIB_DEFLATE + depends on CRASH_DUMP + help + Say Y to allow saving dumps with Gnu Zip compression. + config DEBUG_KERNEL bool "Kernel debugging" help diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index d70853d99..feb561e9a 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -102,3 +102,4 @@ zlilo: $(BOOTIMAGE) install: $(BOOTIMAGE) sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" + if [ -f init/kerntypes.o ]; then cp init/kerntypes.o $(INSTALL_PATH)/Kerntypes; fi diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index fd4bf7f42..5a50c536d 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; @@ -201,3 +203,20 @@ EXPORT_SYMBOL(ist_info); EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL_GPL(empty_zero_page); + +#ifdef CONFIG_CRASH_DUMP_MODULE +#ifdef CONFIG_SMP +extern irq_desc_t irq_desc[NR_IRQS]; +extern unsigned long irq_affinity[NR_IRQS]; +extern void stop_this_cpu(void *); +EXPORT_SYMBOL(irq_desc); +EXPORT_SYMBOL(irq_affinity); +EXPORT_SYMBOL(stop_this_cpu); +EXPORT_SYMBOL(dump_send_ipi); +#endif +extern int pfn_is_ram(unsigned long); +EXPORT_SYMBOL(pfn_is_ram); +#ifdef ARCH_HAS_NMI_WATCHDOG +EXPORT_SYMBOL(touch_nmi_watchdog); +#endif +#endif diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 8e388b214..7a2cdb557 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -486,6 +487,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) bust_spinlocks(1); printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip); show_registers(regs); + dump("NMI Watchdog detected LOCKUP", regs); printk("console shuts up ...\n"); console_silent(); spin_unlock(&nmi_print_lock); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 375fd0761..c0675d559 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -656,6 +656,8 @@ static inline void copy_edd(void) */ #define LOWMEMSIZE() (0x9f000) +unsigned long crashdump_addr = 0xdeadbeef; + static void __init parse_cmdline_early (char ** cmdline_p) { char c = ' ', *to = command_line, *from = saved_command_line; @@ -809,6 +811,9 @@ static void __init parse_cmdline_early (char ** cmdline_p) if (c == ' ' && !memcmp(from, "highmem=", 8)) highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; + if (c == ' ' && !memcmp(from, "crashdump=", 10)) + crashdump_addr = memparse(from+10, &from); + c = *(from++); if (!c) break; @@ -1260,6 +1265,10 @@ __setup("noreplacement", noreplacement_setup); static char * __init machine_specific_memory_setup(void); +#ifdef CONFIG_CRASH_DUMP_SOFTBOOT +extern void crashdump_reserve(void); +#endif + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1356,6 +1365,10 @@ void __init setup_arch(char **cmdline_p) #endif +#ifdef CONFIG_CRASH_DUMP_SOFTBOOT + crashdump_reserve(); /* Preserve crash dump state from prev boot */ +#endif + dmi_scan_machine(); #ifdef CONFIG_X86_GENERICARCH diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index c88dcbe54..2772f1852 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -143,6 +144,13 @@ inline void __send_IPI_shortcut(unsigned int shortcut, int vector) */ cfg = __prepare_ICR(shortcut, vector); + if (vector == DUMP_VECTOR) { + /* + * Setup DUMP IPI to be delivered as an NMI + */ + cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI; + } + /* * Send the IPI. The write to APIC_ICR fires this off. */ @@ -220,7 +228,13 @@ inline void send_IPI_mask_sequence(cpumask_t mask, int vector) * program the ICR */ cfg = __prepare_ICR(0, vector); - + + if (vector == DUMP_VECTOR) { + /* + * Setup DUMP IPI to be delivered as an NMI + */ + cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI; + } /* * Send the IPI. The write to APIC_ICR fires this off. */ @@ -456,6 +470,11 @@ void flush_tlb_all(void) on_each_cpu(do_flush_tlb_all, NULL, 1, 1); } +void dump_send_ipi(void) +{ + send_IPI_allbutself(DUMP_VECTOR); +} + /* * this function sends a 'reschedule' IPI to another CPU. * it goes straight through and wastes no time serializing @@ -542,7 +561,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, return 0; } -static void stop_this_cpu (void * dummy) +void stop_this_cpu (void * dummy) { /* * Remove this CPU: @@ -568,6 +587,8 @@ void smp_send_stop(void) local_irq_enable(); } +EXPORT_SYMBOL(smp_send_stop); + /* * Reschedule call back. Nothing to do, * all the work is done automatically when @@ -603,4 +624,3 @@ asmlinkage void smp_call_function_interrupt(void) atomic_inc(&call_data->finished); } } - diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 2703da6ad..da766543f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef CONFIG_EISA #include @@ -324,6 +325,7 @@ void die(const char * str, struct pt_regs * regs, long err) show_registers(regs); if (netdump_func) netdump_func(regs); + dump((char *)str, regs); bust_spinlocks(0); die_owner = -1; spin_unlock_irq(&die_lock); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 2fc263ce4..5cd4a3981 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -93,6 +93,13 @@ int page_is_ram(unsigned long pagenr) return 0; } +/* To enable modules to check if a page is in RAM */ +int pfn_is_ram(unsigned long pfn) +{ + return (page_is_ram(pfn)); +} + + pte_t *kmap_pte; EXPORT_SYMBOL(kmap_pte); diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index a67fd8afc..6ead7ff3b 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -15,4 +15,4 @@ $(obj)/image: vmlinux FORCE install: $(CONFIGURE) $(obj)/image sh -x $(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ - System.map Kerntypes "$(INSTALL_PATH)" + System.map init/kerntypes.o "$(INSTALL_PATH)" diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh index 278a8139c..860bebc1b 100644 --- a/arch/s390/boot/install.sh +++ b/arch/s390/boot/install.sh @@ -16,7 +16,8 @@ # $1 - kernel version # $2 - kernel image file # $3 - kernel map file -# $4 - default install path (blank if root directory) +# $4 - kernel type file +# $5 - default install path (blank if root directory) # # User may have a custom install script @@ -26,13 +27,22 @@ if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi # Default install - same as make zlilo -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old +if [ -f $5/vmlinuz ]; then + mv $5/vmlinuz $5/vmlinuz.old fi -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old +if [ -f $5/System.map ]; then + mv $5/System.map $5/System.old fi -cat $2 > $4/vmlinuz -cp $3 $4/System.map +if [ -f $5/Kerntypes ]; then + mv $5/Kerntypes $5/Kerntypes.old +fi + +cat $2 > $5/vmlinuz +cp $3 $5/System.map + +# copy the kernel type file if it exists +if [ -f $4 ]; then + cp $4 $5/Kerntypes +fi diff --git a/drivers/Makefile b/drivers/Makefile index 847d2c1ed..d5406c3a0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -50,4 +50,5 @@ obj-$(CONFIG_ISDN) += isdn/ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ +obj-$(CONFIG_CRASH_DUMP) += dump/ obj-y += firmware/ diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h index 258481c33..ca46a62e4 100644 --- a/include/asm-i386/kmap_types.h +++ b/include/asm-i386/kmap_types.h @@ -31,7 +31,8 @@ enum km_type { KM_SOFTIRQ1, KM_NETDUMP, KM_UNUSED, - KM_TYPE_NR + KM_TYPE_NR, + KM_DUMP }; #endif diff --git a/include/asm-i386/mach-default/irq_vectors.h b/include/asm-i386/mach-default/irq_vectors.h index 881c63ca6..0bcc6f1ad 100644 --- a/include/asm-i386/mach-default/irq_vectors.h +++ b/include/asm-i386/mach-default/irq_vectors.h @@ -48,6 +48,7 @@ #define INVALIDATE_TLB_VECTOR 0xfd #define RESCHEDULE_VECTOR 0xfc #define CALL_FUNCTION_VECTOR 0xfb +#define DUMP_VECTOR 0xfa #define THERMAL_APIC_VECTOR 0xf0 /* diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 88c461e5e..bd8fa4cd9 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -37,6 +37,7 @@ extern int smp_num_siblings; extern cpumask_t cpu_sibling_map[]; extern void smp_flush_tlb(void); +extern void dump_send_ipi(void); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 041263ab1..5cb08ee54 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -24,6 +24,7 @@ #define MICROCODE_MINOR 184 #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ #define MPT_MINOR 220 +#define CRASH_DUMP_MINOR 230 /* LKCD */ #define MISC_DYNAMIC_MINOR 255 #define TUN_MINOR 200 diff --git a/include/linux/sched.h b/include/linux/sched.h index b922e873e..c22973fab 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -94,6 +94,7 @@ extern unsigned long avenrun[]; /* Load averages */ extern int nr_threads; extern int last_pid; DECLARE_PER_CPU(unsigned long, process_counts); +DECLARE_PER_CPU(struct runqueue, runqueues); extern int nr_processes(void); extern unsigned long nr_running(void); extern unsigned long nr_uninterruptible(void); @@ -733,6 +734,83 @@ extern int idle_cpu(int cpu); void yield(void); +/* + * These are the runqueue data structures: + */ +typedef struct runqueue runqueue_t; + +#ifdef CONFIG_CKRM_CPU_SCHEDULE +#include +#endif + +#ifdef CONFIG_CKRM_CPU_SCHEDULE + +/** + * if belong to different class, compare class priority + * otherwise compare task priority + */ +#define TASK_PREEMPTS_CURR(p, rq) \ + (((p)->cpu_class != (rq)->curr->cpu_class) && ((rq)->curr != (rq)->idle))? class_preempts_curr((p),(rq)->curr) : ((p)->prio < (rq)->curr->prio) +#else +#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long)) +struct prio_array { + unsigned int nr_active; + unsigned long bitmap[BITMAP_SIZE]; + struct list_head queue[MAX_PRIO]; +}; +#define rq_active(p,rq) (rq->active) +#define rq_expired(p,rq) (rq->expired) +#define ckrm_rebalance_tick(j,this_cpu) do {} while (0) +#define TASK_PREEMPTS_CURR(p, rq) \ + ((p)->prio < (rq)->curr->prio) +#endif + +/* + * This is the main, per-CPU runqueue data structure. + * + * Locking rule: those places that want to lock multiple runqueues + * (such as the load balancing or the thread migration code), lock + * acquire operations must be ordered by ascending &runqueue. + */ +struct runqueue { + spinlock_t lock; + + /* + * nr_running and cpu_load should be in the same cacheline because + * remote CPUs use both these fields when doing load calculation. + */ + unsigned long nr_running; +#if defined(CONFIG_SMP) + unsigned long cpu_load; +#endif + unsigned long long nr_switches, nr_preempt; + unsigned long expired_timestamp, nr_uninterruptible; + unsigned long long timestamp_last_tick; + task_t *curr, *idle; + struct mm_struct *prev_mm; +#ifdef CONFIG_CKRM_CPU_SCHEDULE + unsigned long ckrm_cpu_load; + struct classqueue_struct classqueue; +#else + prio_array_t *active, *expired, arrays[2]; +#endif + int best_expired_prio; + atomic_t nr_iowait; + +#ifdef CONFIG_SMP + struct sched_domain *sd; + + /* For active balancing */ + int active_balance; + int push_cpu; + + task_t *migration_thread; + struct list_head migration_queue; +#endif + struct list_head hold_queue; + int idle_tokens; +}; + /* * The default (Linux) execution domain. */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 7b0218e86..7715c2e8a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -134,6 +134,7 @@ enum KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */ KERN_HZ_TIMER=65, /* int: hz timer on or off */ KERN_VSHELPER=66, /* string: path to vshelper policy agent */ + KERN_DUMP=67, /* dir: dump parameters */ }; diff --git a/init/Makefile b/init/Makefile index 767b47b4f..75aa6626b 100644 --- a/init/Makefile +++ b/init/Makefile @@ -9,6 +9,9 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o +extra-$(subst m,y,$(CONFIG_CRASH_DUMP)) += kerntypes.o +CFLAGS_kerntypes.o := -gstabs + # files to be removed upon make clean clean-files := ../include/linux/compile.h diff --git a/init/main.c b/init/main.c index 5c3a795b7..e93d25685 100644 --- a/init/main.c +++ b/init/main.c @@ -108,6 +108,16 @@ extern void tc_init(void); enum system_states system_state; EXPORT_SYMBOL(system_state); +/* + * The kernel_magic value represents the address of _end, which allows + * namelist tools to "match" each other respectively. That way a tool + * that looks at /dev/mem can verify that it is using the right System.map + * file -- if kernel_magic doesn't equal the namelist value of _end, + * something's wrong. + */ +extern unsigned long _end; +unsigned long *kernel_magic = &_end; + /* * Boot command-line arguments */ diff --git a/init/version.c b/init/version.c index d8878ae6c..e027a09d2 100644 --- a/init/version.c +++ b/init/version.c @@ -11,6 +11,7 @@ #include #include #include +#include #define version(a) Version_ ## a #define version_string(a) version(a) @@ -31,3 +32,6 @@ EXPORT_SYMBOL(system_utsname); const char *linux_banner = "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; + +const char *LINUX_COMPILE_VERSION_ID = __stringify(LINUX_COMPILE_VERSION_ID); +LINUX_COMPILE_VERSION_ID_TYPE; diff --git a/kernel/panic.c b/kernel/panic.c index e3470b2c7..290bf0d1e 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -19,12 +19,17 @@ #include #include #include +#ifdef CONFIG_KEXEC +#include +#endif int panic_timeout; int panic_on_oops; int tainted; +void (*dump_function_ptr)(const char *, const struct pt_regs *) = 0; EXPORT_SYMBOL(panic_timeout); +EXPORT_SYMBOL(dump_function_ptr); struct notifier_block *panic_notifier_list; @@ -62,6 +67,7 @@ NORET_TYPE void panic(const char * fmt, ...) va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); + printk(KERN_EMERG "Kernel panic: %s\n",buf); if (netdump_func) BUG(); @@ -73,20 +79,30 @@ NORET_TYPE void panic(const char * fmt, ...) sys_sync(); bust_spinlocks(0); + notifier_call_chain(&panic_notifier_list, 0, buf); + #ifdef CONFIG_SMP smp_send_stop(); #endif - notifier_call_chain(&panic_notifier_list, 0, buf); - - if (panic_timeout > 0) - { + if (panic_timeout > 0) { int i; /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); +#ifdef CONFIG_KEXEC +{ + struct kimage *image; + image = xchg(&kexec_image, 0); + if (image) { + printk(KERN_EMERG "by starting a new kernel ..\n"); + mdelay(panic_timeout*1000); + machine_kexec(image); + } + } +#endif for (i = 0; i < panic_timeout; i++) { touch_nmi_watchdog(); mdelay(1000); diff --git a/kernel/sched.c b/kernel/sched.c index fa04c39c8..e9c48e425 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -52,6 +52,10 @@ #define cpu_to_node_mask(cpu) (cpu_online_map) #endif +/* used to soft spin in sched while dump is in progress */ +unsigned long dump_oncpu; +EXPORT_SYMBOL(dump_oncpu); + /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], @@ -181,84 +185,7 @@ static unsigned int task_timeslice(task_t *p) #define task_hot(p, now, sd) ((now) - (p)->timestamp < (sd)->cache_hot_time) -/* - * These are the runqueue data structures: - */ -typedef struct runqueue runqueue_t; - -#ifdef CONFIG_CKRM_CPU_SCHEDULE -#include -#endif - -#ifdef CONFIG_CKRM_CPU_SCHEDULE - -/** - * if belong to different class, compare class priority - * otherwise compare task priority - */ -#define TASK_PREEMPTS_CURR(p, rq) \ - (((p)->cpu_class != (rq)->curr->cpu_class) && ((rq)->curr != (rq)->idle))? class_preempts_curr((p),(rq)->curr) : ((p)->prio < (rq)->curr->prio) -#else -#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long)) -struct prio_array { - unsigned int nr_active; - unsigned long bitmap[BITMAP_SIZE]; - struct list_head queue[MAX_PRIO]; -}; -#define rq_active(p,rq) (rq->active) -#define rq_expired(p,rq) (rq->expired) -#define ckrm_rebalance_tick(j,this_cpu) do {} while (0) -#define TASK_PREEMPTS_CURR(p, rq) \ - ((p)->prio < (rq)->curr->prio) -#endif - -/* - * This is the main, per-CPU runqueue data structure. - * - * Locking rule: those places that want to lock multiple runqueues - * (such as the load balancing or the thread migration code), lock - * acquire operations must be ordered by ascending &runqueue. - */ -struct runqueue { - spinlock_t lock; - - /* - * nr_running and cpu_load should be in the same cacheline because - * remote CPUs use both these fields when doing load calculation. - */ - unsigned long nr_running; -#if defined(CONFIG_SMP) - unsigned long cpu_load; -#endif - unsigned long long nr_switches, nr_preempt; - unsigned long expired_timestamp, nr_uninterruptible; - unsigned long long timestamp_last_tick; - task_t *curr, *idle; - struct mm_struct *prev_mm; -#ifdef CONFIG_CKRM_CPU_SCHEDULE - unsigned long ckrm_cpu_load; - struct classqueue_struct classqueue; -#else - prio_array_t *active, *expired, arrays[2]; -#endif - int best_expired_prio; - atomic_t nr_iowait; - -#ifdef CONFIG_SMP - struct sched_domain *sd; - - /* For active balancing */ - int active_balance; - int push_cpu; - - task_t *migration_thread; - struct list_head migration_queue; -#endif - struct list_head hold_queue; - int idle_tokens; -}; - -static DEFINE_PER_CPU(struct runqueue, runqueues); +DEFINE_PER_CPU(struct runqueue, runqueues); #define for_each_domain(cpu, domain) \ for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent) @@ -1952,6 +1879,15 @@ nextgroup: 100*max_load <= sd->imbalance_pct*this_load) goto out_balanced; + /* + * If crash dump is in progress, this other cpu's + * need to wait until it completes. + * NB: this code is optimized away for kernels without + * dumping enabled. + */ + if (unlikely(dump_oncpu)) + goto dump_scheduling_disabled; + /* * We're trying to get all the cpus to the average_load, so we don't * want to push ourselves above the average load, nor do we wish to @@ -2771,6 +2707,16 @@ switch_tasks: preempt_enable_no_resched(); if (test_thread_flag(TIF_NEED_RESCHED)) goto need_resched; + + return; + + dump_scheduling_disabled: + /* allow scheduling only if this is the dumping cpu */ + if (dump_oncpu != smp_processor_id()+1) { + while (dump_oncpu) + cpu_relax(); + } + return; } EXPORT_SYMBOL(schedule); diff --git a/mm/bootmem.c b/mm/bootmem.c index 966135b90..1c6773721 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -26,6 +26,7 @@ */ unsigned long max_low_pfn; unsigned long min_low_pfn; +EXPORT_SYMBOL(min_low_pfn); unsigned long max_pfn; EXPORT_SYMBOL(max_pfn); /* This is exported so diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f2fbdc430..072d1380c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -47,6 +47,11 @@ int sysctl_lower_zone_protection = 0; EXPORT_SYMBOL(totalram_pages); EXPORT_SYMBOL(nr_swap_pages); +#ifdef CONFIG_CRASH_DUMP_MODULE +/* This symbol has to be exported to use 'for_each_pgdat' macro by modules. */ +EXPORT_SYMBOL(pgdat_list); +#endif + /* * Used by page_zone() to look up the address of the struct zone whose * id is encoded in the upper bits of page->flags @@ -98,7 +103,8 @@ static void bad_page(const char *function, struct page *page) page->mapcount = 0; } -#ifndef CONFIG_HUGETLB_PAGE +#if !defined(CONFIG_HUGETLB_PAGE) && !defined(CONFIG_CRASH_DUMP) \ + && !defined(CONFIG_CRASH_DUMP_MODULE) #define prep_compound_page(page, order) do { } while (0) #define destroy_compound_page(page, order) do { } while (0) #else diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 019ee9605..1357c29c2 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -33,7 +33,7 @@ UTS_VERSION="$UTS_VERSION `LC_ALL=C LANG=C date`" UTS_LEN=64 UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" - +LINUX_COMPILE_VERSION_ID="__linux_compile_version_id__`hostname | tr -c '[0-9A-Za-z\n]' '__'`_`LANG=C date | tr -c '[0-9A-Za-z\n]' '_'`" # Generate a temporary compile.h ( echo /\* This file is auto generated, version $VERSION \*/ @@ -55,6 +55,8 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" fi echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\" + echo \#define LINUX_COMPILE_VERSION_ID $LINUX_COMPILE_VERSION_ID + echo \#define LINUX_COMPILE_VERSION_ID_TYPE typedef char* "$LINUX_COMPILE_VERSION_ID""_t" ) > .tmpcompile # Only replace the real compile.h if the new one is different,