diff options
72 files changed, 589 insertions, 389 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index bc859a311eaf..45bf04eb7d70 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2034,7 +2034,8 @@ sba_init(void) if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb")) return 0; -#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP) +#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP) && \ + defined(CONFIG_PROC_FS) /* If we are booting a kdump kernel, the sba_iommu will * cause devices that were not shutdown properly to MCA * as soon as they are turned back on. Our only option for diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index f6ae3ec93810..3e35987af458 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -52,33 +52,29 @@ extern struct page *ia32_shared_page[]; extern unsigned long *ia32_gdt; extern struct page *ia32_gate_page; -struct page * -ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int *type) +int +ia32_install_shared_page (struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *pg = ia32_shared_page[smp_processor_id()]; - get_page(pg); - if (type) - *type = VM_FAULT_MINOR; - return pg; + vmf->page = ia32_shared_page[smp_processor_id()]; + get_page(vmf->page); + return 0; } -struct page * -ia32_install_gate_page (struct vm_area_struct *vma, unsigned long address, int *type) +int +ia32_install_gate_page (struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *pg = ia32_gate_page; - get_page(pg); - if (type) - *type = VM_FAULT_MINOR; - return pg; + vmf->page = ia32_gate_page; + get_page(vmf->page); + return 0; } static struct vm_operations_struct ia32_shared_page_vm_ops = { - .nopage = ia32_install_shared_page + .fault = ia32_install_shared_page }; static struct vm_operations_struct ia32_gate_page_vm_ops = { - .nopage = ia32_install_gate_page + .fault = ia32_install_gate_page }; void diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 4e5e27540e27..d3a41d5f8d12 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -1176,6 +1176,7 @@ tlb_purge_done: RESTORE_REG(cr.dcr, r25, r17);; RESTORE_REG(cr.iva, r25, r17);; RESTORE_REG(cr.pta, r25, r17);; + srlz.d;; // required not to violate RAW dependency RESTORE_REG(cr.itv, r25, r17);; RESTORE_REG(cr.pmv, r25, r17);; RESTORE_REG(cr.cmcv, r25, r17);; diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 00a4599e5f47..0b52f19ed046 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -200,7 +200,7 @@ assign_irq_vector (int irq) { unsigned long flags; int vector, cpu; - cpumask_t domain; + cpumask_t domain = CPU_MASK_NONE; vector = -ENOSPC; @@ -340,7 +340,7 @@ int create_irq(void) { unsigned long flags; int irq, vector, cpu; - cpumask_t domain; + cpumask_t domain = CPU_MASK_NONE; irq = vector = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 10b48cd15a87..6dbf5919d2d0 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -75,6 +75,7 @@ #include <linux/workqueue.h> #include <linux/cpumask.h> #include <linux/kdebug.h> +#include <linux/cpu.h> #include <asm/delay.h> #include <asm/machvec.h> @@ -1813,6 +1814,36 @@ ia64_mca_cpu_init(void *cpu_data) PAGE_KERNEL)); } +static void __cpuinit ia64_mca_cmc_vector_adjust(void *dummy) +{ + unsigned long flags; + + local_irq_save(flags); + if (!cmc_polling_enabled) + ia64_mca_cmc_vector_enable(NULL); + local_irq_restore(flags); +} + +static int __cpuinit mca_cpu_callback(struct notifier_block *nfb, + unsigned long action, + void *hcpu) +{ + int hotcpu = (unsigned long) hcpu; + + switch (action) { + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + smp_call_function_single(hotcpu, ia64_mca_cmc_vector_adjust, + NULL, 1, 0); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block mca_cpu_notifier __cpuinitdata = { + .notifier_call = mca_cpu_callback +}; + /* * ia64_mca_init * @@ -1996,6 +2027,8 @@ ia64_mca_late_init(void) if (!mca_init) return 0; + register_hotcpu_notifier(&mca_cpu_notifier); + /* Setup the CMCI/P vector and handler */ init_timer(&cmc_poll_timer); cmc_poll_timer.function = ia64_mca_cmc_poll; diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 2418289ee5ca..7377d323131d 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -27,6 +27,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/kdebug.h> +#include <linux/utsname.h> #include <asm/cpu.h> #include <asm/delay.h> @@ -107,8 +108,9 @@ show_regs (struct pt_regs *regs) print_modules(); printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current), smp_processor_id(), current->comm); - printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", - regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); + printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n", + regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(), + init_utsname()->release); print_symbol("ip is at %s\n", ip); printk("unat: %016lx pfs : %016lx rsc : %016lx\n", regs->ar_unat, regs->ar_pfs, regs->ar_rsc); @@ -737,6 +739,7 @@ flush_thread (void) ia32_drop_ia64_partial_page_list(current); current->thread.task_size = IA32_PAGE_OFFSET; set_fs(USER_DS); + memset(current->thread.tls_array, 0, sizeof(current->thread.tls_array)); } #endif } diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 4c730099d58f..309da3567bc8 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -280,15 +280,7 @@ setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratc err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8); /* r15 */ err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip); - if (flags & IA64_SC_FLAG_IN_SYSCALL) { - /* Clear scratch registers if the signal interrupted a system call. */ - err |= __put_user(0, &sc->sc_ar_ccv); /* ar.ccv */ - err |= __put_user(0, &sc->sc_br[7]); /* b7 */ - err |= __put_user(0, &sc->sc_gr[14]); /* r14 */ - err |= __clear_user(&sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */ - err |= __clear_user(&sc->sc_gr[2], 2*8); /* r2-r3 */ - err |= __clear_user(&sc->sc_gr[16], 16*8); /* r16-r31 */ - } else { + if (!(flags & IA64_SC_FLAG_IN_SYSCALL)) { /* Copy scratch regs to sigcontext if the signal didn't interrupt a syscall. */ err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); /* ar.ccv */ err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index a7be4f203420..2a90c32024f4 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -118,7 +118,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid) for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++) SetPageUncached(&page[i]); - flush_tlb_kernel_range(uc_addr, uc_adddr + IA64_GRANULE_SIZE); + flush_tlb_kernel_range(uc_addr, uc_addr + IA64_GRANULE_SIZE); status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); if (status == PAL_VISIBILITY_OK_REMOTE_NEEDED) { diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index cef164729db7..655da240d13c 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -10,6 +10,7 @@ * IPI based ptc implementation and A-step IPI implementation. * Rohit Seth <rohit.seth@intel.com> * Ken Chen <kenneth.w.chen@intel.com> + * Christophe de Dinechin <ddd@hp.com>: Avoid ptc.e on memory allocation */ #include <linux/module.h> #include <linux/init.h> @@ -89,9 +90,16 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, { static DEFINE_SPINLOCK(ptcg_lock); - if (mm != current->active_mm || !current->mm) { - flush_tlb_all(); - return; + struct mm_struct *active_mm = current->active_mm; + + if (mm != active_mm) { + /* Restore region IDs for mm */ + if (mm && active_mm) { + activate_context(mm); + } else { + flush_tlb_all(); + return; + } } /* HW requires global serialization of ptc.ga. */ @@ -107,6 +115,10 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, } while (start < end); } spin_unlock(&ptcg_lock); + + if (mm != active_mm) { + activate_context(active_mm); + } } void diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index b362d6d6a8c8..9456d4034024 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. */ #include <linux/module.h> @@ -227,7 +227,7 @@ retry_bteop: BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na)); if (transfer_stat & IBLS_ERROR) { - bte_status = transfer_stat & ~IBLS_ERROR; + bte_status = BTE_GET_ERROR_STATUS(transfer_stat); } else { bte_status = BTE_SUCCESS; } diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c index 27c5936ccfe9..4cb09f3f1efc 100644 --- a/arch/ia64/sn/kernel/bte_error.c +++ b/arch/ia64/sn/kernel/bte_error.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. */ #include <linux/types.h> @@ -148,7 +148,11 @@ int shub2_bte_error_handler(unsigned long _nodepda) for (i = 0; i < BTES_PER_NODE; i++) { bte = &err_nodepda->bte_if[i]; status = BTE_LNSTAT_LOAD(bte); - if ((status & IBLS_ERROR) || !(status & IBLS_BUSY)) + if (status & IBLS_ERROR) { + bte->bh_error = BTE_SHUB2_ERROR(status); + continue; + } + if (!(status & IBLS_BUSY)) continue; mod_timer(recovery_timer, jiffies + (HZ * 5)); BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index cee9379d44e0..e1a3e19d3d9c 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -41,7 +41,7 @@ * } else * do desired mmr access * - * According to hw, we can use reads instead of writes to the above addres + * According to hw, we can use reads instead of writes to the above address * * Note this WAR can only to be used for accessing internal MMR's in the * TIOCE Coretalk Address Range 0x0 - 0x07ff_ffff. This includes the diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 96986b46bc85..edb5108e5d0e 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c @@ -849,7 +849,7 @@ void __init init_bsp_APIC(void) /** * setup_local_APIC - setup the local APIC */ -void __devinit setup_local_APIC(void) +void __cpuinit setup_local_APIC(void) { unsigned long oldvalue, value, maxlvt, integrated; int i, j; diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 6cf27319a91c..c3a565bba106 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -1882,13 +1882,16 @@ __setup("no_timer_check", notimercheck); static int __init timer_irq_works(void) { unsigned long t1 = jiffies; + unsigned long flags; if (no_timer_check) return 1; + local_save_flags(flags); local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); + local_irq_restore(flags); /* * Expect a few ticks at least, to be sure some possible @@ -2167,6 +2170,9 @@ static inline void __init check_timer(void) int apic1, pin1, apic2, pin2; int vector; unsigned int ver; + unsigned long flags; + + local_irq_save(flags); ver = apic_read(APIC_LVR); ver = GET_APIC_VERSION(ver); @@ -2219,7 +2225,7 @@ static inline void __init check_timer(void) } if (disable_timer_pin_1 > 0) clear_IO_APIC_pin(0, pin1); - return; + goto out; } clear_IO_APIC_pin(apic1, pin1); printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to " @@ -2242,7 +2248,7 @@ static inline void __init check_timer(void) if (nmi_watchdog == NMI_IO_APIC) { setup_nmi(); } - return; + goto out; } /* * Cleanup, just in case ... @@ -2266,7 +2272,7 @@ static inline void __init check_timer(void) if (timer_irq_works()) { printk(" works.\n"); - return; + goto out; } apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); printk(" failed.\n"); @@ -2282,11 +2288,13 @@ static inline void __init check_timer(void) if (timer_irq_works()) { printk(" works.\n"); - return; + goto out; } printk(" failed :(.\n"); panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " "report. Then try booting with the 'noapic' option"); +out: + local_irq_restore(flags); } /* diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 435a8c9b55f8..cbac1670c7c3 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -1281,10 +1281,13 @@ void disable_IO_APIC(void) static int __init timer_irq_works(void) { unsigned long t1 = jiffies; + unsigned long flags; + local_save_flags(flags); local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); + local_irq_restore(flags); /* * Expect a few ticks at least, to be sure some possible @@ -1655,6 +1658,9 @@ static inline void check_timer(void) { struct irq_cfg *cfg = irq_cfg + 0; int apic1, pin1, apic2, pin2; + unsigned long flags; + + local_irq_save(flags); /* * get/set the timer IRQ vector: @@ -1696,7 +1702,7 @@ static inline void check_timer(void) } if (disable_timer_pin_1 > 0) clear_IO_APIC_pin(0, pin1); - return; + goto out; } clear_IO_APIC_pin(apic1, pin1); apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not " @@ -1718,7 +1724,7 @@ static inline void check_timer(void) if (nmi_watchdog == NMI_IO_APIC) { setup_nmi(); } - return; + goto out; } /* * Cleanup, just in case ... @@ -1741,7 +1747,7 @@ static inline void check_timer(void) if (timer_irq_works()) { apic_printk(APIC_VERBOSE," works.\n"); - return; + goto out; } apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); apic_printk(APIC_VERBOSE," failed.\n"); @@ -1756,10 +1762,12 @@ static inline void check_timer(void) if (timer_irq_works()) { apic_printk(APIC_VERBOSE," works.\n"); - return; + goto out; } apic_printk(APIC_VERBOSE," failed :(.\n"); panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); +out: + local_irq_restore(flags); } static int __init notimercheck(char *s) diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c index d87a523070d1..3a020f79f82b 100644 --- a/arch/x86/kernel/kprobes_32.c +++ b/arch/x86/kernel/kprobes_32.c @@ -727,9 +727,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { if (®s->esp != kcb->jprobe_saved_esp) { - struct pt_regs *saved_regs = - container_of(kcb->jprobe_saved_esp, - struct pt_regs, esp); + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; printk("current esp %p does not match saved esp %p\n", ®s->esp, kcb->jprobe_saved_esp); printk("Saved registers for jprobe %p\n", jp); diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c index 0c467644589c..5df19a9f9239 100644 --- a/arch/x86/kernel/kprobes_64.c +++ b/arch/x86/kernel/kprobes_64.c @@ -485,7 +485,6 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { unsigned long *tos = (unsigned long *)regs->rsp; - unsigned long next_rip = 0; unsigned long copy_rip = (unsigned long)p->ainsn.insn; unsigned long orig_rip = (unsigned long)p->addr; kprobe_opcode_t *insn = p->ainsn.insn; @@ -494,46 +493,42 @@ static void __kprobes resume_execution(struct kprobe *p, if (*insn >= 0x40 && *insn <= 0x4f) insn++; + regs->eflags &= ~TF_MASK; switch (*insn) { - case 0x9c: /* pushfl */ + case 0x9c: /* pushfl */ *tos &= ~(TF_MASK | IF_MASK); *tos |= kcb->kprobe_old_rflags; break; - case 0xc3: /* ret/lret */ - case 0xcb: - case 0xc2: + case 0xc2: /* iret/ret/lret */ + case 0xc3: case 0xca: - regs->eflags &= ~TF_MASK; - /* rip is already adjusted, no more changes required*/ - return; - case 0xe8: /* call relative - Fix return addr */ + case 0xcb: + case 0xcf: + case 0xea: /* jmp absolute -- ip is correct */ + /* ip is already adjusted, no more changes required */ + goto no_change; + case 0xe8: /* call relative - Fix return addr */ *tos = orig_rip + (*tos - copy_rip); break; case 0xff: if ((insn[1] & 0x30) == 0x10) { /* call absolute, indirect */ - /* Fix return addr; rip is correct. */ - next_rip = regs->rip; + /* Fix return addr; ip is correct. */ *tos = orig_rip + (*tos - copy_rip); + goto no_change; } else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ ((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ - /* rip is correct. */ - next_rip = regs->rip; + /* ip is correct. */ + goto no_change; } - break; - case 0xea: /* jmp absolute -- rip is correct */ - next_rip = regs->rip; - break; default: break; } - regs->eflags &= ~TF_MASK; - if (next_rip) { - regs->rip = next_rip; - } else { - regs->rip = orig_rip + (regs->rip - copy_rip); - } + regs->rip = orig_rip + (regs->rip - copy_rip); +no_change: + + return; } int __kprobes post_kprobe_handler(struct pt_regs *regs) @@ -716,10 +711,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp); if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { - if ((long *)regs->rsp != kcb->jprobe_saved_rsp) { - struct pt_regs *saved_regs = - container_of(kcb->jprobe_saved_rsp, - struct pt_regs, rsp); + if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) { + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; printk("current rsp %p does not match saved rsp %p\n", (long *)regs->rsp, kcb->jprobe_saved_rsp); printk("Saved registers for jprobe %p\n", jp); diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 7b899584d290..9663c2a74830 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -261,7 +261,7 @@ static void mwait_idle(void) mwait_idle_with_hints(0, 0); } -void __devinit select_idle_routine(const struct cpuinfo_x86 *c) +void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_MWAIT)) { printk("monitor/mwait feature present.\n"); diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index e1e18c34c821..9c24b45b513c 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -67,7 +67,7 @@ address, and must not be in the .bss segment! */ unsigned long init_pg_tables_end __initdata = ~0UL; -int disable_pse __devinitdata = 0; +int disable_pse __cpuinitdata = 0; /* * Machine setup.. diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index ef0f34ede1ab..4ea80cbe52e5 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c @@ -60,7 +60,7 @@ #include <asm/mtrr.h> /* Set if we find a B stepping CPU */ -static int __devinitdata smp_b_stepping; +static int __cpuinitdata smp_b_stepping; /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -745,8 +745,8 @@ static inline int alloc_cpu_id(void) } #ifdef CONFIG_HOTPLUG_CPU -static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS]; -static inline struct task_struct * alloc_idle_task(int cpu) +static struct task_struct * __cpuinitdata cpu_idle_tasks[NR_CPUS]; +static inline struct task_struct * __cpuinit alloc_idle_task(int cpu) { struct task_struct *idle; diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 500670c93d81..594889521da1 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -141,8 +141,8 @@ static void __cpuinit smp_store_cpu_info(int id) struct cpuinfo_x86 *c = &cpu_data(id); *c = boot_cpu_data; - c->cpu_index = id; identify_cpu(c); + c->cpu_index = id; print_cpu_info(c); } diff --git a/arch/x86/oprofile/op_model_athlon.c b/arch/x86/oprofile/op_model_athlon.c index 3057a19e4641..c3ee43333f26 100644 --- a/arch/x86/oprofile/op_model_athlon.c +++ b/arch/x86/oprofile/op_model_athlon.c @@ -1,6 +1,6 @@ /** * @file op_model_athlon.h - * athlon / K7 model-specific MSR operations + * athlon / K7 / K8 / Family 10h model-specific MSR operations * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING @@ -31,12 +31,16 @@ #define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0) #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) #define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) -#define CTRL_CLEAR(x) (x &= (1<<21)) +#define CTRL_CLEAR_LO(x) (x &= (1<<21)) +#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0) #define CTRL_SET_ENABLE(val) (val |= 1<<20) #define CTRL_SET_USR(val,u) (val |= ((u & 1) << 16)) #define CTRL_SET_KERN(val,k) (val |= ((k & 1) << 17)) #define CTRL_SET_UM(val, m) (val |= (m << 8)) -#define CTRL_SET_EVENT(val, e) (val |= e) +#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff)) +#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf)) +#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9)) +#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8)) static unsigned long reset_value[NUM_COUNTERS]; @@ -70,7 +74,8 @@ static void athlon_setup_ctrs(struct op_msrs const * const msrs) if (unlikely(!CTRL_IS_RESERVED(msrs,i))) continue; CTRL_READ(low, high, msrs, i); - CTRL_CLEAR(low); + CTRL_CLEAR_LO(low); + CTRL_CLEAR_HI(high); CTRL_WRITE(low, high, msrs, i); } @@ -89,12 +94,17 @@ static void athlon_setup_ctrs(struct op_msrs const * const msrs) CTR_WRITE(counter_config[i].count, msrs, i); CTRL_READ(low, high, msrs, i); - CTRL_CLEAR(low); + CTRL_CLEAR_LO(low); + CTRL_CLEAR_HI(high); CTRL_SET_ENABLE(low); CTRL_SET_USR(low, counter_config[i].user); CTRL_SET_KERN(low, counter_config[i].kernel); CTRL_SET_UM(low, counter_config[i].unit_mask); - CTRL_SET_EVENT(low, counter_config[i].event); + CTRL_SET_EVENT_LOW(low, counter_config[i].event); + CTRL_SET_EVENT_HIGH(high, counter_config[i].event); + CTRL_SET_HOST_ONLY(high, 0); + CTRL_SET_GUEST_ONLY(high, 0); + CTRL_WRITE(low, high, msrs, i); } else { reset_value[i] = 0; diff --git a/block/as-iosched.c b/block/as-iosched.c index dc715a562e14..cb5e53b05c7c 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c @@ -880,7 +880,7 @@ static void as_remove_queued_request(struct request_queue *q, } /* - * as_fifo_expired returns 0 if there are no expired reads on the fifo, + * as_fifo_expired returns 0 if there are no expired requests on the fifo, * 1 otherwise. It is ratelimited so that we only perform the check once per * `fifo_expire' interval. Otherwise a large number of expired requests * would create a hopeless seekstorm. @@ -1097,7 +1097,8 @@ dispatch_writes: ad->batch_data_dir = REQ_ASYNC; ad->current_write_count = ad->write_batch_count; ad->write_batch_idled = 0; - rq = ad->next_rq[ad->batch_data_dir]; + rq = rq_entry_fifo(ad->fifo_list[REQ_ASYNC].next); + ad->last_check_fifo[REQ_ASYNC] = jiffies; goto dispatch_request; } @@ -1159,7 +1160,7 @@ static void as_add_request(struct request_queue *q, struct request *rq) as_add_rq_rb(ad, rq); /* - * set expire time (only used for reads) and add to fifo list + * set expire time and add to fifo list */ rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]); list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]); @@ -1463,7 +1464,9 @@ static struct elevator_type iosched_as = { static int __init as_init(void) { - return elv_register(&iosched_as); + elv_register(&iosched_as); + + return 0; } static void __exit as_exit(void) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 0b4a47905575..13553e015d72 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2279,8 +2279,6 @@ static struct elevator_type iosched_cfq = { static int __init cfq_init(void) { - int ret; - /* * could be 0 on HZ < 1000 setups */ @@ -2292,11 +2290,9 @@ static int __init cfq_init(void) if (cfq_slab_setup()) return -ENOMEM; - ret = elv_register(&iosched_cfq); - if (ret) - cfq_slab_kill(); + elv_register(&iosched_cfq); - return ret; + return 0; } static void __exit cfq_exit(void) diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c index a054eef8dff6..342448c3d2dd 100644 --- a/block/deadline-iosched.c +++ b/block/deadline-iosched.c @@ -467,7 +467,9 @@ static struct elevator_type iosched_deadline = { static int __init deadline_init(void) { - return elv_register(&iosched_deadline); + elv_register(&iosched_deadline); + + return 0; } static void __exit deadline_exit(void) diff --git a/block/elevator.c b/block/elevator.c index 446aea2a3cfb..e452deb80395 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -960,7 +960,7 @@ void elv_unregister_queue(struct request_queue *q) __elv_unregister_queue(q->elevator); } -int elv_register(struct elevator_type *e) +void elv_register(struct elevator_type *e) { char *def = ""; @@ -975,7 +975,6 @@ int elv_register(struct elevator_type *e) def = " (default)"; printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def); - return 0; } EXPORT_SYMBOL_GPL(elv_register); diff --git a/block/noop-iosched.c b/block/noop-iosched.c index 7563d8aa3944..c23e02969650 100644 --- a/block/noop-iosched.c +++ b/block/noop-iosched.c @@ -101,7 +101,9 @@ static struct elevator_type elevator_noop = { static int __init noop_init(void) { - return elv_register(&elevator_noop); + elv_register(&elevator_noop); + + return 0; } static void __exit noop_exit(void) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 91c73224f4c6..9675b34638d4 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -230,7 +230,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, rq->cmd_len = hdr->cmd_len; rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->timeout = (hdr->timeout * HZ) / 1000; + rq->timeout = msecs_to_jiffies(hdr->timeout); if (!rq->timeout) rq->timeout = q->sg_timeout; if (!rq->timeout) @@ -366,7 +366,7 @@ static int sg_io(struct file *file, struct request_queue *q, */ blk_execute_rq(q, bd_disk, rq, 0); - hdr->duration = ((jiffies - start_time) * 1000) / HZ; + hdr->duration = jiffies_to_msecs(jiffies - start_time); return blk_complete_sghdr_rq(rq, hdr, bio); out: diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 46dc70e0dee7..c79f066c2bc9 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -375,7 +375,7 @@ static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline) pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000); pci_read_config_byte(pdev, 0x5A, &ata66); /* Reset TCBLID/FCBLID to output */ - pci_write_config_word(pdev, 0x52, mcr3); + pci_write_config_word(pdev, mcrbase + 2, mcr3); if (ata66 & (2 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 5f5095afb06b..c24e1bdbad43 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -34,7 +34,7 @@ * - set initialised bit then. */ -//#define DEBUG /* uncomment if you want debugging info (pr_debug) */ +#undef DEBUG /* #define DEBUG if you want debugging info (pr_debug) */ #include <linux/fs.h> #include <linux/bio.h> #include <linux/kernel.h> @@ -143,17 +143,12 @@ static struct cardinfo cards[MM_MAXCARDS]; static struct block_device_operations mm_fops; static struct timer_list battery_timer; -static int num_cards = 0; +static int num_cards; static struct gendisk *mm_gendisk[MM_MAXCARDS]; static void check_batteries(struct cardinfo *card); -/* ------------------------------------------------------------------------------------ --- get_userbit ------------------------------------------------------------------------------------ -*/ static int get_userbit(struct cardinfo *card, int bit) { unsigned char led; @@ -161,11 +156,7 @@ static int get_userbit(struct cardinfo *card, int bit) led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL); return led & bit; } -/* ------------------------------------------------------------------------------------ --- set_userbit ------------------------------------------------------------------------------------ -*/ + static int set_userbit(struct cardinfo *card, int bit, unsigned char state) { unsigned char led; @@ -179,11 +170,7 @@ static int set_userbit(struct cardinfo *card, int bit, unsigned char state) return 0; } -/* ------------------------------------------------------------------------------------ --- set_led ------------------------------------------------------------------------------------ -*/ + /* * NOTE: For the power LED, use the LED_POWER_* macros since they differ */ @@ -203,11 +190,6 @@ static void set_led(struct cardinfo *card, int shift, unsigned char state) } #ifdef MM_DIAG -/* ------------------------------------------------------------------------------------ --- dump_regs ------------------------------------------------------------------------------------ -*/ static void dump_regs(struct cardinfo *card) { unsigned char *p; @@ -224,32 +206,28 @@ static void dump_regs(struct cardinfo *card) } } #endif -/* ------------------------------------------------------------------------------------ --- dump_dmastat ------------------------------------------------------------------------------------ -*/ + static void dump_dmastat(struct cardinfo *card, unsigned int dmastat) { dev_printk(KERN_DEBUG, &card->dev->dev, "DMAstat - "); if (dmastat & DMASCR_ANY_ERR) - printk("ANY_ERR "); + printk(KERN_CONT "ANY_ERR "); if (dmastat & DMASCR_MBE_ERR) - printk("MBE_ERR "); + printk(KERN_CONT "MBE_ERR "); if (dmastat & DMASCR_PARITY_ERR_REP) - printk("PARITY_ERR_REP "); + printk(KERN_CONT "PARITY_ERR_REP "); if (dmastat & DMASCR_PARITY_ERR_DET) - printk("PARITY_ERR_DET "); + printk(KERN_CONT "PARITY_ERR_DET "); if (dmastat & DMASCR_SYSTEM_ERR_SIG) - printk("SYSTEM_ERR_SIG "); + printk(KERN_CONT "SYSTEM_ERR_SIG "); if (dmastat & DMASCR_TARGET_ABT) - printk("TARGET_ABT "); + printk(KERN_CONT "TARGET_ABT "); if (dmastat & DMASCR_MASTER_ABT) - printk("MASTER_ABT "); + printk(KERN_CONT "MASTER_ABT "); if (dmastat & DMASCR_CHAIN_COMPLETE) - printk("CHAIN_COMPLETE "); + printk(KERN_CONT "CHAIN_COMPLETE "); if (dmastat & DMASCR_DMA_COMPLETE) - printk("DMA_COMPLETE "); + printk(KERN_CONT "DMA_COMPLETE "); printk("\n"); } @@ -286,7 +264,8 @@ static void mm_start_io(struct cardinfo *card) /* make the last descriptor end the chain */ page = &card->mm_pages[card->Active]; - pr_debug("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1); + pr_debug("start_io: %d %d->%d\n", + card->Active, page->headcnt, page->cnt - 1); desc = &page->desc[page->cnt-1]; desc->control_bits |= cpu_to_le32(DMASCR_CHAIN_COMP_EN); @@ -310,8 +289,8 @@ static void mm_start_io(struct cardinfo *card) writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR); writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR + 4); - offset = ((char*)desc) - ((char*)page->desc); - writel(cpu_to_le32((page->page_dma+offset)&0xffffffff), + offset = ((char *)desc) - ((char *)page->desc); + writel(cpu_to_le32((page->page_dma+offset) & 0xffffffff), card->csr_remap + DMA_DESCRIPTOR_ADDR); /* Force the value to u64 before shifting otherwise >> 32 is undefined C * and on some ports will do nothing ! */ @@ -352,7 +331,7 @@ static inline void reset_page(struct mm_page *page) page->cnt = 0; page->headcnt = 0; page->bio = NULL; - page->biotail = & page->bio; + page->biotail = &page->bio; } static void mm_unplug_device(struct request_queue *q) @@ -408,7 +387,7 @@ static int add_bio(struct cardinfo *card) vec->bv_page, vec->bv_offset, len, - (rw==READ) ? + (rw == READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); p = &card->mm_pages[card->Ready]; @@ -427,10 +406,10 @@ static int add_bio(struct cardinfo *card) desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle); desc->local_addr = cpu_to_le64(card->current_sector << 9); desc->transfer_size = cpu_to_le32(len); - offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc)); + offset = (((char *)&desc->sem_control_bits) - ((char *)p->desc)); desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset)); desc->zero1 = desc->zero2 = 0; - offset = ( ((char*)(desc+1)) - ((char*)p->desc)); + offset = (((char *)(desc+1)) - ((char *)p->desc)); desc->next_desc_addr = cpu_to_le64(p->page_dma+offset); desc->control_bits = cpu_to_le32(DMASCR_GO|DMASCR_ERR_INT_EN| DMASCR_PARITY_INT_EN| @@ -455,11 +434,11 @@ static void process_page(unsigned long data) /* check if any of the requests in the page are DMA_COMPLETE, * and deal with them appropriately. * If we find a descriptor without DMA_COMPLETE in the semaphore, then - * dma must have hit an error on that descriptor, so use dma_status instead - * and assume that all following descriptors must be re-tried. + * dma must have hit an error on that descriptor, so use dma_status + * instead and assume that all following descriptors must be re-tried. */ struct mm_page *page; - struct bio *return_bio=NULL; + struct bio *return_bio = NULL; struct cardinfo *card = (struct cardinfo *)data; unsigned int dma_status = card->dma_status; @@ -472,12 +451,12 @@ static void process_page(unsigned long data) struct bio *bio = page->bio; struct mm_dma_desc *desc = &page->desc[page->headcnt]; int control = le32_to_cpu(desc->sem_control_bits); - int last=0; + int last = 0; int idx; if (!(control & DMASCR_DMA_COMPLETE)) { control = dma_status; - last=1; + last = 1; } page->headcnt++; idx = page->idx; @@ -489,8 +468,8 @@ static void process_page(unsigned long data) } pci_unmap_page(card->dev, desc->data_dma_handle, - bio_iovec_idx(bio,idx)->bv_len, - (control& DMASCR_TRANSFER_READ) ? + bio_iovec_idx(bio, idx)->bv_len, + (control & DMASCR_TRANSFER_READ) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (control & DMASCR_HARD_ERROR) { /* error */ @@ -501,9 +480,10 @@ static void process_page(unsigned long data) le32_to_cpu(desc->transfer_size)); dump_dmastat(card, control); } else if (test_bit(BIO_RW, &bio->bi_rw) && - le32_to_cpu(desc->local_addr)>>9 == card->init_size) { - card->init_size += le32_to_cpu(desc->transfer_size)>>9; - if (card->init_size>>1 >= card->mm_size) { + le32_to_cpu(desc->local_addr) >> 9 == + card->init_size) { + card->init_size += le32_to_cpu(desc->transfer_size) >> 9; + if (card->init_size >> 1 >= card->mm_size) { dev_printk(KERN_INFO, &card->dev->dev, "memory now initialised\n"); set_userbit(card, MEMORY_INITIALIZED, 1); @@ -514,7 +494,8 @@ static void process_page(unsigned long data) return_bio = bio; } - if (last) break; + if (last) + break; } if (debug & DEBUG_LED_ON_TRANSFER) @@ -536,7 +517,7 @@ static void process_page(unsigned long data) out_unlock: spin_unlock_bh(&card->lock); - while(return_bio) { + while (return_bio) { struct bio *bio = return_bio; return_bio = bio->bi_next; @@ -545,11 +526,6 @@ static void process_page(unsigned long data) } } -/* ------------------------------------------------------------------------------------ --- mm_make_request ------------------------------------------------------------------------------------ -*/ static int mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -566,11 +542,6 @@ static int mm_make_request(struct request_queue *q, struct bio *bio) return 0; } -/* ------------------------------------------------------------------------------------ --- mm_interrupt ------------------------------------------------------------------------------------ -*/ static irqreturn_t mm_interrupt(int irq, void *__card) { struct cardinfo *card = (struct cardinfo *) __card; @@ -584,15 +555,15 @@ HW_TRACE(0x30); if (!(dma_status & (DMASCR_ERROR_MASK | DMASCR_CHAIN_COMPLETE))) { /* interrupt wasn't for me ... */ return IRQ_NONE; - } + } /* clear COMPLETION interrupts */ if (card->flags & UM_FLAG_NO_BYTE_STATUS) writel(cpu_to_le32(DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE), - card->csr_remap+ DMA_STATUS_CTRL); + card->csr_remap + DMA_STATUS_CTRL); else writeb((DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE) >> 16, - card->csr_remap+ DMA_STATUS_CTRL + 2); + card->csr_remap + DMA_STATUS_CTRL + 2); /* log errors and clear interrupt status */ if (dma_status & DMASCR_ANY_ERR) { @@ -602,9 +573,12 @@ HW_TRACE(0x30); stat = readb(card->csr_remap + MEMCTRLCMD_ERRSTATUS); - data_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG)); - data_log2 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG + 4)); - addr_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_ADDR_LOG)); + data_log1 = le32_to_cpu(readl(card->csr_remap + + ERROR_DATA_LOG)); + data_log2 = le32_to_cpu(readl(card->csr_remap + + ERROR_DATA_LOG + 4)); + addr_log1 = le32_to_cpu(readl(card->csr_remap + + ERROR_ADDR_LOG)); addr_log2 = readb(card->csr_remap + ERROR_ADDR_LOG + 4); count = readb(card->csr_remap + ERROR_COUNT); @@ -671,11 +645,7 @@ HW_TRACE(0x36); return IRQ_HANDLED; } -/* ------------------------------------------------------------------------------------ --- set_fault_to_battery_status ------------------------------------------------------------------------------------ -*/ + /* * If both batteries are good, no LED * If either battery has been warned, solid LED @@ -696,12 +666,6 @@ static void set_fault_to_battery_status(struct cardinfo *card) static void init_battery_timer(void); - -/* ------------------------------------------------------------------------------------ --- check_battery ------------------------------------------------------------------------------------ -*/ static int check_battery(struct cardinfo *card, int battery, int status) { if (status != card->battery[battery].good) { @@ -730,11 +694,7 @@ static int check_battery(struct cardinfo *card, int battery, int status) return 0; } -/* ------------------------------------------------------------------------------------ --- check_batteries ------------------------------------------------------------------------------------ -*/ + static void check_batteries(struct cardinfo *card) { /* NOTE: this must *never* be called while the card @@ -775,11 +735,7 @@ static void check_all_batteries(unsigned long ptr) init_battery_timer(); } -/* ------------------------------------------------------------------------------------ --- init_battery_timer ------------------------------------------------------------------------------------ -*/ + static void init_battery_timer(void) { init_timer(&battery_timer); @@ -787,20 +743,12 @@ static void init_battery_timer(void) battery_timer.expires = jiffies + (HZ * 60); add_timer(&battery_timer); } -/* ------------------------------------------------------------------------------------ --- del_battery_timer ------------------------------------------------------------------------------------ -*/ + static void del_battery_timer(void) { del_timer(&battery_timer); } -/* ------------------------------------------------------------------------------------ --- mm_revalidate ------------------------------------------------------------------------------------ -*/ + /* * Note no locks taken out here. In a worst case scenario, we could drop * a chunk of system memory. But that should never happen, since validation @@ -833,33 +781,23 @@ static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /* ------------------------------------------------------------------------------------ --- mm_check_change ------------------------------------------------------------------------------------ - Future support for removable devices -*/ + * Future support for removable devices + */ static int mm_check_change(struct gendisk *disk) { /* struct cardinfo *dev = disk->private_data; */ return 0; } -/* ------------------------------------------------------------------------------------ --- mm_fops ------------------------------------------------------------------------------------ -*/ + static struct block_device_operations mm_fops = { .owner = THIS_MODULE, .getgeo = mm_getgeo, - .revalidate_disk= mm_revalidate, + .revalidate_disk = mm_revalidate, .media_changed = mm_check_change, }; -/* ------------------------------------------------------------------------------------ --- mm_pci_probe ------------------------------------------------------------------------------------ -*/ -static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + +static int __devinit mm_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) { int ret = -ENODEV; struct cardinfo *card = &cards[num_cards]; @@ -889,7 +827,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i return -ENODEV; dev_printk(KERN_INFO, &dev->dev, - "Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n"); + "Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n"); if (pci_set_dma_mask(dev, DMA_64BIT_MASK) && pci_set_dma_mask(dev, DMA_32BIT_MASK)) { @@ -917,7 +855,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i "CSR 0x%08lx -> 0x%p (0x%lx)\n", csr_base, card->csr_remap, csr_len); - switch(card->dev->device) { + switch (card->dev->device) { case 0x5415: card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG; magic_number = 0x59; @@ -929,7 +867,8 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i break; case 0x6155: - card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG | UM_FLAG_NO_BATT; + card->flags |= UM_FLAG_NO_BYTE_STATUS | + UM_FLAG_NO_BATTREG | UM_FLAG_NO_BATT; magic_number = 0x99; break; @@ -945,11 +884,11 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i } card->mm_pages[0].desc = pci_alloc_consistent(card->dev, - PAGE_SIZE*2, - &card->mm_pages[0].page_dma); + PAGE_SIZE * 2, + &card->mm_pages[0].page_dma); card->mm_pages[1].desc = pci_alloc_consistent(card->dev, - PAGE_SIZE*2, - &card->mm_pages[1].page_dma); + PAGE_SIZE * 2, + &card->mm_pages[1].page_dma); if (card->mm_pages[0].desc == NULL || card->mm_pages[1].desc == NULL) { dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); @@ -1013,9 +952,9 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i dev_printk(KERN_INFO, &card->dev->dev, "Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n", card->mm_size, - (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"), + batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled", card->battery[0].good ? "OK" : "FAILURE", - (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"), + batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled", card->battery[1].good ? "OK" : "FAILURE"); set_fault_to_battery_status(card); @@ -1030,18 +969,18 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i data = ~data; data += 1; - if (request_irq(dev->irq, mm_interrupt, IRQF_SHARED, DRIVER_NAME, card)) { + if (request_irq(dev->irq, mm_interrupt, IRQF_SHARED, DRIVER_NAME, + card)) { dev_printk(KERN_ERR, &card->dev->dev, "Unable to allocate IRQ\n"); ret = -ENODEV; - goto failed_req_irq; } dev_printk(KERN_INFO, &card->dev->dev, "Window size %d bytes, IRQ %d\n", data, dev->irq); - spin_lock_init(&card->lock); + spin_lock_init(&card->lock); pci_set_drvdata(dev, card); @@ -1060,7 +999,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i if (!get_userbit(card, MEMORY_INITIALIZED)) { dev_printk(KERN_INFO, &card->dev->dev, - "memory NOT initialized. Consider over-writing whole device.\n"); + "memory NOT initialized. Consider over-writing whole device.\n"); card->init_size = 0; } else { dev_printk(KERN_INFO, &card->dev->dev, @@ -1091,11 +1030,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i return ret; } -/* ------------------------------------------------------------------------------------ --- mm_pci_remove ------------------------------------------------------------------------------------ -*/ + static void mm_pci_remove(struct pci_dev *dev) { struct cardinfo *card = pci_get_drvdata(dev); @@ -1119,16 +1054,16 @@ static void mm_pci_remove(struct pci_dev *dev) } static const struct pci_device_id mm_pci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_5415CN)}, - {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_5425CN)}, - {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_6155)}, + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY, PCI_DEVICE_ID_MICRO_MEMORY_5415CN)}, + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY, PCI_DEVICE_ID_MICRO_MEMORY_5425CN)}, + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY, PCI_DEVICE_ID_MICRO_MEMORY_6155)}, { .vendor = 0x8086, .device = 0xB555, - .subvendor= 0x1332, - .subdevice= 0x5460, - .class = 0x050000, - .class_mask= 0, + .subvendor = 0x1332, + .subdevice = 0x5460, + .class = 0x050000, + .class_mask = 0, }, { /* end: all zeroes */ } }; @@ -1141,12 +1076,6 @@ static struct pci_driver mm_pci_driver = { .remove = mm_pci_remove, }; -/* ------------------------------------------------------------------------------------ --- mm_init ------------------------------------------------------------------------------------ -*/ - static int __init mm_init(void) { int retval, i; @@ -1193,18 +1122,14 @@ out: put_disk(mm_gendisk[i]); return -ENOMEM; } -/* ------------------------------------------------------------------------------------ --- mm_cleanup ------------------------------------------------------------------------------------ -*/ + static void __exit mm_cleanup(void) { int i; del_battery_timer(); - for (i=0; i < num_cards ; i++) { + for (i = 0; i < num_cards ; i++) { del_gendisk(mm_gendisk[i]); put_disk(mm_gendisk[i]); } diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 9b6fbf044fd8..3fa7c77d9bd9 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -269,7 +269,7 @@ config DM_MULTIPATH_RDAC config DM_MULTIPATH_HP tristate "HP MSA multipath support (EXPERIMENTAL)" - depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL + depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL ---help--- Multipath support for HP MSA (Active/Passive) series hardware. diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 28c6ae095c56..6b66ee46b87d 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -398,7 +398,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) struct bio *clone; unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; - unsigned int i; + unsigned i, len; + struct page *page; clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); if (!clone) @@ -407,10 +408,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) clone_init(io, clone); for (i = 0; i < nr_iovecs; i++) { - struct bio_vec *bv = bio_iovec_idx(clone, i); - - bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask); - if (!bv->bv_page) + page = mempool_alloc(cc->page_pool, gfp_mask); + if (!page) break; /* @@ -421,15 +420,14 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) if (i == (MIN_BIO_PAGES - 1)) gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; - bv->bv_offset = 0; - if (size > PAGE_SIZE) - bv->bv_len = PAGE_SIZE; - else - bv->bv_len = size; + len = (size > PAGE_SIZE) ? PAGE_SIZE : size; + + if (!bio_add_page(clone, page, len, 0)) { + mempool_free(page, cc->page_pool); + break; + } - clone->bi_size += bv->bv_len; - clone->bi_vcnt++; - size -= bv->bv_len; + size -= len; } if (!clone->bi_size) { @@ -511,6 +509,9 @@ static void crypt_endio(struct bio *clone, int error) struct crypt_config *cc = io->target->private; unsigned read_io = bio_data_dir(clone) == READ; + if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error)) + error = -EIO; + /* * free the processed pages */ @@ -519,10 +520,8 @@ static void crypt_endio(struct bio *clone, int error) goto out; } - if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) { - error = -EIO; + if (unlikely(error)) goto out; - } bio_put(clone); kcryptd_queue_crypt(io); diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 138200bf5e0b..9627fa0f9470 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -332,6 +332,8 @@ static int dm_hash_rename(const char *old, const char *new) dm_table_put(table); } + dm_kobject_uevent(hc->md); + dm_put(hc->md); up_write(&_hash_lock); kfree(old_name); @@ -1250,21 +1252,17 @@ static int target_message(struct dm_ioctl *param, size_t param_size) if (!table) goto out_argv; - if (tmsg->sector >= dm_table_get_size(table)) { + ti = dm_table_find_target(table, tmsg->sector); + if (!dm_target_is_valid(ti)) { DMWARN("Target message sector outside device."); r = -EINVAL; - goto out_table; - } - - ti = dm_table_find_target(table, tmsg->sector); - if (ti->type->message) + } else if (ti->type->message) r = ti->type->message(ti, argc, argv); else { DMWARN("Target type does not support messages"); r = -EINVAL; } - out_table: dm_table_put(table); out_argv: kfree(argv); diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index e298d8d11f24..47818d8249cb 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -99,6 +99,9 @@ static void combine_restrictions_low(struct io_restrictions *lhs, lhs->max_segment_size = min_not_zero(lhs->max_segment_size, rhs->max_segment_size); + lhs->max_hw_sectors = + min_not_zero(lhs->max_hw_sectors, rhs->max_hw_sectors); + lhs->seg_boundary_mask = min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); @@ -189,8 +192,10 @@ static int alloc_targets(struct dm_table *t, unsigned int num) /* * Allocate both the target array and offset array at once. + * Append an empty entry to catch sectors beyond the end of + * the device. */ - n_highs = (sector_t *) dm_vcalloc(num, sizeof(struct dm_target) + + n_highs = (sector_t *) dm_vcalloc(num + 1, sizeof(struct dm_target) + sizeof(sector_t)); if (!n_highs) return -ENOMEM; @@ -564,6 +569,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) rs->max_segment_size = min_not_zero(rs->max_segment_size, q->max_segment_size); + rs->max_hw_sectors = + min_not_zero(rs->max_hw_sectors, q->max_hw_sectors); + rs->seg_boundary_mask = min_not_zero(rs->seg_boundary_mask, q->seg_boundary_mask); @@ -701,6 +709,8 @@ static void check_for_valid_limits(struct io_restrictions *rs) { if (!rs->max_sectors) rs->max_sectors = SAFE_MAX_SECTORS; + if (!rs->max_hw_sectors) + rs->max_hw_sectors = SAFE_MAX_SECTORS; if (!rs->max_phys_segments) rs->max_phys_segments = MAX_PHYS_SEGMENTS; if (!rs->max_hw_segments) @@ -867,6 +877,9 @@ struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index) /* * Search the btree for the correct target. + * + * Caller should check returned pointer with dm_target_is_valid() + * to trap I/O beyond end of device. */ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector) { @@ -896,6 +909,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) q->max_hw_segments = t->limits.max_hw_segments; q->hardsect_size = t->limits.hardsect_size; q->max_segment_size = t->limits.max_segment_size; + q->max_hw_sectors = t->limits.max_hw_sectors; q->seg_boundary_mask = t->limits.seg_boundary_mask; q->bounce_pfn = t->limits.bounce_pfn; if (t->limits.no_cluster) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 07cbbb8eb3e0..88c0fd657825 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -672,13 +672,19 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector, return clone; } -static void __clone_and_map(struct clone_info *ci) +static int __clone_and_map(struct clone_info *ci) { struct bio *clone, *bio = ci->bio; - struct dm_target *ti = dm_table_find_target(ci->map, ci->sector); - sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti); + struct dm_target *ti; + sector_t len = 0, max; struct dm_target_io *tio; + ti = dm_table_find_target(ci->map, ci->sector); + if (!dm_target_is_valid(ti)) + return -EIO; + + max = max_io_len(ci->md, ci->sector, ti); + /* * Allocate a target io object. */ @@ -736,6 +742,9 @@ static void __clone_and_map(struct clone_info *ci) do { if (offset) { ti = dm_table_find_target(ci->map, ci->sector); + if (!dm_target_is_valid(ti)) + return -EIO; + max = max_io_len(ci->md, ci->sector, ti); tio = alloc_tio(ci->md); @@ -759,6 +768,8 @@ static void __clone_and_map(struct clone_info *ci) ci->idx++; } + + return 0; } /* @@ -767,6 +778,7 @@ static void __clone_and_map(struct clone_info *ci) static int __split_bio(struct mapped_device *md, struct bio *bio) { struct clone_info ci; + int error = 0; ci.map = dm_get_table(md); if (unlikely(!ci.map)) @@ -784,11 +796,11 @@ static int __split_bio(struct mapped_device *md, struct bio *bio) ci.idx = bio->bi_idx; start_io_acct(ci.io); - while (ci.sector_count) - __clone_and_map(&ci); + while (ci.sector_count && !error) + error = __clone_and_map(&ci); /* drop the extra reference count */ - dec_pending(ci.io, 0); + dec_pending(ci.io, error); dm_table_put(ci.map); return 0; @@ -1502,7 +1514,7 @@ int dm_resume(struct mapped_device *md) dm_table_unplug_all(map); - kobject_uevent(&md->disk->kobj, KOBJ_CHANGE); + dm_kobject_uevent(md); r = 0; @@ -1516,6 +1528,11 @@ out: /*----------------------------------------------------------------- * Event notification. *---------------------------------------------------------------*/ +void dm_kobject_uevent(struct mapped_device *md) +{ + kobject_uevent(&md->disk->kobj, KOBJ_CHANGE); +} + uint32_t dm_next_uevent_seq(struct mapped_device *md) { return atomic_add_return(1, &md->uevent_seq); diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 4b3faa45277e..b4584a39383b 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -112,6 +112,11 @@ int dm_table_resume_targets(struct dm_table *t); int dm_table_any_congested(struct dm_table *t, int bdi_bits); void dm_table_unplug_all(struct dm_table *t); +/* + * To check the return value from dm_table_find_target(). + */ +#define dm_target_is_valid(t) ((t)->table) + /*----------------------------------------------------------------- * A registry of target types. *---------------------------------------------------------------*/ @@ -182,4 +187,6 @@ union map_info *dm_get_mapinfo(struct bio *bio); int dm_open_count(struct mapped_device *md); int dm_lock_for_deletion(struct mapped_device *md); +void dm_kobject_uevent(struct mapped_device *md); + #endif diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ff59d2e0475b..785bbdcf4a58 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -7,6 +7,10 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. + * + * Thanks to the following companies for their support: + * + * - JMicron (hardware and technical support) */ #include <linux/delay.h> @@ -26,13 +30,29 @@ static unsigned int debug_quirks = 0; +/* + * Different quirks to handle when the hardware deviates from a strict + * interpretation of the SDHCI specification. + */ + +/* Controller doesn't honor resets unless we touch the clock register */ #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) +/* Controller has bad caps bits, but really supports DMA */ #define SDHCI_QUIRK_FORCE_DMA (1<<1) /* Controller doesn't like some resets when there is no card inserted. */ #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) +/* Controller doesn't like clearing the power reg before a change */ #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) +/* Controller has flaky internal state so reset it on each ios change */ #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) +/* Controller has an unusable DMA engine */ #define SDHCI_QUIRK_BROKEN_DMA (1<<5) +/* Controller can only DMA from 32-bit aligned addresses */ +#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) +/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ +#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) +/* Controller needs to be reset after each request to stay stable */ +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) static const struct pci_device_id pci_ids[] __devinitdata = { { @@ -97,6 +117,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = { SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, }, + { + .vendor = PCI_VENDOR_ID_JMICRON, + .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, @@ -419,7 +449,29 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); - if (host->flags & SDHCI_USE_DMA) { + if (host->flags & SDHCI_USE_DMA) + host->flags |= SDHCI_REQ_USE_DMA; + + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && + (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && + ((data->blksz * data->blocks) & 0x3))) { + DBG("Reverting to PIO because of transfer size (%d)\n", + data->blksz * data->blocks); + host->flags &= ~SDHCI_REQ_USE_DMA; + } + + /* + * The assumption here being that alignment is the same after + * translation to device address space. + */ + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && + (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && + (data->sg->offset & 0x3))) { + DBG("Reverting to PIO because of bad alignment\n"); + host->flags &= ~SDHCI_REQ_USE_DMA; + } + + if (host->flags & SDHCI_REQ_USE_DMA) { int count; count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, @@ -456,7 +508,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, mode |= SDHCI_TRNS_MULTI; if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; - if (host->flags & SDHCI_USE_DMA) + if (host->flags & SDHCI_REQ_USE_DMA) mode |= SDHCI_TRNS_DMA; writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); @@ -472,7 +524,7 @@ static void sdhci_finish_data(struct sdhci_host *host) data = host->data; host->data = NULL; - if (host->flags & SDHCI_USE_DMA) { + if (host->flags & SDHCI_REQ_USE_DMA) { pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); } @@ -886,7 +938,8 @@ static void sdhci_tasklet_finish(unsigned long param) */ if (mrq->cmd->error || (mrq->data && (mrq->data->error || - (mrq->data->stop && mrq->data->stop->error)))) { + (mrq->data->stop && mrq->data->stop->error))) || + (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { /* Some controllers need this kick or reset won't work here */ if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { @@ -1284,7 +1337,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) version = readw(host->ioaddr + SDHCI_HOST_VERSION); version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; - if (version != 0) { + if (version > 1) { printk(KERN_ERR "%s: Unknown controller version (%d). " "You may experience problems.\n", host->slot_descr, version); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 05195ea900f4..e4d77b038bfa 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -171,7 +171,8 @@ struct sdhci_host { spinlock_t lock; /* Mutex */ int flags; /* Host attributes */ -#define SDHCI_USE_DMA (1<<0) +#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ +#define SDHCI_REQ_USE_DMA (1<<1) /* Use DMA for this req. */ unsigned int max_clk; /* Max possible freq (MHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */ diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 70f48a1a6d58..b31d1c95c9fb 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -906,8 +906,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev } pci_set_master(pDev); - if (pci_set_dma_mask(pDev, DMA_64BIT_MASK) && - pci_set_dma_mask(pDev, DMA_32BIT_MASK)) + if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) return -EINVAL; base_addr0_phys = pci_resource_start(pDev,0); diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 4c4465d39a1d..01bf0189367d 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -2616,6 +2616,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) { sg->data = cpu_to_le32((u32)sg_dma_address(sglist)); total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist)); + ++sg; } cblk->buflen = (scsi_bufflen(cmnd) > total_len) ? @@ -2867,6 +2868,7 @@ static int initio_probe_one(struct pci_dev *pdev, } host = (struct initio_host *)shost->hostdata; memset(host, 0, sizeof(struct initio_host)); + host->addr = pci_resource_start(pdev, 0); if (!request_region(host->addr, 256, "i91u")) { printk(KERN_WARNING "initio: I/O port range 0x%x is busy.\n", host->addr); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 98dfd6ea209c..328c47c6aeb1 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3611,6 +3611,7 @@ static struct st_buffer * tb->dma = need_dma; tb->buffer_size = got; + sg_init_table(tb->sg, max_sg); return tb; } diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 0f74aba5b237..9e0908d1981a 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1243,7 +1243,7 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) * Free O/S specific resources. */ if (pdev->irq) - free_irq(pdev->irq, np); + free_irq(pdev->irq, np->s.host); if (np->s.ioaddr) pci_iounmap(pdev, np->s.ioaddr); if (np->s.ramaddr) diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 463f119f20e9..254bdaeb35ff 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -2791,7 +2791,7 @@ irqreturn_t sym_interrupt(struct Scsi_Host *shost) istat = INB(np, nc_istat); if (istat & INTF) { OUTB(np, nc_istat, (istat & SIGP) | INTF | np->istat_sem); - istat = INB(np, nc_istat); /* DUMMY READ */ + istat |= INB(np, nc_istat); /* DUMMY READ */ if (DEBUG_FLAGS & DEBUG_TINY) printf ("F "); sym_wakeup_done(np); } diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 9c56c492a693..b3128903d673 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -51,7 +51,8 @@ #define L1GPU_DISPLAY_SYNC_HSYNC 1 #define L1GPU_DISPLAY_SYNC_VSYNC 2 -#define GPU_CMD_BUF_SIZE (64 * 1024) +#define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) +#define GPU_FB_START (64 * 1024) #define GPU_IOIF (0x0d000000UL) #define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64) #define GPU_MAX_LINE_LENGTH (65536 - 64) @@ -406,6 +407,7 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset, if (src_line_length != dst_line_length) line_length |= (u64)src_line_length << 32; + src_offset += GPU_FB_START; status = lv1_gpu_context_attribute(ps3fb.context_handle, L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, dst_offset, GPU_IOIF + src_offset, @@ -976,9 +978,8 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev) status = lv1_gpu_context_attribute(ps3fb.context_handle, L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, - xdr_lpar + ps3fb.xdr_size, - GPU_CMD_BUF_SIZE, - GPU_IOIF + ps3fb.xdr_size, 0); + xdr_lpar, GPU_CMD_BUF_SIZE, + GPU_IOIF, 0); if (status) { dev_err(dev, "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", @@ -1061,6 +1062,11 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) struct task_struct *task; unsigned long max_ps3fb_size; + if (ps3fb_videomemory.size < GPU_CMD_BUF_SIZE) { + dev_err(&dev->core, "%s: Not enough video memory\n", __func__); + return -ENOMEM; + } + status = ps3_open_hv_device(dev); if (status) { dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", @@ -1131,8 +1137,14 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) /* Clear memory to prevent kernel info leakage into userspace */ memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); - /* The GPU command buffer is at the end of video memory */ - ps3fb.xdr_size = ps3fb_videomemory.size - GPU_CMD_BUF_SIZE; + /* + * The GPU command buffer is at the start of video memory + * As we don't use the full command buffer, we can put the actual + * frame buffer at offset GPU_FB_START and save some precious XDR + * memory + */ + ps3fb.xdr_ea += GPU_FB_START; + ps3fb.xdr_size = ps3fb_videomemory.size - GPU_FB_START; retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); if (retval) @@ -1200,7 +1212,7 @@ err_fb_dealloc: err_framebuffer_release: framebuffer_release(info); err_free_irq: - free_irq(ps3fb.irq_no, dev); + free_irq(ps3fb.irq_no, &dev->core); ps3_irq_plug_destroy(ps3fb.irq_no); err_iounmap_dinfo: iounmap((u8 __iomem *)ps3fb.dinfo); @@ -1235,7 +1247,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) kthread_stop(task); } if (ps3fb.irq_no) { - free_irq(ps3fb.irq_no, dev); + free_irq(ps3fb.irq_no, &dev->core); ps3_irq_plug_destroy(ps3fb.irq_no); } iounmap((u8 __iomem *)ps3fb.dinfo); diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index e176d195e7e5..7596e1e94cde 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -319,7 +319,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->free_area_cache = current->mm->mmap_base; current->mm->cached_hole_size = 0; - current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; #ifdef __sparc__ diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h index a977affaebec..a1b9719f5fbb 100644 --- a/include/asm-ia64/bitops.h +++ b/include/asm-ia64/bitops.h @@ -124,10 +124,21 @@ clear_bit_unlock (int nr, volatile void *addr) /** * __clear_bit_unlock - Non-atomically clear a bit with release * - * This is like clear_bit_unlock, but the implementation may use a non-atomic - * store (this one uses an atomic, however). + * This is like clear_bit_unlock, but the implementation uses a store + * with release semantics. See also __raw_spin_unlock(). */ -#define __clear_bit_unlock clear_bit_unlock +static __inline__ void +__clear_bit_unlock(int nr, volatile void *addr) +{ + __u32 mask, new; + volatile __u32 *m; + + m = (volatile __u32 *)addr + (nr >> 5); + mask = ~(1 << (nr & 31)); + new = *m & mask; + barrier(); + ia64_st4_rel_nta(m, new); +} /** * __clear_bit - Clears a bit in memory (non-atomic version) diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h index 4fb4e439b05c..e58d3298fa10 100644 --- a/include/asm-ia64/gcc_intrin.h +++ b/include/asm-ia64/gcc_intrin.h @@ -191,6 +191,11 @@ register unsigned long ia64_r13 asm ("r13") __attribute_used__; asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \ }) +#define ia64_st4_rel_nta(m, val) \ +({ \ + asm volatile ("st4.rel.nta [%0] = %1\n\t" :: "r"(m), "r"(val)); \ +}) + #define ia64_stfs(x, regnum) \ ({ \ register double __f__ asm ("f"#regnum); \ diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index bba5baa3c7fc..7e6e3779670a 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h @@ -63,7 +63,7 @@ extern int ia64_last_device_vector; #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) #define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */ -#define IA64_PERFMON_VECTOR 0xee /* performanc monitor interrupt vector */ +#define IA64_PERFMON_VECTOR 0xee /* performance monitor interrupt vector */ #define IA64_TIMER_VECTOR 0xef /* use highest-prio group 15 interrupt for timer */ #define IA64_MCA_WAKEUP_VECTOR 0xf0 /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */ #define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */ diff --git a/include/asm-ia64/intel_intrin.h b/include/asm-ia64/intel_intrin.h index d069b6acddce..a520d103d808 100644 --- a/include/asm-ia64/intel_intrin.h +++ b/include/asm-ia64/intel_intrin.h @@ -110,6 +110,9 @@ #define ia64_st4_rel __st4_rel #define ia64_st8_rel __st8_rel +/* FIXME: need st4.rel.nta intrinsic */ +#define ia64_st4_rel_nta __st4_rel + #define ia64_ld1_acq __ld1_acq #define ia64_ld2_acq __ld2_acq #define ia64_ld4_acq __ld4_acq diff --git a/include/asm-ia64/sn/bte.h b/include/asm-ia64/sn/bte.h index 5335d87ca5f8..a0d214f43115 100644 --- a/include/asm-ia64/sn/bte.h +++ b/include/asm-ia64/sn/bte.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. */ @@ -150,6 +150,35 @@ typedef enum { BTEFAIL_NOTAVAIL, /* BTE not available */ } bte_result_t; +#define BTEFAIL_SH2_RESP_SHORT 0x1 /* bit 000001 */ +#define BTEFAIL_SH2_RESP_LONG 0x2 /* bit 000010 */ +#define BTEFAIL_SH2_RESP_DSP 0x4 /* bit 000100 */ +#define BTEFAIL_SH2_RESP_ACCESS 0x8 /* bit 001000 */ +#define BTEFAIL_SH2_CRB_TO 0x10 /* bit 010000 */ +#define BTEFAIL_SH2_NACK_LIMIT 0x20 /* bit 100000 */ +#define BTEFAIL_SH2_ALL 0x3F /* bit 111111 */ + +#define BTE_ERR_BITS 0x3FUL +#define BTE_ERR_SHIFT 36 +#define BTE_ERR_MASK (BTE_ERR_BITS << BTE_ERR_SHIFT) + +#define BTE_ERROR_RETRY(value) \ + (is_shub2() ? (value != BTEFAIL_SH2_CRB_TO) \ + : (value != BTEFAIL_TOUT)) + +/* + * On shub1 BTE_ERR_MASK will always be false, so no need for is_shub2() + */ +#define BTE_SHUB2_ERROR(_status) \ + ((_status & BTE_ERR_MASK) \ + ? (((_status >> BTE_ERR_SHIFT) & BTE_ERR_BITS) | IBLS_ERROR) \ + : _status) + +#define BTE_GET_ERROR_STATUS(_status) \ + (BTE_SHUB2_ERROR(_status) & ~IBLS_ERROR) + +#define BTE_VALID_SH2_ERROR(value) \ + ((value >= BTEFAIL_SH2_RESP_SHORT) && (value <= BTEFAIL_SH2_ALL)) /* * Structure defining a bte. An instance of this diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index 6f807e0193b7..f7711b308e48 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h @@ -86,7 +86,7 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification) BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL); ret = bte_copy(src, pdst, len, mode, notification); - if (ret != BTE_SUCCESS) { + if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) { if (!in_interrupt()) { cond_resched(); } @@ -244,7 +244,30 @@ enum xpc_retval { xpcDisconnected, /* 51: channel disconnected (closed) */ - xpcUnknownReason /* 52: unknown reason -- must be last in list */ + xpcBteSh2Start, /* 52: BTE CRB timeout */ + + /* 53: 0x1 BTE Error Response Short */ + xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT, + + /* 54: 0x2 BTE Error Response Long */ + xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG, + + /* 56: 0x4 BTE Error Response DSB */ + xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP, + + /* 60: 0x8 BTE Error Response Access */ + xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS, + + /* 68: 0x10 BTE Error CRB timeout */ + xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO, + + /* 84: 0x20 BTE Error NACK limit */ + xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT, + + /* 115: BTE end */ + xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL, + + xpcUnknownReason /* 116: unknown reason -- must be last in list */ }; diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index e52b8508083b..8e5d7de9c632 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2007 Silicon Graphics, Inc. All Rights Reserved. */ @@ -1211,6 +1211,12 @@ xpc_IPI_init(int index) static inline enum xpc_retval xpc_map_bte_errors(bte_result_t error) { + if (is_shub2()) { + if (BTE_VALID_SH2_ERROR(error)) + return xpcBteSh2Start + error; + else + return xpcBteUnmappedError; + } switch (error) { case BTE_SUCCESS: return xpcSuccess; case BTEFAIL_DIR: return xpcBteDirectoryError; diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h index 80bcb0a38e8a..7774a1cac0cc 100644 --- a/include/asm-ia64/tlbflush.h +++ b/include/asm-ia64/tlbflush.h @@ -92,6 +92,10 @@ void smp_local_flush_tlb(void); #define smp_local_flush_tlb() #endif -#define flush_tlb_kernel_range(start, end) flush_tlb_all() /* XXX fix me */ +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + flush_tlb_all(); /* XXX fix me */ +} #endif /* _ASM_IA64_TLBFLUSH_H */ diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h index b772d5b38685..9fe8f3bddfd5 100644 --- a/include/asm-x86/kprobes_32.h +++ b/include/asm-x86/kprobes_32.h @@ -73,7 +73,7 @@ struct kprobe_ctlblk { unsigned long kprobe_status; unsigned long kprobe_old_eflags; unsigned long kprobe_saved_eflags; - long *jprobe_saved_esp; + unsigned long *jprobe_saved_esp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index 53f4d8507354..743d76218fc9 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h @@ -66,7 +66,7 @@ struct kprobe_ctlblk { unsigned long kprobe_status; unsigned long kprobe_old_rflags; unsigned long kprobe_saved_rflags; - long *jprobe_saved_rsp; + unsigned long *jprobe_saved_rsp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 4cb23848d460..6e9e4841a2da 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -7,6 +7,13 @@ #ifdef __KERNEL__ +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + #define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t" #define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index b8b7c51389fe..e765e191663d 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -115,6 +115,7 @@ struct io_restrictions { unsigned short max_hw_segments; unsigned short hardsect_size; unsigned int max_segment_size; + unsigned int max_hw_sectors; unsigned long seg_boundary_mask; unsigned long bounce_pfn; unsigned char no_cluster; /* inverted so that 0 is default */ diff --git a/include/linux/elevator.h b/include/linux/elevator.h index e8f42133a616..639624b55fbe 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -119,7 +119,7 @@ extern void elv_put_request(struct request_queue *, struct request *); /* * io scheduler registration */ -extern int elv_register(struct elevator_type *); +extern void elv_register(struct elevator_type *); extern void elv_unregister(struct elevator_type *); /* diff --git a/include/linux/irq.h b/include/linux/irq.h index efc88538b2ba..4669be080617 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -339,6 +339,13 @@ extern void __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, const char *name); +/* caller has locked the irq_desc and both params are valid */ +static inline void __set_irq_handler_unlocked(int irq, + irq_flow_handler_t handler) +{ + irq_desc[irq].handle_irq = handler; +} + /* * Set a highlevel flow handler for a given IRQ: */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 125eee1407ff..7ab962fa1d73 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -118,10 +118,6 @@ struct mmc_host { unsigned int removed:1; /* host is being removed */ #endif - unsigned int mode; /* current card mode of host */ -#define MMC_MODE_MMC 0 -#define MMC_MODE_SD 1 - struct mmc_card *card; /* device attached to this host */ wait_queue_head_t wq; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 111aa10f1136..023656d2f1da 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2148,6 +2148,7 @@ #define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 +#define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 #define PCI_VENDOR_ID_KORENIX 0x1982 #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9b5dff6b3f6a..44019ce30a14 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -297,18 +297,13 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) if (unlikely(desc->status & IRQ_INPROGRESS)) goto out_unlock; + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); kstat_cpu(cpu).irqs[irq]++; action = desc->action; - if (unlikely(!action || (desc->status & IRQ_DISABLED))) { - if (desc->chip->mask) - desc->chip->mask(irq); - desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); - desc->status |= IRQ_PENDING; + if (unlikely(!action || (desc->status & IRQ_DISABLED))) goto out_unlock; - } - desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING); desc->status |= IRQ_INPROGRESS; spin_unlock(&desc->lock); diff --git a/kernel/panic.c b/kernel/panic.c index 6f6e03e91595..da4d6bac270e 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -19,6 +19,7 @@ #include <linux/nmi.h> #include <linux/kexec.h> #include <linux/debug_locks.h> +#include <linux/random.h> int panic_on_oops; int tainted; @@ -266,12 +267,29 @@ void oops_enter(void) } /* + * 64-bit random ID for oopses: + */ +static u64 oops_id; + +static int init_oops_id(void) +{ + if (!oops_id) + get_random_bytes(&oops_id, sizeof(oops_id)); + + return 0; +} +late_initcall(init_oops_id); + +/* * Called when the architecture exits its oops handler, after printing * everything. */ void oops_exit(void) { do_oops_enter_exit(); + init_oops_id(); + printk(KERN_WARNING "---[ end trace %016llx ]---\n", + (unsigned long long)oops_id); } #ifdef CONFIG_CC_STACKPROTECTOR diff --git a/kernel/rwsem.c b/kernel/rwsem.c index 1ec620c03064..cae050b05f5e 100644 --- a/kernel/rwsem.c +++ b/kernel/rwsem.c @@ -6,6 +6,7 @@ #include <linux/types.h> #include <linux/kernel.h> +#include <linux/sched.h> #include <linux/module.h> #include <linux/rwsem.h> @@ -15,7 +16,7 @@ /* * lock for reading */ -void down_read(struct rw_semaphore *sem) +void __sched down_read(struct rw_semaphore *sem) { might_sleep(); rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); @@ -42,7 +43,7 @@ EXPORT_SYMBOL(down_read_trylock); /* * lock for writing */ -void down_write(struct rw_semaphore *sem) +void __sched down_write(struct rw_semaphore *sem) { might_sleep(); rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); diff --git a/kernel/sched.c b/kernel/sched.c index c6e551de795b..3df84ea6aba9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -508,10 +508,15 @@ EXPORT_SYMBOL_GPL(cpu_clock); # define finish_arch_switch(prev) do { } while (0) #endif +static inline int task_current(struct rq *rq, struct task_struct *p) +{ + return rq->curr == p; +} + #ifndef __ARCH_WANT_UNLOCKED_CTXSW static inline int task_running(struct rq *rq, struct task_struct *p) { - return rq->curr == p; + return task_current(rq, p); } static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) @@ -540,7 +545,7 @@ static inline int task_running(struct rq *rq, struct task_struct *p) #ifdef CONFIG_SMP return p->oncpu; #else - return rq->curr == p; + return task_current(rq, p); #endif } @@ -663,6 +668,7 @@ void sched_clock_idle_wakeup_event(u64 delta_ns) struct rq *rq = cpu_rq(smp_processor_id()); u64 now = sched_clock(); + touch_softlockup_watchdog(); rq->idle_clock += delta_ns; /* * Override the previous timestamp and ignore all @@ -3334,7 +3340,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) rq = task_rq_lock(p, &flags); ns = p->se.sum_exec_runtime; - if (rq->curr == p) { + if (task_current(rq, p)) { update_rq_clock(rq); delta_exec = rq->clock - p->se.exec_start; if ((s64)delta_exec > 0) @@ -4021,7 +4027,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) oldprio = p->prio; on_rq = p->se.on_rq; - running = task_running(rq, p); + running = task_current(rq, p); if (on_rq) { dequeue_task(rq, p, 0); if (running) @@ -4332,7 +4338,7 @@ recheck: } update_rq_clock(rq); on_rq = p->se.on_rq; - running = task_running(rq, p); + running = task_current(rq, p); if (on_rq) { deactivate_task(rq, p, 0); if (running) @@ -7101,7 +7107,7 @@ void sched_move_task(struct task_struct *tsk) update_rq_clock(rq); - running = task_running(rq, tsk); + running = task_current(rq, tsk); on_rq = tsk->se.on_rq; if (on_rq) { diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index c33f0ceb3de9..da7c061e7206 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -511,8 +511,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) if (!initial) { /* sleeps upto a single latency don't count. */ - if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se) && - task_of(se)->policy != SCHED_BATCH) + if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se)) vruntime -= sysctl_sched_latency; /* ensure we never gain time by being placed backwards. */ diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index ee9c8b6529e9..9ba3daa03475 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -208,6 +208,8 @@ move_one_task_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, static void task_tick_rt(struct rq *rq, struct task_struct *p) { + update_curr_rt(rq); + /* * RR tasks need a special form of timeslice management. * FIFO tasks have no timeslices. diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 1135de730872..c68f68dcc605 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -225,10 +225,10 @@ static struct ctl_table root_table[] = { }; #ifdef CONFIG_SCHED_DEBUG -static unsigned long min_sched_granularity_ns = 100000; /* 100 usecs */ -static unsigned long max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ -static unsigned long min_wakeup_granularity_ns; /* 0 usecs */ -static unsigned long max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ +static int min_sched_granularity_ns = 100000; /* 100 usecs */ +static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ +static int min_wakeup_granularity_ns; /* 0 usecs */ +static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ #endif static struct ctl_table kern_table[] = { diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index aa82d7bf478a..5b86698faa0b 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -384,45 +384,19 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc) } /* - * Reprogram the broadcast device: - * - * Called with tick_broadcast_lock held and interrupts disabled. - */ -static int tick_broadcast_reprogram(void) -{ - ktime_t expires = { .tv64 = KTIME_MAX }; - struct tick_device *td; - int cpu; - - /* - * Find the event which expires next: - */ - for (cpu = first_cpu(tick_broadcast_oneshot_mask); cpu != NR_CPUS; - cpu = next_cpu(cpu, tick_broadcast_oneshot_mask)) { - td = &per_cpu(tick_cpu_device, cpu); - if (td->evtdev->next_event.tv64 < expires.tv64) - expires = td->evtdev->next_event; - } - - if (expires.tv64 == KTIME_MAX) - return 0; - - return tick_broadcast_set_event(expires, 0); -} - -/* * Handle oneshot mode broadcasting */ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) { struct tick_device *td; cpumask_t mask; - ktime_t now; + ktime_t now, next_event; int cpu; spin_lock(&tick_broadcast_lock); again: dev->next_event.tv64 = KTIME_MAX; + next_event.tv64 = KTIME_MAX; mask = CPU_MASK_NONE; now = ktime_get(); /* Find all expired events */ @@ -431,19 +405,31 @@ again: td = &per_cpu(tick_cpu_device, cpu); if (td->evtdev->next_event.tv64 <= now.tv64) cpu_set(cpu, mask); + else if (td->evtdev->next_event.tv64 < next_event.tv64) + next_event.tv64 = td->evtdev->next_event.tv64; } /* - * Wakeup the cpus which have an expired event. The broadcast - * device is reprogrammed in the return from idle code. + * Wakeup the cpus which have an expired event. + */ + tick_do_broadcast(mask); + + /* + * Two reasons for reprogram: + * + * - The global event did not expire any CPU local + * events. This happens in dyntick mode, as the maximum PIT + * delta is quite small. + * + * - There are pending events on sleeping CPUs which were not + * in the event mask */ - if (!tick_do_broadcast(mask)) { + if (next_event.tv64 != KTIME_MAX) { /* - * The global event did not expire any CPU local - * events. This happens in dyntick mode, as the - * maximum PIT delta is quite small. + * Rearm the broadcast device. If event expired, + * repeat the above */ - if (tick_broadcast_reprogram()) + if (tick_broadcast_set_event(next_event, 0)) goto again; } spin_unlock(&tick_broadcast_lock); diff --git a/kernel/timer.c b/kernel/timer.c index a05817c021d6..d4527dcef1af 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1219,11 +1219,11 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) */ static struct lock_class_key base_lock_keys[NR_CPUS]; -static int __devinit init_timers_cpu(int cpu) +static int __cpuinit init_timers_cpu(int cpu) { int j; tvec_base_t *base; - static char __devinitdata tvec_base_done[NR_CPUS]; + static char __cpuinitdata tvec_base_done[NR_CPUS]; if (!tvec_base_done[cpu]) { static char boot_done; diff --git a/lib/rwsem.c b/lib/rwsem.c index cdb4e3d05607..7d02700a4b0e 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c @@ -146,7 +146,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) /* * wait for a lock to be granted */ -static struct rw_semaphore * +static struct rw_semaphore __sched * rwsem_down_failed_common(struct rw_semaphore *sem, struct rwsem_waiter *waiter, signed long adjustment) { diff --git a/mm/filemap.c b/mm/filemap.c index 188cf5fd3e8d..f4d0cded0e10 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -124,6 +124,18 @@ void __remove_from_page_cache(struct page *page) mapping->nrpages--; __dec_zone_page_state(page, NR_FILE_PAGES); BUG_ON(page_mapped(page)); + + /* + * Some filesystems seem to re-dirty the page even after + * the VM has canceled the dirty bit (eg ext3 journaling). + * + * Fix it up by doing a final dirty accounting check after + * having removed the page entirely. + */ + if (PageDirty(page) && mapping_cap_account_dirty(mapping)) { + dec_zone_page_state(page, NR_FILE_DIRTY); + dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); + } } void remove_from_page_cache(struct page *page) |