diff options
114 files changed, 814 insertions, 405 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 75205391b335..bad5987c4727 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1284,6 +1284,19 @@ running once the system is up. New name for the ramdisk parameter. See Documentation/ramdisk.txt. + rcu.blimit= [KNL,BOOT] Set maximum number of finished + RCU callbacks to process in one batch. + + rcu.qhimark= [KNL,BOOT] Set threshold of queued + RCU callbacks over which batch limiting is disabled. + + rcu.qlowmark= [KNL,BOOT] Set threshold of queued + RCU callbacks below which batch limiting is re-enabled. + + rcu.rsinterval= [KNL,BOOT,SMP] Set the number of additional + RCU callbacks to queued before forcing reschedule + on all cpus. + rdinit= [KNL] Format: <full_path> Run specified binary instead of /init from the ramdisk, diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15dc1a0dffbb..9f80fa502f8f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -78,7 +78,7 @@ menu "System Type" choice prompt "ARM system type" - default ARCH_RPC + default ARCH_VERSATILE config ARCH_CLPS7500 bool "Cirrus-CL-PS7500FE" diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index d7d932c02866..d6bd435a6857 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -422,12 +422,14 @@ static int timer_dyn_tick_disable(void) void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; + unsigned long next, seq; - if (dyn_tick) { - write_seqlock(&xtime_lock); - if (dyn_tick->state & DYN_TICK_ENABLED) + if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { + next = next_timer_interrupt(); + do { + seq = read_seqbegin(&xtime_lock); dyn_tick->reprogram(next_timer_interrupt() - jiffies); - write_sequnlock(&xtime_lock); + } while (read_seqretry(&xtime_lock, seq)); } } diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c index 2bec69bfa715..99d333d7ebdd 100644 --- a/arch/arm/mach-ixp4xx/nas100d-power.c +++ b/arch/arm/mach-ixp4xx/nas100d-power.c @@ -56,6 +56,9 @@ static int __init nas100d_power_init(void) static void __exit nas100d_power_exit(void) { + if (!(machine_is_nas100d())) + return; + free_irq(NAS100D_RB_IRQ, NULL); } diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index 6f76b89ef46e..fd6adde39091 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S @@ -80,6 +80,7 @@ ENTRY(v6wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b + mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier mov pc, lr .section ".text.init", #alloc, #execinstr diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index ed79ae20e88d..dd344f112cfe 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -45,6 +45,9 @@ #include <asm/setup.h> #include <asm/pgtable.h> +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + asmlinkage void ret_from_fork(void); /* diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 4ecd4b326ded..e6bd095ae108 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -278,10 +278,10 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; c->x86_model = (tfms >> 4) & 15; - if (c->x86 == 0xf) { + if (c->x86 == 0xf) c->x86 += (tfms >> 20) & 0xff; + if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; - } c->x86_mask = tfms & 15; } else { /* Have CPUID level 0 only - unheard of */ diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index e3e42fd62401..c9cad7ba0d2d 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -70,10 +70,13 @@ static void efi_call_phys_prelog(void) { unsigned long cr4; unsigned long temp; + struct Xgt_desc_struct *cpu_gdt_descr; spin_lock(&efi_rt_lock); local_irq_save(efi_rt_eflags); + cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); + /* * If I don't have PSE, I should just duplicate two entries in page * directory. If I have PSE, I just need to duplicate one entry in @@ -103,18 +106,17 @@ static void efi_call_phys_prelog(void) */ local_flush_tlb(); - per_cpu(cpu_gdt_descr, 0).address = - __pa(per_cpu(cpu_gdt_descr, 0).address); - load_gdt((struct Xgt_desc_struct *)__pa(&per_cpu(cpu_gdt_descr, 0))); + cpu_gdt_descr->address = __pa(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); } static void efi_call_phys_epilog(void) { unsigned long cr4; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); - per_cpu(cpu_gdt_descr, 0).address = - (unsigned long)__va(per_cpu(cpu_gdt_descr, 0).address); - load_gdt((struct Xgt_desc_struct *)__va(&per_cpu(cpu_gdt_descr, 0))); + cpu_gdt_descr->address = __va(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); cr4 = read_cr4(); diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index a912fed48482..f73d7374a2ba 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c @@ -116,13 +116,13 @@ static void load_segments(void) __asm__ __volatile__ ( "\tljmp $"STR(__KERNEL_CS)",$1f\n" "\t1:\n" - "\tmovl $"STR(__KERNEL_DS)",%eax\n" - "\tmovl %eax,%ds\n" - "\tmovl %eax,%es\n" - "\tmovl %eax,%fs\n" - "\tmovl %eax,%gs\n" - "\tmovl %eax,%ss\n" - ); + "\tmovl $"STR(__KERNEL_DS)",%%eax\n" + "\tmovl %%eax,%%ds\n" + "\tmovl %%eax,%%es\n" + "\tmovl %%eax,%%fs\n" + "\tmovl %%eax,%%gs\n" + "\tmovl %%eax,%%ss\n" + ::: "eax", "memory"); #undef STR #undef __STR } diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 63f39a7e2c96..be87c5e2ee95 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -357,7 +357,7 @@ static void clear_msr_range(unsigned int base, unsigned int n) wrmsr(base+i, 0, 0); } -static inline void write_watchdog_counter(const char *descr) +static void write_watchdog_counter(const char *descr) { u64 count = (u64)cpu_khz * 1000; @@ -544,7 +544,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) * die_nmi will return ONLY if NOTIFY_STOP happens.. */ die_nmi(regs, "NMI Watchdog detected LOCKUP"); - + } else { last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; } diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index a14d594bfbeb..9d3074759856 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -412,9 +412,9 @@ static int timer_resume(struct sys_device *dev) write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = sec; xtime.tv_nsec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); - jiffies += sleep_length; + jiffies_64 += sleep_length; wall_jiffies += sleep_length; + write_sequnlock_irqrestore(&xtime_lock, flags); if (last_timer->resume) last_timer->resume(); cur_timer = last_timer; diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 184678fe7832..744fd2f79f61 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16-rc5 -# Mon Feb 27 16:15:43 2006 +# Thu Mar 2 16:39:10 2006 # # @@ -312,7 +312,13 @@ CONFIG_FW_LOADER=m # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -357,6 +363,7 @@ CONFIG_BLK_DEV_IDESCSI=m # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -525,6 +532,7 @@ CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index 6ade3790ce07..e00b21514f7c 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c @@ -36,7 +36,7 @@ int __init init_cyclone_clock(void) u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ if (!use_cyclone) - return -ENODEV; + return 0; printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 8fd93afa75a7..e883d85906db 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -123,8 +123,9 @@ mca_page_isolate(unsigned long paddr) void mca_handler_bh(unsigned long paddr) { - printk(KERN_DEBUG "OS_MCA: process [pid: %d](%s) encounters MCA.\n", - current->pid, current->comm); + printk(KERN_ERR + "OS_MCA: process [pid: %d](%s) encounters MCA (paddr=%lx)\n", + current->pid, current->comm, paddr); spin_lock(&mca_bh_lock); switch (mca_page_isolate(paddr)) { @@ -132,7 +133,7 @@ mca_handler_bh(unsigned long paddr) printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr); break; case ISOLATE_NG: - printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr); + printk(KERN_CRIT "Page isolation: ( %lx ) failure.\n", paddr); break; default: break; @@ -567,10 +568,15 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, return 0; /* - * If there is no bus error, record is weird but we need not to recover. + * The cache check and bus check bits have four possible states + * cc bc + * 0 0 Weird record, not recovered + * 1 0 Cache error, not recovered + * 0 1 I/O error, attempt recovery + * 1 1 Memory error, attempt recovery */ if (psp->bc == 0 || pbci == NULL) - return 1; + return 0; /* * Sorry, we cannot handle so many. diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 24eefb2fc55f..b2e1e746b47f 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -446,7 +446,7 @@ static struct proc_dir_entry *proc_sn2_ptc; static int __init sn2_ptc_init(void) { if (!ia64_platform_is("sn2")) - return -ENOSYS; + return 0; if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 8a56f8b5ffa2..99cb28e74295 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -484,7 +484,7 @@ static int __init tiocx_init(void) int found_tiocx_device = 0; if (!ia64_platform_is("sn2")) - return -ENODEV; + return 0; bus_register(&tiocx_bus_type); diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 11f2cd5af7dc..9b65029dd2a3 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1537,6 +1537,9 @@ _STATIC(__boot_from_prom) mr r28,r6 mr r27,r7 + /* Align the stack to 16-byte boundary for broken yaboot */ + rldicr r1,r1,0,59 + /* Make sure we are running in 64 bits mode */ bl .enable_64b_mode diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S index 88fc94fe6488..5d59e2625048 100644 --- a/arch/s390/lib/uaccess.S +++ b/arch/s390/lib/uaccess.S @@ -198,12 +198,12 @@ __strnlen_user_asm: 0: srst %r2,%r1 jo 0b sacf 0 - jh 1f # \0 found in string ? ahi %r2,1 # strnlen_user result includes the \0 -1: slr %r2,%r3 + # or return count+1 if \0 not found + slr %r2,%r3 br %r14 2: sacf 0 - lhi %r2,-EFAULT + slr %r2,%r2 # return 0 on exception br %r14 .section __ex_table,"a" .long 0b,2b diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S index 50219786fc7a..19b41a33c230 100644 --- a/arch/s390/lib/uaccess64.S +++ b/arch/s390/lib/uaccess64.S @@ -194,12 +194,12 @@ __strnlen_user_asm: 0: srst %r2,%r1 jo 0b sacf 0 - jh 1f # \0 found in string ? aghi %r2,1 # strnlen_user result includes the \0 -1: slgr %r2,%r3 + # or return count+1 if \0 not found + slgr %r2,%r3 br %r14 2: sacf 0 - lghi %r2,-EFAULT + slgr %r2,%r2 # return 0 on exception br %r14 .section __ex_table,"a" .quad 0b,2b diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 60b59375aa78..c4a1cef4b1e5 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -318,7 +318,7 @@ do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) nop nop - .section __ex_table + .section __ex_table,"a" .align 4 .word 1b, __retl_efault, 2b, __retl_efault .word 3b, __retl_efault, 4b, __retl_efault diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S index 1f5b5b708ce7..be183fe41443 100644 --- a/arch/sparc64/kernel/una_asm.S +++ b/arch/sparc64/kernel/una_asm.S @@ -47,7 +47,7 @@ __do_int_store: mov 0, %o0 .size __do_int_store, .-__do_int_store - .section __ex_table + .section __ex_table,"a" .word 4b, __retl_efault .word 5b, __retl_efault .word 6b, __retl_efault @@ -129,7 +129,7 @@ do_int_load: mov 0, %o0 .size __do_int_load, .-__do_int_load - .section __ex_table + .section __ex_table,"a" .word 4b, __retl_efault .word 5b, __retl_efault .word 6b, __retl_efault diff --git a/arch/sparc64/lib/U1copy_from_user.S b/arch/sparc64/lib/U1copy_from_user.S index 93146a81e2d3..3192b0bf4fab 100644 --- a/arch/sparc64/lib/U1copy_from_user.S +++ b/arch/sparc64/lib/U1copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U1copy_to_user.S b/arch/sparc64/lib/U1copy_to_user.S index 1fccc521e2bd..d1210ffb0b82 100644 --- a/arch/sparc64/lib/U1copy_to_user.S +++ b/arch/sparc64/lib/U1copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U3copy_from_user.S b/arch/sparc64/lib/U3copy_from_user.S index df600b667e48..f5bfc8d9d216 100644 --- a/arch/sparc64/lib/U3copy_from_user.S +++ b/arch/sparc64/lib/U3copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U3copy_to_user.S b/arch/sparc64/lib/U3copy_to_user.S index f337f22ed82e..2334f111bb0c 100644 --- a/arch/sparc64/lib/U3copy_to_user.S +++ b/arch/sparc64/lib/U3copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/bzero.S b/arch/sparc64/lib/bzero.S index 21a933ffb7c2..1d2abcfa4e52 100644 --- a/arch/sparc64/lib/bzero.S +++ b/arch/sparc64/lib/bzero.S @@ -92,7 +92,7 @@ __bzero_done: .align 4; \ 99: retl; \ mov %o1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/copy_in_user.S b/arch/sparc64/lib/copy_in_user.S index 816076c0bc06..650af3f21f78 100644 --- a/arch/sparc64/lib/copy_in_user.S +++ b/arch/sparc64/lib/copy_in_user.S @@ -13,7 +13,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/csum_copy_from_user.S b/arch/sparc64/lib/csum_copy_from_user.S index 817ebdae39f8..a22eddbe5dba 100644 --- a/arch/sparc64/lib/csum_copy_from_user.S +++ b/arch/sparc64/lib/csum_copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov -1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/csum_copy_to_user.S b/arch/sparc64/lib/csum_copy_to_user.S index c2f9463ea1e2..d5b12f441f02 100644 --- a/arch/sparc64/lib/csum_copy_to_user.S +++ b/arch/sparc64/lib/csum_copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov -1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/strlen_user.S b/arch/sparc64/lib/strlen_user.S index 9ed54ba14fc6..114ed111e251 100644 --- a/arch/sparc64/lib/strlen_user.S +++ b/arch/sparc64/lib/strlen_user.S @@ -85,7 +85,7 @@ __strnlen_user: retl clr %o0 - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word 10b, 30b diff --git a/arch/sparc64/lib/strncpy_from_user.S b/arch/sparc64/lib/strncpy_from_user.S index e1264650ca7a..b2f499f79427 100644 --- a/arch/sparc64/lib/strncpy_from_user.S +++ b/arch/sparc64/lib/strncpy_from_user.S @@ -125,7 +125,7 @@ __strncpy_from_user: add %o2, %o3, %o0 .size __strncpy_from_user, .-__strncpy_from_user - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word 60b, __retl_efault .word 61b, __retl_efault diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index eb314ed23cdb..f170324e8bf2 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S @@ -217,7 +217,7 @@ solaris_unimplemented: ba,pt %xcc, ret_from_solaris nop - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word exen, exenf diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c index eb909937958b..621111ddf907 100644 --- a/arch/v850/kernel/process.c +++ b/arch/v850/kernel/process.c @@ -30,6 +30,9 @@ #include <asm/system.h> #include <asm/pgtable.h> +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + extern void ret_from_fork (void); diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index 89fab51e20f4..25ac8a3faae6 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c @@ -140,7 +140,7 @@ static void load_segments(void) "\tmovl %0,%%ss\n" "\tmovl %0,%%fs\n" "\tmovl %0,%%gs\n" - : : "a" (__KERNEL_DS) + : : "a" (__KERNEL_DS) : "memory" ); } diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index f1f596644bfc..64a649eb883f 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -64,6 +64,9 @@ EXPORT_SYMBOL(init_task); struct task_struct *current_set[NR_CPUS] = {&init_task, }; +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + #if XCHAL_CP_NUM > 0 diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 14f6a6201da3..05983a312d50 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -555,7 +555,7 @@ fore200e_pca_reset(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_map(struct fore200e* fore200e) { DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); @@ -589,7 +589,7 @@ fore200e_pca_unmap(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_configure(struct fore200e* fore200e) { struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; @@ -2125,7 +2125,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) } -static int __init +static int __devinit fore200e_irq_request(struct fore200e* fore200e) { if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { @@ -2148,7 +2148,7 @@ fore200e_irq_request(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_get_esi(struct fore200e* fore200e) { struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); @@ -2180,7 +2180,7 @@ fore200e_get_esi(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_alloc_rx_buf(struct fore200e* fore200e) { int scheme, magn, nbr, size, i; @@ -2245,7 +2245,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_bs_queue(struct fore200e* fore200e) { int scheme, magn, i; @@ -2308,7 +2308,7 @@ fore200e_init_bs_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_rx_queue(struct fore200e* fore200e) { struct host_rxq* rxq = &fore200e->host_rxq; @@ -2368,7 +2368,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_tx_queue(struct fore200e* fore200e) { struct host_txq* txq = &fore200e->host_txq; @@ -2431,7 +2431,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_cmd_queue(struct fore200e* fore200e) { struct host_cmdq* cmdq = &fore200e->host_cmdq; @@ -2487,7 +2487,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e, } -static int __init +static int __devinit fore200e_initialize(struct fore200e* fore200e) { struct cp_queues __iomem * cpq; @@ -2539,7 +2539,7 @@ fore200e_initialize(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_putc(struct fore200e* fore200e, char c) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; @@ -2551,7 +2551,7 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c) } -static int __init +static int __devinit fore200e_monitor_getc(struct fore200e* fore200e) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; @@ -2576,7 +2576,7 @@ fore200e_monitor_getc(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_puts(struct fore200e* fore200e, char* str) { while (*str) { @@ -2591,7 +2591,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) } -static int __init +static int __devinit fore200e_start_fw(struct fore200e* fore200e) { int ok; @@ -2622,7 +2622,7 @@ fore200e_start_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_load_fw(struct fore200e* fore200e) { u32* fw_data = (u32*) fore200e->bus->fw_data; @@ -2648,7 +2648,7 @@ fore200e_load_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_register(struct fore200e* fore200e) { struct atm_dev* atm_dev; @@ -2675,7 +2675,7 @@ fore200e_register(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init(struct fore200e* fore200e) { if (fore200e_register(fore200e) < 0) @@ -2721,7 +2721,7 @@ fore200e_init(struct fore200e* fore200e) return -EBUSY; fore200e_supply(fore200e); - + /* all done, board initialization is now complete */ fore200e->state = FORE200E_STATE_COMPLETE; return 0; diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6ede1f352c29..37b8cda3e8bc 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -41,6 +41,7 @@ #include <linux/timer.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/random.h> #include <asm/io.h> #include <asm/uaccess.h> #include "DAC960.h" @@ -3463,7 +3464,7 @@ static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, Command->SegmentCount, Command->DmaDirection); if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { - + add_disk_randomness(Request->rq_disk); end_that_request_last(Request, UpToDate); if (Command->Completion) { diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index b3bc2e37e616..29dc87e59020 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c @@ -131,7 +131,9 @@ enum { rng_hw_none, rng_hw_intel, rng_hw_amd, +#ifdef __i386__ rng_hw_via, +#endif rng_hw_geode, }; diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index c92378121b4c..1b05fa688996 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -675,7 +675,7 @@ static int __init mmtimer_init(void) cnodeid_t node, maxn = -1; if (!ia64_platform_is("sn2")) - return -1; + return 0; /* * Sanity check the cycles/sec variable diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 2d2d4ac3525a..960dae5c87d1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1155,6 +1155,12 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) spin_lock_irq(target->scsi_host->host_lock); + if (target->state == SRP_TARGET_DEAD || + target->state == SRP_TARGET_REMOVED) { + scmnd->result = DID_BAD_TARGET << 16; + goto out; + } + if (scmnd->host_scribble == (void *) -1L) goto out; diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 8159bcecd0c2..df9d65201819 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1929,6 +1929,8 @@ static struct pci_device_id hisax_pci_tbl[] __initdata = { {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, PCI_ANY_ID, PCI_ANY_ID}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID}, diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 4866fc32d8d9..91d25acb5ede 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -51,6 +51,8 @@ static const PCI_ENTRY id_list[] = {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"}, {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index ca5b4a3b683e..262c44127419 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1,7 +1,7 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $ + * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * @@ -45,7 +45,7 @@ #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ "; + "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; /* Hisax debug support * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG @@ -219,7 +219,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) for (i = 0; list[i].name != NULL; i++) if (list[i].num == num) return (list[i].name); - return "<unkown ERROR>"; + return "<unknown ERROR>"; } @@ -235,9 +235,9 @@ ctrl_start_transfer(hfcusb_data * hfc) hfc->ctrl_urb->transfer_buffer = NULL; hfc->ctrl_urb->transfer_buffer_length = 0; hfc->ctrl_write.wIndex = - hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg; + cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg); hfc->ctrl_write.wValue = - hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val; + cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val); usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ } @@ -1282,7 +1282,7 @@ usb_init(hfcusb_data * hfc) /* init the background machinery for control requests */ hfc->ctrl_read.bRequestType = 0xc0; hfc->ctrl_read.bRequest = 1; - hfc->ctrl_read.wLength = 1; + hfc->ctrl_read.wLength = cpu_to_le16(1); hfc->ctrl_write.bRequestType = 0x40; hfc->ctrl_write.bRequest = 0; hfc->ctrl_write.wLength = 0; @@ -1373,9 +1373,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) vend_idx = 0xffff; for (i = 0; hfcusb_idtab[i].idVendor; i++) { - if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor - && dev->descriptor.idProduct == - hfcusb_idtab[i].idProduct) { + if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor) + && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) { vend_idx = i; continue; } @@ -1516,8 +1515,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_INT; packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; case USB_ENDPOINT_XFER_BULK: if (ep_addr & 0x80) @@ -1545,8 +1543,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_BULK; packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; case USB_ENDPOINT_XFER_ISOC: if (ep_addr & 0x80) @@ -1574,8 +1571,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_ISOC; iso_packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; default: context-> @@ -1588,10 +1584,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) fifonum = cidx; context->fifos[cidx].hfc = context; - context->fifos[cidx]. - usb_packet_maxlen = - ep->desc. - wMaxPacketSize; + context->fifos[cidx].usb_packet_maxlen = + le16_to_cpu(ep->desc.wMaxPacketSize); context->fifos[cidx]. intervall = ep->desc.bInterval; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 393633681f49..aeaa1db74bd8 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1682,6 +1682,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); #endif + module_put(info->owner); return; } info->flags |= ISDN_ASYNC_CLOSING; diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 0842432e27ad..f10efb28cae4 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c @@ -143,3 +143,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) return st->target; } EXPORT_SYMBOL_GPL(wf_cpu_pid_run); + +MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); +MODULE_DESCRIPTION("PID algorithm for PowerMacs thermal control"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 227c39a7c1b4..8d84b045bc83 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -37,7 +37,7 @@ #include <linux/config.h> #include <linux/module.h> #include <linux/init.h> -#include <linux/device.h> +#include <linux/platform_device.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> @@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); - switch (mmc_rsp_type(cmd->flags)) { + switch (mmc_resp_type(cmd)) { case MMC_RSP_R1: mmccmd |= SD_CMD_RT_1; break; @@ -740,7 +740,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs) { struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; - u32 status; /* Avoid spurious interrupts */ @@ -887,7 +886,7 @@ struct mmc_host_ops au1xmmc_ops = { .set_ios = au1xmmc_set_ios, }; -static int au1xmmc_probe(struct device *dev) +static int __devinit au1xmmc_probe(struct platform_device *pdev) { int i, ret = 0; @@ -904,7 +903,7 @@ static int au1xmmc_probe(struct device *dev) disable_irq(AU1100_SD_IRQ); for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { - struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev); + struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); struct au1xmmc_host *host = 0; if (!mmc) { @@ -967,7 +966,7 @@ static int au1xmmc_probe(struct device *dev) return 0; } -static int au1xmmc_remove(struct device *dev) +static int __devexit au1xmmc_remove(struct platform_device *pdev) { int i; @@ -997,23 +996,24 @@ static int au1xmmc_remove(struct device *dev) return 0; } -static struct device_driver au1xmmc_driver = { - .name = DRIVER_NAME, - .bus = &platform_bus_type, +static struct platform_driver au1xmmc_driver = { .probe = au1xmmc_probe, .remove = au1xmmc_remove, .suspend = NULL, - .resume = NULL + .resume = NULL, + .driver = { + .name = DRIVER_NAME, + }, }; static int __init au1xmmc_init(void) { - return driver_register(&au1xmmc_driver); + return platform_driver_register(&au1xmmc_driver); } static void __exit au1xmmc_exit(void) { - driver_unregister(&au1xmmc_driver); + platform_driver_unregister(&au1xmmc_driver); } module_init(au1xmmc_init); diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index 230642571c92..e824acaf188a 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c @@ -296,9 +296,7 @@ void t1_espi_destroy(struct peespi *espi) struct peespi *t1_espi_create(adapter_t *adapter) { - struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL); - - memset(espi, 0, sizeof(*espi)); + struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL); if (espi) espi->adapter = adapter; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 49b597cbc19a..b7f00d6eb6a6 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -4092,6 +4092,7 @@ static void s2io_set_multicast(struct net_device *dev) i++, mclist = mclist->next) { memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr, ETH_ALEN); + mac_addr = 0; for (j = 0; j < ETH_ALEN; j++) { mac_addr |= mclist->dmi_addr[j]; mac_addr <<= 8; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e8e92c853e89..15545620ab0e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3532,9 +3532,23 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) (base + len + 8 < base)); } +/* Test for DMA addresses > 40-bit */ +static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, + int len) +{ +#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) + return (((u64) mapping + len) > DMA_40BIT_MASK); + return 0; +#else + return 0; +#endif +} + static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); -static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, +/* Workaround 4GB and 40-bit hardware DMA bugs. */ +static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, u32 last_plus_one, u32 *start, u32 base_flags, u32 mss) { @@ -3742,6 +3756,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if (tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; + if (tg3_40bit_overflow_test(tp, mapping, len)) + would_hit_hwbug = 1; + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tg3_set_txd(tp, entry, mapping, len, base_flags, (i == last)|(mss << 1)); @@ -3763,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* If the workaround fails due to memory/mapping * failure, silently drop this packet. */ - if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one, + if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one, &start, base_flags, mss)) goto out_unlock; @@ -10608,8 +10625,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, unsigned long tg3reg_base, tg3reg_len; struct net_device *dev; struct tg3 *tp; - int i, err, pci_using_dac, pm_cap; + int i, err, pm_cap; char str[40]; + u64 dma_mask, persist_dma_mask; if (tg3_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -10646,26 +10664,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_res; } - /* Configure DMA attributes. */ - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (!err) { - pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (err < 0) { - printk(KERN_ERR PFX "Unable to obtain 64 bit DMA " - "for consistent allocations\n"); - goto err_out_free_res; - } - } else { - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " - "aborting.\n"); - goto err_out_free_res; - } - pci_using_dac = 0; - } - tg3reg_base = pci_resource_start(pdev, 0); tg3reg_len = pci_resource_len(pdev, 0); @@ -10679,8 +10677,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - if (pci_using_dac) - dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_LLTX; #if TG3_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; @@ -10765,6 +10761,44 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_iounmap; } + /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit. + * On 64-bit systems with IOMMU, use 40-bit dma_mask. + * On 64-bit systems without IOMMU, use 64-bit dma_mask and + * do DMA address check in tg3_start_xmit(). + */ + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { + persist_dma_mask = dma_mask = DMA_40BIT_MASK; +#ifdef CONFIG_HIGHMEM + dma_mask = DMA_64BIT_MASK; +#endif + } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788) + persist_dma_mask = dma_mask = DMA_32BIT_MASK; + else + persist_dma_mask = dma_mask = DMA_64BIT_MASK; + + /* Configure DMA attributes. */ + if (dma_mask > DMA_32BIT_MASK) { + err = pci_set_dma_mask(pdev, dma_mask); + if (!err) { + dev->features |= NETIF_F_HIGHDMA; + err = pci_set_consistent_dma_mask(pdev, + persist_dma_mask); + if (err < 0) { + printk(KERN_ERR PFX "Unable to obtain 64 bit " + "DMA for consistent allocations\n"); + goto err_out_iounmap; + } + } + } + if (err || dma_mask == DMA_32BIT_MASK) { + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { + printk(KERN_ERR PFX "No usable DMA configuration, " + "aborting.\n"); + goto err_out_iounmap; + } + } + tg3_init_bufmgr_config(tp); #if TG3_TSO_SUPPORT != 0 @@ -10833,9 +10867,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; - if (tp->tg3_flags2 & TG3_FLG2_IS_5788) - dev->features &= ~NETIF_F_HIGHDMA; - /* flow control autonegotiation is default behavior */ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 166de3507780..10845253c9e0 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -312,8 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev, { struct parport_pc_pci *card; struct parport_serial_private *priv = pci_get_drvdata (dev); - int i = id->driver_data, n; - int success = 0; + int n, success = 0; priv->par = cards[id->driver_data]; card = &priv->par; @@ -344,10 +343,8 @@ static int __devinit parport_register (struct pci_dev *dev, "hi" as an offset (see SYBA def.) */ /* TODO: test if sharing interrupts works */ - printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, " - "I/O at %#lx(%#lx)\n", - parport_serial_pci_tbl[i].vendor, - parport_serial_pci_tbl[i].device, io_lo, io_hi); + dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " + "%#lx(%#lx)\n", io_lo, io_hi); port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, dev); if (port) { @@ -359,7 +356,7 @@ static int __devinit parport_register (struct pci_dev *dev, if (card->postinit_hook) card->postinit_hook (dev, card, !success); - return success ? 0 : 1; + return 0; } static int __devinit parport_serial_pci_probe (struct pci_dev *dev, diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index af1d5b404cee..33157c84d1d3 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -215,9 +215,10 @@ dasd_state_basic_to_known(struct dasd_device * device) * interrupt for this detection ccw uses the kernel event daemon to * trigger the call to dasd_change_state. All this is done in the * discipline code, see dasd_eckd.c. - * After the analysis ccw is done (do_analysis returned 0 or error) - * the block device is setup. Either a fake disk is added to allow - * formatting or a proper device request queue is created. + * After the analysis ccw is done (do_analysis returned 0) the block + * device is setup. + * In case the analysis returns an error, the device setup is stopped + * (a fake disk was already added to allow formatting). */ static inline int dasd_state_basic_to_ready(struct dasd_device * device) @@ -227,13 +228,19 @@ dasd_state_basic_to_ready(struct dasd_device * device) rc = 0; if (device->discipline->do_analysis != NULL) rc = device->discipline->do_analysis(device); - if (rc) + if (rc) { + if (rc != -EAGAIN) + device->state = DASD_STATE_UNFMT; return rc; + } + /* make disk known with correct capacity */ dasd_setup_queue(device); + set_capacity(device->gdp, device->blocks << device->s2b_shift); device->state = DASD_STATE_READY; - if (dasd_scan_partitions(device) != 0) + rc = dasd_scan_partitions(device); + if (rc) device->state = DASD_STATE_BASIC; - return 0; + return rc; } /* @@ -254,6 +261,15 @@ dasd_state_ready_to_basic(struct dasd_device * device) } /* + * Back to basic. + */ +static inline void +dasd_state_unfmt_to_basic(struct dasd_device * device) +{ + device->state = DASD_STATE_BASIC; +} + +/* * Make the device online and schedule the bottom half to start * the requeueing of requests from the linux request queue to the * ccw queue. @@ -319,8 +335,12 @@ dasd_decrease_state(struct dasd_device *device) if (device->state == DASD_STATE_READY && device->target <= DASD_STATE_BASIC) dasd_state_ready_to_basic(device); - - if (device->state == DASD_STATE_BASIC && + + if (device->state == DASD_STATE_UNFMT && + device->target <= DASD_STATE_BASIC) + dasd_state_unfmt_to_basic(device); + + if (device->state == DASD_STATE_BASIC && device->target <= DASD_STATE_KNOWN) dasd_state_basic_to_known(device); @@ -1722,7 +1742,7 @@ dasd_open(struct inode *inp, struct file *filp) goto out; } - if (device->state < DASD_STATE_BASIC) { + if (device->state <= DASD_STATE_BASIC) { DBF_DEV_EVENT(DBF_ERR, device, " %s", " Cannot open unrecognized device"); rc = -ENODEV; diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 65dc844b975c..fce2835e7d19 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -100,8 +100,6 @@ dasd_scan_partitions(struct dasd_device * device) { struct block_device *bdev; - /* Make the disk known. */ - set_capacity(device->gdp, device->blocks << device->s2b_shift); bdev = bdget_disk(device->gdp, 0); if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) return -ENODEV; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 0592354cc604..7cb0b9e78a6a 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -26,7 +26,7 @@ * new: the dasd_device structure is allocated. * known: the discipline for the device is identified. * basic: the device can do basic i/o. - * accept: the device is analysed (format is known). + * unfmt: the device could not be analyzed (format is unknown). * ready: partition detection is done and the device is can do block io. * online: the device accepts requests from the block device queue. * @@ -47,8 +47,9 @@ #define DASD_STATE_NEW 0 #define DASD_STATE_KNOWN 1 #define DASD_STATE_BASIC 2 -#define DASD_STATE_READY 3 -#define DASD_STATE_ONLINE 4 +#define DASD_STATE_UNFMT 3 +#define DASD_STATE_READY 4 +#define DASD_STATE_ONLINE 5 #include <linux/module.h> #include <linux/wait.h> diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 2d5da3c75ca7..4c1acc8daa82 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -93,6 +93,9 @@ dasd_devices_show(struct seq_file *m, void *v) case DASD_STATE_BASIC: seq_printf(m, "basic"); break; + case DASD_STATE_UNFMT: + seq_printf(m, "unnformatted"); + break; case DASD_STATE_READY: case DASD_STATE_ONLINE: seq_printf(m, "active "); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 8cf9905d484b..f4183d660258 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -1115,6 +1115,9 @@ chsc_enable_facility(int operation_code) goto out; } switch (sda_area->response.code) { + case 0x0001: /* everything ok */ + ret = 0; + break; case 0x0003: /* invalid request block */ case 0x0007: ret = -EINVAL; @@ -1123,6 +1126,8 @@ chsc_enable_facility(int operation_code) case 0x0101: /* facility not provided */ ret = -EOPNOTSUPP; break; + default: /* something went wrong */ + ret = -EIO; } out: free_page((unsigned long)sda_area); diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index d6469baa7e16..72118ee68954 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -168,7 +168,7 @@ smsg_init(void) driver_unregister(&smsg_driver); return -EIO; /* better errno ? */ } - rc = iucv_connect (&smsg_pathid, 1, 0, "*MSG ", 0, 0, 0, 0, + rc = iucv_connect (&smsg_pathid, 255, 0, "*MSG ", 0, 0, 0, 0, smsg_handle, 0); if (rc) { printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 5d02ff4db6cc..b65462f76484 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -192,7 +192,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) SDev = cd->device; if (!sense) { - sense = kmalloc(sizeof(*sense), GFP_KERNEL); + sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!sense) { err = -ENOMEM; goto out; diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 419dd3cd7862..193722d680cf 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -420,10 +420,8 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, if (up->port.info == NULL) goto ack_tx_int; xmit = &up->port.info->xmit; - if (uart_circ_empty(xmit)) { - uart_write_wakeup(&up->port); + if (uart_circ_empty(xmit)) goto ack_tx_int; - } if (uart_tx_stopped(&up->port)) goto ack_tx_int; diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 95fb4939c675..cc1faa31d124 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state); void uart_write_wakeup(struct uart_port *port) { struct uart_info *info = port->info; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + BUG_ON(!info); tasklet_schedule(&info->tlet); } @@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty) } static int -uart_write(struct tty_struct *tty, const unsigned char * buf, int count) +uart_write(struct tty_struct *tty, const unsigned char *buf, int count) { struct uart_state *state = tty->driver_data; - struct uart_port *port = state->port; - struct circ_buf *circ = &state->info->xmit; + struct uart_port *port; + struct circ_buf *circ; unsigned long flags; int c, ret = 0; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + if (!state || !state->info) { + WARN_ON(1); + return -EL3HLT; + } + + port = state->port; + circ = &state->info->xmit; + if (!circ->buf) return 0; @@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty) struct uart_port *port = state->port; unsigned long flags; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + if (!state || !state->info) { + WARN_ON(1); + return; + } + DPRINTK("uart_flush_buffer(%d) called\n", tty->index); spin_lock_irqsave(&port->lock, flags); diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 43e67d6c29d4..60ea4a3f0713 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c @@ -820,7 +820,7 @@ static int __init sn_sal_module_init(void) int retval; if (!ia64_platform_is("sn2")) - return -ENODEV; + return 0; printk(KERN_INFO "sn_console: Console driver init\n"); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4dd6865d32b0..b5c96e74a903 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -242,8 +242,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) down(&port->sem); - if (port->open_count == 0) - goto out; + if (port->open_count == 0) { + up(&port->sem); + return; + } --port->open_count; if (port->open_count == 0) { @@ -260,10 +262,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp) module_put(port->serial->type->driver.owner); } - kref_put(&port->serial->kref, destroy_serial); - -out: up(&port->sem); + kref_put(&port->serial->kref, destroy_serial); } static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) diff --git a/fs/9p/9p.c b/fs/9p/9p.c index 1a6d08761f39..f86a28d1d6a6 100644 --- a/fs/9p/9p.c +++ b/fs/9p/9p.c @@ -111,7 +111,6 @@ static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, if (!rc) return; - dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id); v9ses = a; if (rc->id == RCLUNK) v9fs_put_idpool(fid, &v9ses->fidpool); diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c index 1a28ef97a3d1..5b2ce21b10fa 100644 --- a/fs/9p/trans_fd.c +++ b/fs/9p/trans_fd.c @@ -80,6 +80,7 @@ static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len) if (!trans || trans->status != Connected || !ts) return -EIO; + oldfs = get_fs(); set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index dce729d42869..3ad8455f8577 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -265,8 +265,7 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, fid = v9fs_get_idpool(&v9ses->fidpool); if (fid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); - err = -ENOSPC; - goto error; + return -ENOSPC; } err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); @@ -313,8 +312,7 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) nfid = v9fs_get_idpool(&v9ses->fidpool); if (nfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); - err = -ENOSPC; - goto error; + return ERR_PTR(-ENOSPC); } err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, @@ -612,7 +610,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, int result = 0; dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", - dir, dentry->d_iname, dentry, nameidata); + dir, dentry->d_name.name, dentry, nameidata); sb = dir->i_sb; v9ses = v9fs_inode2v9ses(dir); diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index cdf787ee08de..d05318fa684e 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -156,7 +156,6 @@ static struct super_block *v9fs_get_sb(struct file_system_type stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); - kfree(fcall); v9fs_t_clunk(v9ses, newfid); } else { /* Setup the Root Inode */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 3c03aadaff0c..7b25463d3c14 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -52,7 +52,7 @@ extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, int * /* type of buf returned */ , const int long_op); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); -extern int is_valid_oplock_break(struct smb_hdr *smb); +extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); extern unsigned int smbCalcSize(struct smb_hdr *ptr); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ef5ae6f93c75..2a0c1f4ca0ae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -630,7 +630,7 @@ multi_t2_fnd: smallbuf = NULL; } wake_up_process(task_to_wake); - } else if ((is_valid_oplock_break(smb_buffer) == FALSE) + } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) && (isMultiRsp == FALSE)) { cERROR(1, ("No task to wake, unknown frame rcvd!")); cifs_dump_mem("Received Data is: ",(char *)smb_buffer, diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 812c6bb0fe38..432ba15e2c2d 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -475,7 +475,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) return 0; } int -is_valid_oplock_break(struct smb_hdr *buf) +is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) { struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; struct list_head *tmp; @@ -535,7 +535,7 @@ is_valid_oplock_break(struct smb_hdr *buf) read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if (tcon->tid == buf->Tid) { + if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { cifs_stats_inc(&tcon->num_oplock_brks); list_for_each(tmp1,&tcon->openFileList){ netfile = list_entry(tmp1,struct cifsFileInfo, diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 7fe85415ae7c..8ad52f5bf255 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -36,7 +36,7 @@ static DECLARE_MUTEX(read_mutex); /* These two macros may change in future, to provide better st_ino semantics. */ -#define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) +#define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1) #define OFFSET(x) ((x)->i_ino) @@ -66,8 +66,36 @@ static int cramfs_iget5_test(struct inode *inode, void *opaque) static int cramfs_iget5_set(struct inode *inode, void *opaque) { + static struct timespec zerotime; struct cramfs_inode *cramfs_inode = opaque; + inode->i_mode = cramfs_inode->mode; + inode->i_uid = cramfs_inode->uid; + inode->i_size = cramfs_inode->size; + inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; + inode->i_blksize = PAGE_CACHE_SIZE; + inode->i_gid = cramfs_inode->gid; + /* Struct copy intentional */ + inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; inode->i_ino = CRAMINO(cramfs_inode); + /* inode->i_nlink is left 1 - arguably wrong for directories, + but it's the best we can do without reading the directory + contents. 1 yields the right result in GNU find, even + without -noleaf option. */ + if (S_ISREG(inode->i_mode)) { + inode->i_fop = &generic_ro_fops; + inode->i_data.a_ops = &cramfs_aops; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &cramfs_dir_inode_operations; + inode->i_fop = &cramfs_directory_operations; + } else if (S_ISLNK(inode->i_mode)) { + inode->i_op = &page_symlink_inode_operations; + inode->i_data.a_ops = &cramfs_aops; + } else { + inode->i_size = 0; + inode->i_blocks = 0; + init_special_inode(inode, inode->i_mode, + old_decode_dev(cramfs_inode->size)); + } return 0; } @@ -77,37 +105,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), cramfs_iget5_test, cramfs_iget5_set, cramfs_inode); - static struct timespec zerotime; - if (inode && (inode->i_state & I_NEW)) { - inode->i_mode = cramfs_inode->mode; - inode->i_uid = cramfs_inode->uid; - inode->i_size = cramfs_inode->size; - inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; - inode->i_blksize = PAGE_CACHE_SIZE; - inode->i_gid = cramfs_inode->gid; - /* Struct copy intentional */ - inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; - inode->i_ino = CRAMINO(cramfs_inode); - /* inode->i_nlink is left 1 - arguably wrong for directories, - but it's the best we can do without reading the directory - contents. 1 yields the right result in GNU find, even - without -noleaf option. */ - if (S_ISREG(inode->i_mode)) { - inode->i_fop = &generic_ro_fops; - inode->i_data.a_ops = &cramfs_aops; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &cramfs_dir_inode_operations; - inode->i_fop = &cramfs_directory_operations; - } else if (S_ISLNK(inode->i_mode)) { - inode->i_op = &page_symlink_inode_operations; - inode->i_data.a_ops = &cramfs_aops; - } else { - inode->i_size = 0; - inode->i_blocks = 0; - init_special_inode(inode, inode->i_mode, - old_decode_dev(cramfs_inode->size)); - } unlock_new_inode(inode); } return inode; diff --git a/fs/dcache.c b/fs/dcache.c index a173bba32666..11dc83092d4a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1736,7 +1736,7 @@ void __init vfs_caches_init(unsigned long mempages) SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, filp_ctor, filp_dtor); + SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); dcache_init(mempages); inode_init(mempages); diff --git a/fs/fifo.c b/fs/fifo.c index 923371b753ab..d13fcd3ec803 100644 --- a/fs/fifo.c +++ b/fs/fifo.c @@ -34,10 +34,7 @@ static int fifo_open(struct inode *inode, struct file *filp) { int ret; - ret = -ERESTARTSYS; - if (mutex_lock_interruptible(PIPE_MUTEX(*inode))) - goto err_nolock_nocleanup; - + mutex_lock(PIPE_MUTEX(*inode)); if (!inode->i_pipe) { ret = -ENOMEM; if(!pipe_new(inode)) @@ -140,8 +137,6 @@ err: err_nocleanup: mutex_unlock(PIPE_MUTEX(*inode)); - -err_nolock_nocleanup: return ret; } diff --git a/fs/file_table.c b/fs/file_table.c index 768b58167543..44fabeaa9415 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -5,6 +5,7 @@ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ +#include <linux/config.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/file.h> @@ -19,52 +20,67 @@ #include <linux/capability.h> #include <linux/cdev.h> #include <linux/fsnotify.h> +#include <linux/sysctl.h> +#include <linux/percpu_counter.h> + +#include <asm/atomic.h> /* sysctl tunables... */ struct files_stat_struct files_stat = { .max_files = NR_FILE }; -EXPORT_SYMBOL(files_stat); /* Needed by unix.o */ - /* public. Not pretty! */ - __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); +__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); -static DEFINE_SPINLOCK(filp_count_lock); +static struct percpu_counter nr_files __cacheline_aligned_in_smp; -/* slab constructors and destructors are called from arbitrary - * context and must be fully threaded - use a local spinlock - * to protect files_stat.nr_files - */ -void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags) +static inline void file_free_rcu(struct rcu_head *head) { - if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { - unsigned long flags; - spin_lock_irqsave(&filp_count_lock, flags); - files_stat.nr_files++; - spin_unlock_irqrestore(&filp_count_lock, flags); - } + struct file *f = container_of(head, struct file, f_u.fu_rcuhead); + kmem_cache_free(filp_cachep, f); } -void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags) +static inline void file_free(struct file *f) { - unsigned long flags; - spin_lock_irqsave(&filp_count_lock, flags); - files_stat.nr_files--; - spin_unlock_irqrestore(&filp_count_lock, flags); + percpu_counter_dec(&nr_files); + call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); } -static inline void file_free_rcu(struct rcu_head *head) +/* + * Return the total number of open files in the system + */ +static int get_nr_files(void) { - struct file *f = container_of(head, struct file, f_u.fu_rcuhead); - kmem_cache_free(filp_cachep, f); + return percpu_counter_read_positive(&nr_files); } -static inline void file_free(struct file *f) +/* + * Return the maximum number of open files in the system + */ +int get_max_files(void) { - call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); + return files_stat.max_files; } +EXPORT_SYMBOL_GPL(get_max_files); + +/* + * Handle nr_files sysctl + */ +#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) +int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + files_stat.nr_files = get_nr_files(); + return proc_dointvec(table, write, filp, buffer, lenp, ppos); +} +#else +int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return -ENOSYS; +} +#endif /* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or @@ -78,14 +94,20 @@ struct file *get_empty_filp(void) /* * Privileged users can go above max_files */ - if (files_stat.nr_files >= files_stat.max_files && - !capable(CAP_SYS_ADMIN)) - goto over; + if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { + /* + * percpu_counters are inaccurate. Do an expensive check before + * we go and fail. + */ + if (percpu_counter_sum(&nr_files) >= files_stat.max_files) + goto over; + } f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; + percpu_counter_inc(&nr_files); memset(f, 0, sizeof(*f)); if (security_file_alloc(f)) goto fail_sec; @@ -101,10 +123,10 @@ struct file *get_empty_filp(void) over: /* Ran out of filps - report that */ - if (files_stat.nr_files > old_max) { + if (get_nr_files() > old_max) { printk(KERN_INFO "VFS: file-max limit %d reached\n", - files_stat.max_files); - old_max = files_stat.nr_files; + get_max_files()); + old_max = get_nr_files(); } goto fail; @@ -276,4 +298,5 @@ void __init files_init(unsigned long mempages) if (files_stat.max_files < NR_FILE) files_stat.max_files = NR_FILE; files_defer_init(); + percpu_counter_init(&nr_files); } diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 3e51dd1da8aa..cf55b221fc2b 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -233,7 +233,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) c->nextblock->dirty_size = 0; } #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { + if (!jffs2_can_mark_obsolete(c) && c->wbuf_pagesize && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { /* If we're going to start writing into a block which already contains data, and the end of the data isn't page-aligned, skip a little and align it. */ diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 78010ad60e47..1e4a93835fed 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c @@ -52,6 +52,7 @@ int ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { int blocksize, offset, size; + loff_t i_size; dasd_information_t *info; struct hd_geometry *geo; char type[5] = {0,}; @@ -63,6 +64,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) unsigned char *data; Sector sect; + blocksize = bdev_hardsect_size(bdev); + if (blocksize <= 0) + return 0; + i_size = i_size_read(bdev->bd_inode); + if (i_size == 0) + return 0; + if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) goto out_noinfo; if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) @@ -73,9 +81,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) goto out_noioctl; - - if ((blocksize = bdev_hardsect_size(bdev)) <= 0) - goto out_badsect; /* * Get volume label, extract name and type. @@ -111,7 +116,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) } else { printk("CMS1/%8s:", name); offset = (info->label_block + 1); - size = bdev->bd_inode->i_size >> 9; + size = i_size >> 9; } put_partition(state, 1, offset*(blocksize >> 9), size-offset*(blocksize >> 9)); @@ -168,7 +173,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) else printk("(nonl)/%8s:", name); offset = (info->label_block + 1); - size = (bdev->bd_inode->i_size >> 9); + size = i_size >> 9; put_partition(state, 1, offset*(blocksize >> 9), size-offset*(blocksize >> 9)); } @@ -180,7 +185,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) return 1; out_readerr: -out_badsect: out_noioctl: kfree(label); out_nolab: diff --git a/fs/pipe.c b/fs/pipe.c index d722579df79a..8aada8e426f4 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -605,7 +605,7 @@ struct file_operations rdwr_fifo_fops = { .fasync = pipe_rdwr_fasync, }; -struct file_operations read_pipe_fops = { +static struct file_operations read_pipe_fops = { .llseek = no_llseek, .read = pipe_read, .readv = pipe_readv, @@ -617,7 +617,7 @@ struct file_operations read_pipe_fops = { .fasync = pipe_read_fasync, }; -struct file_operations write_pipe_fops = { +static struct file_operations write_pipe_fops = { .llseek = no_llseek, .read = bad_pipe_r, .write = pipe_write, @@ -629,7 +629,7 @@ struct file_operations write_pipe_fops = { .fasync = pipe_write_fasync, }; -struct file_operations rdwr_pipe_fops = { +static struct file_operations rdwr_pipe_fops = { .llseek = no_llseek, .read = pipe_read, .readv = pipe_readv, diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 0eaad41f4658..91b7c15ab373 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -204,7 +204,6 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, { pte_t *pte, ptent; spinlock_t *ptl; - unsigned long pfn; struct page *page; pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); @@ -214,12 +213,12 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, continue; mss->resident += PAGE_SIZE; - pfn = pte_pfn(ptent); - if (!pfn_valid(pfn)) + + page = vm_normal_page(vma, addr, ptent); + if (!page) continue; - page = pfn_to_page(pfn); - if (page_count(page) >= 2) { + if (page_mapcount(page) >= 2) { if (pte_dirty(ptent)) mss->shared_dirty += PAGE_SIZE; else @@ -289,7 +288,7 @@ static int show_smap(struct seq_file *m, void *v) struct mem_size_stats mss; memset(&mss, 0, sizeof mss); - if (vma->vm_mm) + if (vma->vm_mm && !is_vm_hugetlb_page(vma)) smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); return show_map_internal(m, v, &mss); } diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index cde5d48994ae..14bd2246fb6d 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -137,6 +137,7 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * inode->i_gid = dir->i_gid; d_instantiate(dentry, inode); dget(dentry); + dir->i_mtime = dir->i_ctime = CURRENT_TIME; } else iput(inode); } diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c8123308e060..284f7852de8b 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -247,7 +247,7 @@ static int linear_search_in_dir_item(struct cpu_key *key, /* mark, that this generation number is used */ if (de->de_gen_number_bit_string) set_bit(GET_GENERATION_NUMBER(deh_offset(deh)), - (unsigned long *)de->de_gen_number_bit_string); + de->de_gen_number_bit_string); // calculate pointer to name and namelen de->de_entry_num = i; @@ -431,7 +431,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, struct reiserfs_de_head *deh; INITIALIZE_PATH(path); struct reiserfs_dir_entry de; - int bit_string[MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1]; + DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1); int gen_number; char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc if we create file with short name */ @@ -486,7 +486,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, /* find the proper place for the new entry */ memset(bit_string, 0, sizeof(bit_string)); - de.de_gen_number_bit_string = (char *)bit_string; + de.de_gen_number_bit_string = bit_string; retval = reiserfs_find_entry(dir, name, namelen, &path, &de); if (retval != NAME_NOT_FOUND) { if (buffer != small_buf) @@ -508,7 +508,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, } gen_number = - find_first_zero_bit((unsigned long *)bit_string, + find_first_zero_bit(bit_string, MAX_GENERATION_NUMBER + 1); if (gen_number > MAX_GENERATION_NUMBER) { /* there is no free generation number */ diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 395e582ee542..d04cff2273b6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1045,10 +1045,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) } inode->i_uid = le32_to_cpu(fe->uid); - if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; + if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_UID_IGNORE)) + inode->i_uid = UDF_SB(inode->i_sb)->s_uid; inode->i_gid = le32_to_cpu(fe->gid); - if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; + if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_GID_IGNORE)) + inode->i_gid = UDF_SB(inode->i_sb)->s_gid; inode->i_nlink = le16_to_cpu(fe->fileLinkCount); if (!inode->i_nlink) @@ -1335,10 +1339,14 @@ udf_update_inode(struct inode *inode, int do_sync) return err; } - if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) + fe->uid = cpu_to_le32(-1); + else if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) fe->uid = cpu_to_le32(inode->i_uid); - if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) + fe->gid = cpu_to_le32(-1); + else if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) fe->gid = cpu_to_le32(inode->i_gid); udfperms = ((inode->i_mode & S_IRWXO) ) | diff --git a/fs/udf/super.c b/fs/udf/super.c index 4a6f49adc609..368d8f81fe54 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -269,7 +269,7 @@ enum { Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, Opt_rootdir, Opt_utf8, Opt_iocharset, - Opt_err + Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore }; static match_table_t tokens = { @@ -282,6 +282,10 @@ static match_table_t tokens = { {Opt_adinicb, "adinicb"}, {Opt_shortad, "shortad"}, {Opt_longad, "longad"}, + {Opt_uforget, "uid=forget"}, + {Opt_uignore, "uid=ignore"}, + {Opt_gforget, "gid=forget"}, + {Opt_gignore, "gid=ignore"}, {Opt_gid, "gid=%u"}, {Opt_uid, "uid=%u"}, {Opt_umask, "umask=%o"}, @@ -414,6 +418,18 @@ udf_parse_options(char *options, struct udf_options *uopt) uopt->flags |= (1 << UDF_FLAG_NLS_MAP); break; #endif + case Opt_uignore: + uopt->flags |= (1 << UDF_FLAG_UID_IGNORE); + break; + case Opt_uforget: + uopt->flags |= (1 << UDF_FLAG_UID_FORGET); + break; + case Opt_gignore: + uopt->flags |= (1 << UDF_FLAG_GID_IGNORE); + break; + case Opt_gforget: + uopt->flags |= (1 << UDF_FLAG_GID_FORGET); + break; default: printk(KERN_ERR "udf: bad mount option \"%s\" " "or missing value\n", p); diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 663669810be6..110f8d62616f 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -20,6 +20,10 @@ #define UDF_FLAG_VARCONV 8 #define UDF_FLAG_NLS_MAP 9 #define UDF_FLAG_UTF8 10 +#define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ +#define UDF_FLAG_UID_IGNORE 12 /* use sb uid instead of on disk uid */ +#define UDF_FLAG_GID_FORGET 13 +#define UDF_FLAG_GID_IGNORE 14 #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index 9387a5e1ffe0..0c2acc944a0a 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -340,6 +340,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); + + /* The ARM ARM states that the completion of a TLB maintenance + * operation is only guaranteed by a DSB instruction + */ + if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); } /* diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h index 4dc8ddb401c1..09ec447fe2af 100644 --- a/include/asm-generic/unaligned.h +++ b/include/asm-generic/unaligned.h @@ -78,7 +78,7 @@ static inline void __ustw(__u16 val, __u16 *addr) #define __get_unaligned(ptr, size) ({ \ const void *__gu_p = ptr; \ - __typeof__(*(ptr)) val; \ + __u64 val; \ switch (size) { \ case 1: \ val = *(const __u8 *)__gu_p; \ @@ -95,7 +95,7 @@ static inline void __ustw(__u16 val, __u16 *addr) default: \ bad_unaligned_access_length(); \ }; \ - val; \ + (__typeof__(*(ptr)))val; \ }) #define __put_unaligned(val, ptr, size) \ diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h index eb392032e19b..5207758a6dd9 100644 --- a/include/asm-powerpc/eeh.h +++ b/include/asm-powerpc/eeh.h @@ -118,6 +118,8 @@ static inline void pci_addr_cache_build(void) { } static inline void eeh_add_device_early(struct device_node *dn) { } +static inline void eeh_add_device_late(struct pci_dev *dev) { } + static inline void eeh_remove_device(struct pci_dev *dev) { } static inline void eeh_add_device_tree_early(struct device_node *dn) { } diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index bda2f217e6fe..6a2af2f6853b 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h @@ -93,7 +93,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs, "mfxer %0\n" "std %0, 296(%2)\n" : "=&r" (tmp1), "=&r" (tmp2) - : "b" (newregs)); + : "b" (newregs) + : "memory"); } } #else diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index b2e65e8bf812..6a89dbb03c1e 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -118,6 +118,8 @@ static inline void sched_cacheflush(void) extern void account_vtime(struct task_struct *); extern void account_tick_vtime(struct task_struct *); extern void account_system_vtime(struct task_struct *); +#else +#define account_vtime(x) do { /* empty */ } while (0) #endif #define finish_arch_switch(prev) do { \ diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h index 0caf60147e97..34c4b43d3f98 100644 --- a/include/asm-sparc64/futex.h +++ b/include/asm-sparc64/futex.h @@ -20,7 +20,7 @@ "4: ba 3b\n" \ " mov %5, %0\n" \ " .previous\n" \ - " .section __ex_table,#alloc\n" \ + " .section __ex_table,\"a\"\n" \ " .align 4\n" \ " .word 1b, 4b\n" \ " .word 2b, 4b\n" \ diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index 203e8eee6351..c91d1e38eac6 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -136,7 +136,7 @@ __asm__ __volatile__( \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\t" \ ".previous\n\n\t" \ @@ -148,7 +148,7 @@ if (__builtin_constant_p(ret) && ret == -EFAULT) \ __asm__ __volatile__( \ "/* Put user asm ret, inline. */\n" \ "1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, __ret_efault\n\n\t" \ ".previous\n\n\t" \ @@ -163,7 +163,7 @@ __asm__ __volatile__( \ "ret\n\t" \ " restore %%g0, %3, %%o0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\n\t" \ @@ -206,7 +206,7 @@ __asm__ __volatile__( \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\t" \ @@ -218,7 +218,7 @@ if (__builtin_constant_p(retval) && retval == -EFAULT) \ __asm__ __volatile__( \ "/* Get user asm ret, inline. */\n" \ "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b,__ret_efault\n\n\t" \ ".previous\n\t" \ @@ -233,7 +233,7 @@ __asm__ __volatile__( \ "ret\n\t" \ " restore %%g0, %2, %%o0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\t" \ diff --git a/include/linux/file.h b/include/linux/file.h index 418b6101b59a..9901b850f2e4 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -60,8 +60,6 @@ extern void put_filp(struct file *); extern int get_unused_fd(void); extern void FASTCALL(put_unused_fd(unsigned int fd)); struct kmem_cache; -extern void filp_ctor(void * objp, struct kmem_cache *cachep, unsigned long cflags); -extern void filp_dtor(void * objp, struct kmem_cache *cachep, unsigned long dflags); extern struct file ** alloc_fd_array(int); extern void free_fd_array(struct file **, int); diff --git a/include/linux/fs.h b/include/linux/fs.h index e059da947007..51c0c93bdf93 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -35,6 +35,7 @@ struct files_stat_struct { int max_files; /* tunable */ }; extern struct files_stat_struct files_stat; +extern int get_max_files(void); struct inodes_stat_t { int nr_inodes; @@ -1418,9 +1419,6 @@ extern int is_bad_inode(struct inode *); extern struct file_operations read_fifo_fops; extern struct file_operations write_fifo_fops; extern struct file_operations rdwr_fifo_fops; -extern struct file_operations read_pipe_fops; -extern struct file_operations write_pipe_fops; -extern struct file_operations rdwr_pipe_fops; extern int fs_may_remount_ro(struct super_block *); diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6361544bb6ae..6401c31d6add 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -116,6 +116,10 @@ extern int hrtimer_try_to_cancel(struct hrtimer *timer); extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); +#ifdef CONFIG_NO_IDLE_HZ +extern ktime_t hrtimer_get_next_event(void); +#endif + static inline int hrtimer_active(const struct hrtimer *timer) { return timer->state == HRTIMER_PENDING; diff --git a/include/linux/kmalloc_sizes.h b/include/linux/kmalloc_sizes.h index d82d4c05c12d..bda23e00ed71 100644 --- a/include/linux/kmalloc_sizes.h +++ b/include/linux/kmalloc_sizes.h @@ -19,8 +19,10 @@ CACHE(32768) CACHE(65536) CACHE(131072) -#ifndef CONFIG_MMU +#if (NR_CPUS > 512) || (MAX_NUMNODES > 256) || !defined(CONFIG_MMU) CACHE(262144) +#endif +#ifndef CONFIG_MMU CACHE(524288) CACHE(1048576) #ifdef CONFIG_LARGE_ALLOCS diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 01f03bc06eff..968b1aa3732c 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -6,6 +6,10 @@ #include <linux/mmzone.h> #include <linux/notifier.h> +struct page; +struct zone; +struct pglist_data; + #ifdef CONFIG_MEMORY_HOTPLUG /* * pgdat resizing functions diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 82b83da25d77..1709b5009d2e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1752,6 +1752,8 @@ #define PCI_DEVICE_ID_CCD_B00B 0xb00b #define PCI_DEVICE_ID_CCD_B00C 0xb00c #define PCI_DEVICE_ID_CCD_B100 0xb100 +#define PCI_DEVICE_ID_CCD_B700 0xb700 +#define PCI_DEVICE_ID_CCD_B701 0xb701 #define PCI_VENDOR_ID_EXAR 0x13a8 #define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index bd6708e2c027..682525511c9e 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -39,6 +39,7 @@ static inline void percpu_counter_destroy(struct percpu_counter *fbc) } void percpu_counter_mod(struct percpu_counter *fbc, long amount); +long percpu_counter_sum(struct percpu_counter *fbc); static inline long percpu_counter_read(struct percpu_counter *fbc) { @@ -92,6 +93,11 @@ static inline long percpu_counter_read_positive(struct percpu_counter *fbc) return fbc->count; } +static inline long percpu_counter_sum(struct percpu_counter *fbc) +{ + return percpu_counter_read_positive(fbc); +} + #endif /* CONFIG_SMP */ static inline void percpu_counter_inc(struct percpu_counter *fbc) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index b87aefa082e2..c2ec6c77874e 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -98,13 +98,17 @@ struct rcu_data { long batch; /* Batch # for current RCU batch */ struct rcu_head *nxtlist; struct rcu_head **nxttail; - long count; /* # of queued items */ + long qlen; /* # of queued callbacks */ struct rcu_head *curlist; struct rcu_head **curtail; struct rcu_head *donelist; struct rcu_head **donetail; + long blimit; /* Upper limit on a processed batch */ int cpu; struct rcu_head barrier; +#ifdef CONFIG_SMP + long last_rs_qlen; /* qlen during the last resched */ +#endif }; DECLARE_PER_CPU(struct rcu_data, rcu_data); diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 7d51149bd793..dad78cecfd20 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1052,7 +1052,7 @@ struct reiserfs_dir_entry { int de_entrylen; int de_namelen; char *de_name; - char *de_gen_number_bit_string; + unsigned long *de_gen_number_bit_string; __u32 de_dir_id; __u32 de_objectid; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 5ae51f1bc7c8..14bc9cfa6399 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -505,6 +505,41 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) return rem; } +#ifdef CONFIG_NO_IDLE_HZ +/** + * hrtimer_get_next_event - get the time until next expiry event + * + * Returns the delta to the next expiry event or KTIME_MAX if no timer + * is pending. + */ +ktime_t hrtimer_get_next_event(void) +{ + struct hrtimer_base *base = __get_cpu_var(hrtimer_bases); + ktime_t delta, mindelta = { .tv64 = KTIME_MAX }; + unsigned long flags; + int i; + + for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) { + struct hrtimer *timer; + + spin_lock_irqsave(&base->lock, flags); + if (!base->first) { + spin_unlock_irqrestore(&base->lock, flags); + continue; + } + timer = rb_entry(base->first, struct hrtimer, node); + delta.tv64 = timer->expires.tv64; + spin_unlock_irqrestore(&base->lock, flags); + delta = ktime_sub(delta, base->get_time()); + if (delta.tv64 < mindelta.tv64) + mindelta.tv64 = delta.tv64; + } + if (mindelta.tv64 < 0) + mindelta.tv64 = 0; + return mindelta; +} +#endif + /** * hrtimer_init - initialize a timer to the given clock * diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 0cf8146bd585..8cf15a569fcd 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -67,7 +67,43 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; /* Fake initialization required by compiler */ static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; -static int maxbatch = 10000; +static int blimit = 10; +static int qhimark = 10000; +static int qlowmark = 100; +#ifdef CONFIG_SMP +static int rsinterval = 1000; +#endif + +static atomic_t rcu_barrier_cpu_count; +static struct semaphore rcu_barrier_sema; +static struct completion rcu_barrier_completion; + +#ifdef CONFIG_SMP +static void force_quiescent_state(struct rcu_data *rdp, + struct rcu_ctrlblk *rcp) +{ + int cpu; + cpumask_t cpumask; + set_need_resched(); + if (unlikely(rdp->qlen - rdp->last_rs_qlen > rsinterval)) { + rdp->last_rs_qlen = rdp->qlen; + /* + * Don't send IPI to itself. With irqs disabled, + * rdp->cpu is the current cpu. + */ + cpumask = rcp->cpumask; + cpu_clear(rdp->cpu, cpumask); + for_each_cpu_mask(cpu, cpumask) + smp_send_reschedule(cpu); + } +} +#else +static inline void force_quiescent_state(struct rcu_data *rdp, + struct rcu_ctrlblk *rcp) +{ + set_need_resched(); +} +#endif /** * call_rcu - Queue an RCU callback for invocation after a grace period. @@ -92,17 +128,13 @@ void fastcall call_rcu(struct rcu_head *head, rdp = &__get_cpu_var(rcu_data); *rdp->nxttail = head; rdp->nxttail = &head->next; - - if (unlikely(++rdp->count > 10000)) - set_need_resched(); - + if (unlikely(++rdp->qlen > qhimark)) { + rdp->blimit = INT_MAX; + force_quiescent_state(rdp, &rcu_ctrlblk); + } local_irq_restore(flags); } -static atomic_t rcu_barrier_cpu_count; -static struct semaphore rcu_barrier_sema; -static struct completion rcu_barrier_completion; - /** * call_rcu_bh - Queue an RCU for invocation after a quicker grace period. * @head: structure to be used for queueing the RCU updates. @@ -131,12 +163,12 @@ void fastcall call_rcu_bh(struct rcu_head *head, rdp = &__get_cpu_var(rcu_bh_data); *rdp->nxttail = head; rdp->nxttail = &head->next; - rdp->count++; -/* - * Should we directly call rcu_do_batch() here ? - * if (unlikely(rdp->count > 10000)) - * rcu_do_batch(rdp); - */ + + if (unlikely(++rdp->qlen > qhimark)) { + rdp->blimit = INT_MAX; + force_quiescent_state(rdp, &rcu_bh_ctrlblk); + } + local_irq_restore(flags); } @@ -199,10 +231,12 @@ static void rcu_do_batch(struct rcu_data *rdp) next = rdp->donelist = list->next; list->func(list); list = next; - rdp->count--; - if (++count >= maxbatch) + rdp->qlen--; + if (++count >= rdp->blimit) break; } + if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark) + rdp->blimit = blimit; if (!rdp->donelist) rdp->donetail = &rdp->donelist; else @@ -473,6 +507,7 @@ static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, rdp->quiescbatch = rcp->completed; rdp->qs_pending = 0; rdp->cpu = cpu; + rdp->blimit = blimit; } static void __devinit rcu_online_cpu(int cpu) @@ -567,7 +602,12 @@ void synchronize_kernel(void) synchronize_rcu(); } -module_param(maxbatch, int, 0); +module_param(blimit, int, 0); +module_param(qhimark, int, 0); +module_param(qlowmark, int, 0); +#ifdef CONFIG_SMP +module_param(rsinterval, int, 0); +#endif EXPORT_SYMBOL_GPL(rcu_batches_completed); EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ diff --git a/kernel/sched.c b/kernel/sched.c index 12d291bf3379..e82c99f1db64 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4028,6 +4028,8 @@ static inline void __cond_resched(void) */ if (unlikely(preempt_count())) return; + if (unlikely(system_state != SYSTEM_RUNNING)) + return; do { add_preempt_count(PREEMPT_ACTIVE); schedule(); @@ -4333,6 +4335,7 @@ void __devinit init_idle(task_t *idle, int cpu) runqueue_t *rq = cpu_rq(cpu); unsigned long flags; + idle->timestamp = sched_clock(); idle->sleep_avg = 0; idle->array = NULL; idle->prio = MAX_PRIO; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index de2d9109194e..32b48e8ee36e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -50,6 +50,9 @@ #include <asm/uaccess.h> #include <asm/processor.h> +extern int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos); + #if defined(CONFIG_SYSCTL) /* External variables not in a header file. */ @@ -943,7 +946,7 @@ static ctl_table fs_table[] = { .data = &files_stat, .maxlen = 3*sizeof(int), .mode = 0444, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_nr_files, }, { .ctl_name = FS_MAXFILE, diff --git a/kernel/timer.c b/kernel/timer.c index fc6646fd5aab..bf7c4193b936 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -489,9 +489,21 @@ unsigned long next_timer_interrupt(void) struct list_head *list; struct timer_list *nte; unsigned long expires; + unsigned long hr_expires = MAX_JIFFY_OFFSET; + ktime_t hr_delta; tvec_t *varray[4]; int i, j; + hr_delta = hrtimer_get_next_event(); + if (hr_delta.tv64 != KTIME_MAX) { + struct timespec tsdelta; + tsdelta = ktime_to_timespec(hr_delta); + hr_expires = timespec_to_jiffies(&tsdelta); + if (hr_expires < 3) + return hr_expires + jiffies; + } + hr_expires += jiffies; + base = &__get_cpu_var(tvec_bases); spin_lock(&base->t_base.lock); expires = base->timer_jiffies + (LONG_MAX >> 1); @@ -542,6 +554,10 @@ found: } } spin_unlock(&base->t_base.lock); + + if (time_before(hr_expires, expires)) + return hr_expires; + return expires; } #endif @@ -925,6 +941,8 @@ static inline void update_times(void) void do_timer(struct pt_regs *regs) { jiffies_64++; + /* prevent loading jiffies before storing new jiffies_64 value. */ + barrier(); update_times(); softlockup_tick(regs); } diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 1a210088ad80..954981b14303 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -197,7 +197,7 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes) return policy; } -static void gather_stats(struct page *, void *); +static void gather_stats(struct page *, void *, int pte_dirty); static void migrate_page_add(struct page *page, struct list_head *pagelist, unsigned long flags); @@ -239,7 +239,7 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, continue; if (flags & MPOL_MF_STATS) - gather_stats(page, private); + gather_stats(page, private, pte_dirty(*pte)); else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) migrate_page_add(page, private, flags); else @@ -1753,67 +1753,145 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) struct numa_maps { unsigned long pages; unsigned long anon; - unsigned long mapped; + unsigned long active; + unsigned long writeback; unsigned long mapcount_max; + unsigned long dirty; + unsigned long swapcache; unsigned long node[MAX_NUMNODES]; }; -static void gather_stats(struct page *page, void *private) +static void gather_stats(struct page *page, void *private, int pte_dirty) { struct numa_maps *md = private; int count = page_mapcount(page); - if (count) - md->mapped++; + md->pages++; + if (pte_dirty || PageDirty(page)) + md->dirty++; - if (count > md->mapcount_max) - md->mapcount_max = count; + if (PageSwapCache(page)) + md->swapcache++; - md->pages++; + if (PageActive(page)) + md->active++; + + if (PageWriteback(page)) + md->writeback++; if (PageAnon(page)) md->anon++; + if (count > md->mapcount_max) + md->mapcount_max = count; + md->node[page_to_nid(page)]++; cond_resched(); } +#ifdef CONFIG_HUGETLB_PAGE +static void check_huge_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + struct numa_maps *md) +{ + unsigned long addr; + struct page *page; + + for (addr = start; addr < end; addr += HPAGE_SIZE) { + pte_t *ptep = huge_pte_offset(vma->vm_mm, addr & HPAGE_MASK); + pte_t pte; + + if (!ptep) + continue; + + pte = *ptep; + if (pte_none(pte)) + continue; + + page = pte_page(pte); + if (!page) + continue; + + gather_stats(page, md, pte_dirty(*ptep)); + } +} +#else +static inline void check_huge_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + struct numa_maps *md) +{ +} +#endif + int show_numa_map(struct seq_file *m, void *v) { struct task_struct *task = m->private; struct vm_area_struct *vma = v; struct numa_maps *md; + struct file *file = vma->vm_file; + struct mm_struct *mm = vma->vm_mm; int n; char buffer[50]; - if (!vma->vm_mm) + if (!mm) return 0; md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL); if (!md) return 0; - if (!is_vm_hugetlb_page(vma)) + mpol_to_str(buffer, sizeof(buffer), + get_vma_policy(task, vma, vma->vm_start)); + + seq_printf(m, "%08lx %s", vma->vm_start, buffer); + + if (file) { + seq_printf(m, " file="); + seq_path(m, file->f_vfsmnt, file->f_dentry, "\n\t= "); + } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { + seq_printf(m, " heap"); + } else if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) { + seq_printf(m, " stack"); + } + + if (is_vm_hugetlb_page(vma)) { + check_huge_range(vma, vma->vm_start, vma->vm_end, md); + seq_printf(m, " huge"); + } else { check_pgd_range(vma, vma->vm_start, vma->vm_end, - &node_online_map, MPOL_MF_STATS, md); + &node_online_map, MPOL_MF_STATS, md); + } - if (md->pages) { - mpol_to_str(buffer, sizeof(buffer), - get_vma_policy(task, vma, vma->vm_start)); + if (!md->pages) + goto out; - seq_printf(m, "%08lx %s pages=%lu mapped=%lu maxref=%lu", - vma->vm_start, buffer, md->pages, - md->mapped, md->mapcount_max); + if (md->anon) + seq_printf(m," anon=%lu",md->anon); - if (md->anon) - seq_printf(m," anon=%lu",md->anon); + if (md->dirty) + seq_printf(m," dirty=%lu",md->dirty); - for_each_online_node(n) - if (md->node[n]) - seq_printf(m, " N%d=%lu", n, md->node[n]); + if (md->pages != md->anon && md->pages != md->dirty) + seq_printf(m, " mapped=%lu", md->pages); - seq_putc(m, '\n'); - } + if (md->mapcount_max > 1) + seq_printf(m, " mapmax=%lu", md->mapcount_max); + + if (md->swapcache) + seq_printf(m," swapcache=%lu", md->swapcache); + + if (md->active < md->pages && !is_vm_hugetlb_page(vma)) + seq_printf(m," active=%lu", md->active); + + if (md->writeback) + seq_printf(m," writeback=%lu", md->writeback); + + for_each_online_node(n) + if (md->node[n]) + seq_printf(m, " N%d=%lu", n, md->node[n]); +out: + seq_putc(m, '\n'); kfree(md); if (m->count < m->size) diff --git a/mm/slab.c b/mm/slab.c index add05d808a4a..61800b88e241 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1124,6 +1124,7 @@ void __init kmem_cache_init(void) struct cache_sizes *sizes; struct cache_names *names; int i; + int order; for (i = 0; i < NUM_INIT_LISTS; i++) { kmem_list3_init(&initkmem_list3[i]); @@ -1167,11 +1168,15 @@ void __init kmem_cache_init(void) cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size()); - cache_estimate(0, cache_cache.buffer_size, cache_line_size(), 0, - &left_over, &cache_cache.num); + for (order = 0; order < MAX_ORDER; order++) { + cache_estimate(order, cache_cache.buffer_size, + cache_line_size(), 0, &left_over, &cache_cache.num); + if (cache_cache.num) + break; + } if (!cache_cache.num) BUG(); - + cache_cache.gfporder = order; cache_cache.colour = left_over / cache_cache.colour_off; cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + sizeof(struct slab), cache_line_size()); @@ -1628,36 +1633,44 @@ static inline size_t calculate_slab_order(struct kmem_cache *cachep, size_t size, size_t align, unsigned long flags) { size_t left_over = 0; + int gfporder; - for (;; cachep->gfporder++) { + for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) { unsigned int num; size_t remainder; - if (cachep->gfporder > MAX_GFP_ORDER) { - cachep->num = 0; - break; - } - - cache_estimate(cachep->gfporder, size, align, flags, - &remainder, &num); + cache_estimate(gfporder, size, align, flags, &remainder, &num); if (!num) continue; + /* More than offslab_limit objects will cause problems */ - if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) + if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit) break; + /* Found something acceptable - save it away */ cachep->num = num; + cachep->gfporder = gfporder; left_over = remainder; /* + * A VFS-reclaimable slab tends to have most allocations + * as GFP_NOFS and we really don't want to have to be allocating + * higher-order pages when we are unable to shrink dcache. + */ + if (flags & SLAB_RECLAIM_ACCOUNT) + break; + + /* * Large number of objects is good, but very large slabs are * currently bad for the gfp()s. */ - if (cachep->gfporder >= slab_break_gfp_order) + if (gfporder >= slab_break_gfp_order) break; - if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder)) - /* Acceptable internal fragmentation */ + /* + * Acceptable internal fragmentation? + */ + if ((left_over * 8) <= (PAGE_SIZE << gfporder)) break; } return left_over; @@ -1869,17 +1882,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, size = ALIGN(size, align); - if ((flags & SLAB_RECLAIM_ACCOUNT) && size <= PAGE_SIZE) { - /* - * A VFS-reclaimable slab tends to have most allocations - * as GFP_NOFS and we really don't want to have to be allocating - * higher-order pages when we are unable to shrink dcache. - */ - cachep->gfporder = 0; - cache_estimate(cachep->gfporder, size, align, flags, - &left_over, &cachep->num); - } else - left_over = calculate_slab_order(cachep, size, align, flags); + left_over = calculate_slab_order(cachep, size, align, flags); if (!cachep->num) { printk("kmem_cache_create: couldn't create cache %s.\n", name); @@ -2554,7 +2557,7 @@ static void check_slabp(struct kmem_cache *cachep, struct slab *slabp) "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n", cachep->name, cachep->num, slabp, slabp->inuse); for (i = 0; - i < sizeof(slabp) + cachep->num * sizeof(kmem_bufctl_t); + i < sizeof(*slabp) + cachep->num * sizeof(kmem_bufctl_t); i++) { if ((i % 16) == 0) printk("\n%03x:", i); diff --git a/mm/swap.c b/mm/swap.c index cce3dda59c59..e9ec06d845e8 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -489,13 +489,34 @@ void percpu_counter_mod(struct percpu_counter *fbc, long amount) if (count >= FBC_BATCH || count <= -FBC_BATCH) { spin_lock(&fbc->lock); fbc->count += count; + *pcount = 0; spin_unlock(&fbc->lock); - count = 0; + } else { + *pcount = count; } - *pcount = count; put_cpu(); } EXPORT_SYMBOL(percpu_counter_mod); + +/* + * Add up all the per-cpu counts, return the result. This is a more accurate + * but much slower version of percpu_counter_read_positive() + */ +long percpu_counter_sum(struct percpu_counter *fbc) +{ + long ret; + int cpu; + + spin_lock(&fbc->lock); + ret = fbc->count; + for_each_cpu(cpu) { + long *pcount = per_cpu_ptr(fbc->counters, cpu); + ret += *pcount; + } + spin_unlock(&fbc->lock); + return ret < 0 ? 0 : ret; +} +EXPORT_SYMBOL(percpu_counter_sum); #endif /* diff --git a/net/atm/signaling.c b/net/atm/signaling.c index 93ad59a28ef5..31d98b57e1de 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c @@ -39,25 +39,19 @@ static DECLARE_WAIT_QUEUE_HEAD(sigd_sleep); static void sigd_put_skb(struct sk_buff *skb) { #ifdef WAIT_FOR_DEMON - static unsigned long silence; DECLARE_WAITQUEUE(wait,current); add_wait_queue(&sigd_sleep,&wait); while (!sigd) { set_current_state(TASK_UNINTERRUPTIBLE); - if (time_after(jiffies, silence) || silence == 0) { - printk(KERN_INFO "atmsvc: waiting for signaling demon " - "...\n"); - silence = (jiffies+30*HZ)|1; - } + DPRINTK("atmsvc: waiting for signaling demon...\n"); schedule(); } current->state = TASK_RUNNING; remove_wait_queue(&sigd_sleep,&wait); #else if (!sigd) { - if (net_ratelimit()) - printk(KERN_WARNING "atmsvc: no signaling demon\n"); + DPRINTK("atmsvc: no signaling demon\n"); kfree_skb(skb); return; } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 7fa3a5a9971f..f36b35edd60c 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -81,26 +81,27 @@ static void port_carrier_check(void *arg) { struct net_device *dev = arg; struct net_bridge_port *p; + struct net_bridge *br; rtnl_lock(); p = dev->br_port; if (!p) goto done; - - if (netif_carrier_ok(p->dev)) { - u32 cost = port_cost(p->dev); - - spin_lock_bh(&p->br->lock); - if (p->state == BR_STATE_DISABLED) { - p->path_cost = cost; - br_stp_enable_port(p); + br = p->br; + + if (netif_carrier_ok(dev)) + p->path_cost = port_cost(dev); + + if (br->dev->flags & IFF_UP) { + spin_lock_bh(&br->lock); + if (netif_carrier_ok(dev)) { + if (p->state == BR_STATE_DISABLED) + br_stp_enable_port(p); + } else { + if (p->state != BR_STATE_DISABLED) + br_stp_disable_port(p); } - spin_unlock_bh(&p->br->lock); - } else { - spin_lock_bh(&p->br->lock); - if (p->state != BR_STATE_DISABLED) - br_stp_disable_port(p); - spin_unlock_bh(&p->br->lock); + spin_unlock_bh(&br->lock); } done: rtnl_unlock(); @@ -168,6 +169,7 @@ static void del_nbp(struct net_bridge_port *p) rcu_assign_pointer(dev->br_port, NULL); + kobject_uevent(&p->kobj, KOBJ_REMOVE); kobject_del(&p->kobj); call_rcu(&p->rcu, destroy_nbp_rcu); @@ -276,8 +278,9 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, br_init_port(p); p->state = BR_STATE_DISABLED; INIT_WORK(&p->carrier_check, port_carrier_check, dev); - kobject_init(&p->kobj); + br_stp_port_timer_init(p); + kobject_init(&p->kobj); kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR); p->kobj.ktype = &brport_ktype; p->kobj.parent = &(dev->class_dev.kobj); diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 35cf3a074087..23dea1422c9a 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -39,8 +39,6 @@ void br_init_port(struct net_bridge_port *p) p->state = BR_STATE_BLOCKING; p->topology_change_ack = 0; p->config_pending = 0; - - br_stp_port_timer_init(p); } /* called under bridge lock */ diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index aa68e0ab274d..35d1d347541c 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -2,7 +2,7 @@ * net/dccp/ccids/ccid3.c * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz> + * Copyright (c) 2005-6 Ian McDonald <imcdnzl@gmail.com> * * An implementation of the DCCP protocol * @@ -1033,9 +1033,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) p_prev = hcrx->ccid3hcrx_p; /* Calculate loss event rate */ - if (!list_empty(&hcrx->ccid3hcrx_li_hist)) + if (!list_empty(&hcrx->ccid3hcrx_li_hist)) { + u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist); + /* Scaling up by 1000000 as fixed decimal */ - hcrx->ccid3hcrx_p = 1000000 / dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist); + if (i_mean != 0) + hcrx->ccid3hcrx_p = 1000000 / i_mean; + } if (hcrx->ccid3hcrx_p > p_prev) { ccid3_hc_rx_send_feedback(sk); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 36339eb39e17..08f80e2ea2aa 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -524,7 +524,7 @@ ipq_rcv_skb(struct sk_buff *skb) write_unlock_bh(&queue_lock); status = ipq_receive_peer(NLMSG_DATA(nlh), type, - skblen - NLMSG_LENGTH(0)); + nlmsglen - NLMSG_LENGTH(0)); if (status < 0) RCV_SKB_FAIL(status); diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 5027bbe6415e..af0635084df8 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -522,7 +522,7 @@ ipq_rcv_skb(struct sk_buff *skb) write_unlock_bh(&queue_lock); status = ipq_receive_peer(NLMSG_DATA(nlh), type, - skblen - NLMSG_LENGTH(0)); + nlmsglen - NLMSG_LENGTH(0)); if (status < 0) RCV_SKB_FAIL(status); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 1b5989b1b670..c323cc6a28b0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -547,7 +547,7 @@ static struct sock * unix_create1(struct socket *sock) struct sock *sk = NULL; struct unix_sock *u; - if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files) + if (atomic_read(&unix_nr_socks) >= 2*get_max_files()) goto out; sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index be97caf664bb..c164b230ad6f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -246,7 +246,7 @@ static int do_ccw_entry(const char *filename, id->cu_model); ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, id->dev_type); - ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, + ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, id->dev_model); return 1; } diff --git a/sound/core/control.c b/sound/core/control.c index abd62f943726..0c29679a8576 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -959,17 +959,15 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl.private_free = snd_ctl_elem_user_free; _kctl = snd_ctl_new(&kctl, access); if (_kctl == NULL) { - kfree(_kctl->private_data); + kfree(ue); return -ENOMEM; } _kctl->private_data = ue; for (idx = 0; idx < _kctl->count; idx++) _kctl->vd[idx].owner = file; err = snd_ctl_add(card, _kctl); - if (err < 0) { - snd_ctl_free_one(_kctl); + if (err < 0) return err; - } down_write(&card->controls_rwsem); card->user_ctl_count++; |