diff --git a/[refs] b/[refs] index 978f900a4d94..5c13cbbbd4b2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b05de01ae1c76b7d61da21bbcc26345bf7a9052f +refs/heads/master: 69aa234b918c0d9bc4a20cd6d4453aaa3418f457 diff --git a/trunk/Documentation/fujitsu/frv/kernel-ABI.txt b/trunk/Documentation/fujitsu/frv/kernel-ABI.txt deleted file mode 100644 index 0ed9b0a779bc..000000000000 --- a/trunk/Documentation/fujitsu/frv/kernel-ABI.txt +++ /dev/null @@ -1,234 +0,0 @@ - ================================= - INTERNAL KERNEL ABI FOR FR-V ARCH - ================================= - -The internal FRV kernel ABI is not quite the same as the userspace ABI. A number of the registers -are used for special purposed, and the ABI is not consistent between modules vs core, and MMU vs -no-MMU. - -This partly stems from the fact that FRV CPUs do not have a separate supervisor stack pointer, and -most of them do not have any scratch registers, thus requiring at least one general purpose -register to be clobbered in such an event. Also, within the kernel core, it is possible to simply -jump or call directly between functions using a relative offset. This cannot be extended to modules -for the displacement is likely to be too far. Thus in modules the address of a function to call -must be calculated in a register and then used, requiring two extra instructions. - -This document has the following sections: - - (*) System call register ABI - (*) CPU operating modes - (*) Internal kernel-mode register ABI - (*) Internal debug-mode register ABI - (*) Virtual interrupt handling - - -======================== -SYSTEM CALL REGISTER ABI -======================== - -When a system call is made, the following registers are effective: - - REGISTERS CALL RETURN - =============== ======================= ======================= - GR7 System call number Preserved - GR8 Syscall arg #1 Return value - GR9-GR13 Syscall arg #2-6 Preserved - - -=================== -CPU OPERATING MODES -=================== - -The FR-V CPU has three basic operating modes. In order of increasing capability: - - (1) User mode. - - Basic userspace running mode. - - (2) Kernel mode. - - Normal kernel mode. There are many additional control registers available that may be - accessed in this mode, in addition to all the stuff available to user mode. This has two - submodes: - - (a) Exceptions enabled (PSR.T == 1). - - Exceptions will invoke the appropriate normal kernel mode handler. On entry to the - handler, the PSR.T bit will be cleared. - - (b) Exceptions disabled (PSR.T == 0). - - No exceptions or interrupts may happen. Any mandatory exceptions will cause the CPU to - halt unless the CPU is told to jump into debug mode instead. - - (3) Debug mode. - - No exceptions may happen in this mode. Memory protection and management exceptions will be - flagged for later consideration, but the exception handler won't be invoked. Debugging traps - such as hardware breakpoints and watchpoints will be ignored. This mode is entered only by - debugging events obtained from the other two modes. - - All kernel mode registers may be accessed, plus a few extra debugging specific registers. - - -================================= -INTERNAL KERNEL-MODE REGISTER ABI -================================= - -There are a number of permanent register assignments that are set up by entry.S in the exception -prologue. Note that there is a complete set of exception prologues for each of user->kernel -transition and kernel->kernel transition. There are also user->debug and kernel->debug mode -transition prologues. - - - REGISTER FLAVOUR USE - =============== ======= ==================================================== - GR1 Supervisor stack pointer - GR15 Current thread info pointer - GR16 GP-Rel base register for small data - GR28 Current exception frame pointer (__frame) - GR29 Current task pointer (current) - GR30 Destroyed by kernel mode entry - GR31 NOMMU Destroyed by debug mode entry - GR31 MMU Destroyed by TLB miss kernel mode entry - CCR.ICC2 Virtual interrupt disablement tracking - CCCR.CC3 Cleared by exception prologue (atomic op emulation) - SCR0 MMU See mmu-layout.txt. - SCR1 MMU See mmu-layout.txt. - SCR2 MMU Save for EAR0 (destroyed by icache insns in debug mode) - SCR3 MMU Save for GR31 during debug exceptions - DAMR/IAMR NOMMU Fixed memory protection layout. - DAMR/IAMR MMU See mmu-layout.txt. - - -Certain registers are also used or modified across function calls: - - REGISTER CALL RETURN - =============== =============================== =============================== - GR0 Fixed Zero - - GR2 Function call frame pointer - GR3 Special Preserved - GR3-GR7 - Clobbered - GR8 Function call arg #1 Return value (or clobbered) - GR9 Function call arg #2 Return value MSW (or clobbered) - GR10-GR13 Function call arg #3-#6 Clobbered - GR14 - Clobbered - GR15-GR16 Special Preserved - GR17-GR27 - Preserved - GR28-GR31 Special Only accessed explicitly - LR Return address after CALL Clobbered - CCR/CCCR - Mostly Clobbered - - -================================ -INTERNAL DEBUG-MODE REGISTER ABI -================================ - -This is the same as the kernel-mode register ABI for functions calls. The difference is that in -debug-mode there's a different stack and a different exception frame. Almost all the global -registers from kernel-mode (including the stack pointer) may be changed. - - REGISTER FLAVOUR USE - =============== ======= ==================================================== - GR1 Debug stack pointer - GR16 GP-Rel base register for small data - GR31 Current debug exception frame pointer (__debug_frame) - SCR3 MMU Saved value of GR31 - - -Note that debug mode is able to interfere with the kernel's emulated atomic ops, so it must be -exceedingly careful not to do any that would interact with the main kernel in this regard. Hence -the debug mode code (gdbstub) is almost completely self-contained. The only external code used is -the sprintf family of functions. - -Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an -exception. That means unless manually disabled, single-stepping will blithely go on stepping into -things like interrupts. See gdbstub.txt for more information. - - -========================== -VIRTUAL INTERRUPT HANDLING -========================== - -Because accesses to the PSR is so slow, and to disable interrupts we have to access it twice (once -to read and once to write), we don't actually disable interrupts at all if we don't have to. What -we do instead is use the ICC2 condition code flags to note virtual disablement, such that if we -then do take an interrupt, we note the flag, really disable interrupts, set another flag and resume -execution at the point the interrupt happened. Setting condition flags as a side effect of an -arithmetic or logical instruction is really fast. This use of the ICC2 only occurs within the -kernel - it does not affect userspace. - -The flags we use are: - - (*) CCR.ICC2.Z [Zero flag] - - Set to virtually disable interrupts, clear when interrupts are virtually enabled. Can be - modified by logical instructions without affecting the Carry flag. - - (*) CCR.ICC2.C [Carry flag] - - Clear to indicate hardware interrupts are really disabled, set otherwise. - - -What happens is this: - - (1) Normal kernel-mode operation. - - ICC2.Z is 0, ICC2.C is 1. - - (2) An interrupt occurs. The exception prologue examines ICC2.Z and determines that nothing needs - doing. This is done simply with an unlikely BEQ instruction. - - (3) The interrupts are disabled (local_irq_disable) - - ICC2.Z is set to 1. - - (4) If interrupts were then re-enabled (local_irq_enable): - - ICC2.Z would be set to 0. - - A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would be used to trap if - interrupts were now virtually enabled, but physically disabled - which they're not, so the - trap isn't taken. The kernel would then be back to state (1). - - (5) An interrupt occurs. The exception prologue examines ICC2.Z and determines that the interrupt - shouldn't actually have happened. It jumps aside, and there disabled interrupts by setting - PSR.PIL to 14 and then it clears ICC2.C. - - (6) If interrupts were then saved and disabled again (local_irq_save): - - ICC2.Z would be shifted into the save variable and masked off (giving a 1). - - ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be unaffected (ie: 0). - - (7) If interrupts were then restored from state (6) (local_irq_restore): - - ICC2.Z would be set to indicate the result of XOR'ing the saved value (ie: 1) with 1, which - gives a result of 0 - thus leaving ICC2.Z set. - - ICC2.C would remain unaffected (ie: 0). - - A TIHI #2 instruction would be used to again assay the current state, but this would do - nothing as Z==1. - - (8) If interrupts were then enabled (local_irq_enable): - - ICC2.Z would be cleared. ICC2.C would be left unaffected. Both flags would now be 0. - - A TIHI #2 instruction again issued to assay the current state would then trap as both Z==0 - [interrupts virtually enabled] and C==0 [interrupts really disabled] would then be true. - - (9) The trap #2 handler would simply enable hardware interrupts (set PSR.PIL to 0), set ICC2.C to - 1 and return. - -(10) Immediately upon returning, the pending interrupt would be taken. - -(11) The interrupt handler would take the path of actually processing the interrupt (ICC2.Z is - clear, BEQ fails as per step (2)). - -(12) The interrupt handler would then set ICC2.C to 1 since hardware interrupts are definitely - enabled - or else the kernel wouldn't be here. - -(13) On return from the interrupt handler, things would be back to state (1). - -This trap (#2) is only available in kernel mode. In user mode it will result in SIGILL. diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index 2c3b1eae4280..0ea5a0c6e827 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -136,20 +136,17 @@ Kprobes, jprobes, and return probes are implemented on the following architectures: - i386 -- x86_64 (AMD-64, EM64T) +- x86_64 (AMD-64, E64MT) - ppc64 -- ia64 (Does not support probes on instruction slot1.) +- ia64 (Support for probes on certain instruction types is still in progress.) - sparc64 (Return probes not yet implemented.) 3. Configuring Kprobes When configuring the kernel using make menuconfig/xconfig/oldconfig, -ensure that CONFIG_KPROBES is set to "y". Under "Instrumentation -Support", look for "Kprobes". - -So that you can load and unload Kprobes-based instrumentation modules, -make sure "Loadable module support" (CONFIG_MODULES) and "Module -unloading" (CONFIG_MODULE_UNLOAD) are set to "y". +ensure that CONFIG_KPROBES is set to "y". Under "Kernel hacking", +look for "Kprobes". You may have to enable "Kernel debugging" +(CONFIG_DEBUG_KERNEL) before you can enable Kprobes. You may also want to ensure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name() @@ -265,18 +262,18 @@ at any time after the probe has been registered. 5. Kprobes Features and Limitations -Kprobes allows multiple probes at the same address. Currently, -however, there cannot be multiple jprobes on the same function at -the same time. +As of Linux v2.6.12, Kprobes allows multiple probes at the same +address. Currently, however, there cannot be multiple jprobes on +the same function at the same time. In general, you can install a probe anywhere in the kernel. In particular, you can probe interrupt handlers. Known exceptions are discussed in this section. -The register_*probe functions will return -EINVAL if you attempt -to install a probe in the code that implements Kprobes (mostly -kernel/kprobes.c and arch/*/kernel/kprobes.c, but also functions such -as do_page_fault and notifier_call_chain). +For obvious reasons, it's a bad idea to install a probe in +the code that implements Kprobes (mostly kernel/kprobes.c and +arch/*/kernel/kprobes.c). A patch in the v2.6.13 timeframe instructs +Kprobes to reject such requests. If you install a probe in an inline-able function, Kprobes makes no attempt to chase down all inline instances of the function and @@ -293,14 +290,18 @@ from the accidental ones. Don't drink and probe. Kprobes makes no attempt to prevent probe handlers from stepping on each other -- e.g., probing printk() and then calling printk() from a -probe handler. If a probe handler hits a probe, that second probe's -handlers won't be run in that instance, and the kprobe.nmissed member -of the second probe will be incremented. - -As of Linux v2.6.15-rc1, multiple handlers (or multiple instances of -the same handler) may run concurrently on different CPUs. - -Kprobes does not use mutexes or allocate memory except during +probe handler. As of Linux v2.6.12, if a probe handler hits a probe, +that second probe's handlers won't be run in that instance. + +In Linux v2.6.12 and previous versions, Kprobes' data structures are +protected by a single lock that is held during probe registration and +unregistration and while handlers are run. Thus, no two handlers +can run simultaneously. To improve scalability on SMP systems, +this restriction will probably be removed soon, in which case +multiple handlers (or multiple instances of the same handler) may +run concurrently on different CPUs. Code your handlers accordingly. + +Kprobes does not use semaphores or allocate memory except during registration and unregistration. Probe handlers are run with preemption disabled. Depending on the @@ -315,18 +316,11 @@ address instead of the real return address for kretprobed functions. (As far as we can tell, __builtin_return_address() is used only for instrumentation and error reporting.) -If the number of times a function is called does not match the number -of times it returns, registering a return probe on that function may -produce undesirable results. We have the do_exit() case covered. -do_execve() and do_fork() are not an issue. We're unaware of other -specific cases where this could be a problem. - -If, upon entry to or exit from a function, the CPU is running on -a stack other than that of the current task, registering a return -probe on that function may produce undesirable results. For this -reason, Kprobes doesn't support return probes (or kprobes or jprobes) -on the x86_64 version of __switch_to(); the registration functions -return -EINVAL. +If the number of times a function is called does not match the +number of times it returns, registering a return probe on that +function may produce undesirable results. We have the do_exit() +and do_execve() cases covered. do_fork() is not an issue. We're +unaware of other specific cases where this could be a problem. 6. Probe Overhead @@ -353,12 +347,14 @@ k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99 7. TODO -a. SystemTap (http://sourceware.org/systemtap): Provides a simplified -programming interface for probe-based instrumentation. Try it out. -b. Kernel return probes for sparc64. -c. Support for other architectures. -d. User-space probes. -e. Watchpoint probes (which fire on data references). +a. SystemTap (http://sourceware.org/systemtap): Work in progress +to provide a simplified programming interface for probe-based +instrumentation. +b. Improved SMP scalability: Currently, work is in progress to handle +multiple kprobes in parallel. +c. Kernel return probes for sparc64. +d. Support for other architectures. +e. User-space probes. 8. Kprobes Example @@ -415,7 +411,8 @@ int init_module(void) printk("Couldn't find %s to plant kprobe\n", "do_fork"); return -1; } - if ((ret = register_kprobe(&kp) < 0)) { + ret = register_kprobe(&kp); + if (ret < 0) { printk("register_kprobe failed, returned %d\n", ret); return -1; } diff --git a/trunk/Documentation/mips/AU1xxx_IDE.README b/trunk/Documentation/mips/AU1xxx_IDE.README index afb31c141d9d..a7e4c4ea3560 100644 --- a/trunk/Documentation/mips/AU1xxx_IDE.README +++ b/trunk/Documentation/mips/AU1xxx_IDE.README @@ -95,13 +95,11 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDE_AU1XXX=y CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y +CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y -Also define 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to enable -the burst support on DBDMA controller. - If the used system need the USB support enable the following kernel configs for high IDE to USB throughput. @@ -117,8 +115,6 @@ CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y -Also undefine 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to -disable the burst support on DBDMA controller. ADD NEW HARD DISC TO WHITE OR BLACK LIST ---------------------------------------- diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index e08383712370..60a617aff8ba 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -25,10 +25,6 @@ config GENERIC_HARDIRQS bool default n -config TIME_LOW_RES - bool - default y - mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/trunk/arch/frv/Makefile b/trunk/arch/frv/Makefile index d163747d17c0..90c0fb8d9dc3 100644 --- a/trunk/arch/frv/Makefile +++ b/trunk/arch/frv/Makefile @@ -81,7 +81,7 @@ endif # - reserve CC3 for use with atomic ops # - all the extra registers are dealt with only at context switch time CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media -CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2 +CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 AFLAGS += -mno-fdpic ASFLAGS += -mno-fdpic diff --git a/trunk/arch/frv/kernel/break.S b/trunk/arch/frv/kernel/break.S index 687c48d62dde..33233dc23e29 100644 --- a/trunk/arch/frv/kernel/break.S +++ b/trunk/arch/frv/kernel/break.S @@ -200,20 +200,12 @@ __break_step: movsg bpcsr,gr2 sethi.p %hi(__entry_kernel_external_interrupt),gr3 setlo %lo(__entry_kernel_external_interrupt),gr3 - subcc.p gr2,gr3,gr0,icc0 - sethi %hi(__entry_uspace_external_interrupt),gr3 - setlo.p %lo(__entry_uspace_external_interrupt),gr3 + subcc gr2,gr3,gr0,icc0 beq icc0,#2,__break_step_kernel_external_interrupt - subcc.p gr2,gr3,gr0,icc0 - sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3 - setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3 - beq icc0,#2,__break_step_uspace_external_interrupt - subcc.p gr2,gr3,gr0,icc0 - sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3 - setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3 - beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled + sethi.p %hi(__entry_uspace_external_interrupt),gr3 + setlo %lo(__entry_uspace_external_interrupt),gr3 subcc gr2,gr3,gr0,icc0 - beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable + beq icc0,#2,__break_step_uspace_external_interrupt LEDS 0x2007,gr2 @@ -262,9 +254,6 @@ __break_step_kernel_softprog_interrupt: # step through an external interrupt from kernel mode .globl __break_step_kernel_external_interrupt __break_step_kernel_external_interrupt: - # deal with virtual interrupt disablement - beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled - sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3 setlo %lo(__entry_kernel_external_interrupt_reentry),gr3 @@ -305,64 +294,6 @@ __break_return_as_kernel_prologue: #endif rett #1 -# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled -# need to really disable interrupts, set flag, fix up and return -__break_step_kernel_external_interrupt_virtually_disabled: - movsg psr,gr2 - andi gr2,#~PSR_PIL,gr2 - ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */ - movgs gr2,psr - - ldi @(gr31,#REG_CCR),gr3 - movgs gr3,ccr - subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */ - - # exceptions must've been enabled and we must've been in supervisor mode - setlos BPSR_BET|BPSR_BS,gr3 - movgs gr3,bpsr - - # return to where the interrupt happened - movsg pcsr,gr2 - movgs gr2,bpcsr - - lddi.p @(gr31,#REG_GR(2)),gr2 - - xor gr31,gr31,gr31 - movgs gr0,brr -#ifdef CONFIG_MMU - movsg scr3,gr31 -#endif - rett #1 - -# we stepped through into the virtual interrupt reenablement trap -# -# we also want to single step anyway, but after fixing up so that we get an event on the -# instruction after the broken-into exception returns - .globl __break_step_kernel_external_interrupt_virtual_reenable -__break_step_kernel_external_interrupt_virtual_reenable: - movsg psr,gr2 - andi gr2,#~PSR_PIL,gr2 - movgs gr2,psr - - ldi @(gr31,#REG_CCR),gr3 - movgs gr3,ccr - subicc gr0,#1,gr0,icc2 /* clear Z, set C */ - - # save the adjusted ICC2 - movsg ccr,gr3 - sti gr3,@(gr31,#REG_CCR) - - # exceptions must've been enabled and we must've been in supervisor mode - setlos BPSR_BET|BPSR_BS,gr3 - movgs gr3,bpsr - - # return to where the trap happened - movsg pcsr,gr2 - movgs gr2,bpcsr - - # and then process the single step - bra __break_continue - # step through an internal exception from uspace mode .globl __break_step_uspace_softprog_interrupt __break_step_uspace_softprog_interrupt: diff --git a/trunk/arch/frv/kernel/entry-table.S b/trunk/arch/frv/kernel/entry-table.S index 81568acea9cd..9b9243e2103c 100644 --- a/trunk/arch/frv/kernel/entry-table.S +++ b/trunk/arch/frv/kernel/entry-table.S @@ -116,8 +116,6 @@ __break_kerneltrap_fixup_table: .long __break_step_uspace_external_interrupt .section .trap.kernel .org \tbr_tt - # deal with virtual interrupt disablement - beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled bra __entry_kernel_external_interrupt .section .trap.fixup.kernel .org \tbr_tt >> 2 @@ -261,52 +259,25 @@ __trap_fixup_kernel_data_tlb_miss: .org TBR_TT_TRAP0 .rept 127 bra __entry_uspace_softprog_interrupt - .long 0,0,0 + bra __break_step_uspace_softprog_interrupt + .long 0,0 .endr .org TBR_TT_BREAK bra __entry_break .long 0,0,0 - .section .trap.fixup.user - .org TBR_TT_TRAP0 >> 2 - .rept 127 - .long __break_step_uspace_softprog_interrupt - .endr - .org TBR_TT_BREAK >> 2 - .long 0 - # miscellaneous kernel mode entry points .section .trap.kernel .org TBR_TT_TRAP0 + .rept 127 bra __entry_kernel_softprog_interrupt - .org TBR_TT_TRAP1 - bra __entry_kernel_softprog_interrupt - - # trap #2 in kernel - reenable interrupts - .org TBR_TT_TRAP2 - bra __entry_kernel_external_interrupt_virtual_reenable - - # miscellaneous kernel traps - .org TBR_TT_TRAP3 - .rept 124 - bra __entry_kernel_softprog_interrupt - .long 0,0,0 + bra __break_step_kernel_softprog_interrupt + .long 0,0 .endr .org TBR_TT_BREAK bra __entry_break .long 0,0,0 - .section .trap.fixup.kernel - .org TBR_TT_TRAP0 >> 2 - .long __break_step_kernel_softprog_interrupt - .long __break_step_kernel_softprog_interrupt - .long __break_step_kernel_external_interrupt_virtual_reenable - .rept 124 - .long __break_step_kernel_softprog_interrupt - .endr - .org TBR_TT_BREAK >> 2 - .long 0 - # miscellaneous debug mode entry points .section .trap.break .org TBR_TT_BREAK diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index 1d21c8d34d8a..5f6548388b74 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -141,10 +141,7 @@ __entry_uspace_external_interrupt_reentry: movsg gner0,gr4 movsg gner1,gr5 - stdi.p gr4,@(gr28,#REG_GNER0) - - # interrupts start off fully disabled in the interrupt handler - subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ + stdi gr4,@(gr28,#REG_GNER0) # set up kernel global registers sethi.p %hi(__kernel_current_task),gr5 @@ -196,8 +193,9 @@ __entry_uspace_external_interrupt_reentry: .type __entry_kernel_external_interrupt,@function __entry_kernel_external_interrupt: LEDS 0x6210 -// sub sp,gr15,gr31 -// LEDS32 + + sub sp,gr15,gr31 + LEDS32 # set up the stack pointer or.p sp,gr0,gr30 @@ -233,10 +231,7 @@ __entry_kernel_external_interrupt_reentry: stdi gr24,@(gr28,#REG_GR(24)) stdi gr26,@(gr28,#REG_GR(26)) sti gr29,@(gr28,#REG_GR(29)) - stdi.p gr30,@(gr28,#REG_GR(30)) - - # note virtual interrupts will be fully enabled upon return - subicc gr0,#1,gr0,icc2 /* clear Z, set C */ + stdi gr30,@(gr28,#REG_GR(30)) movsg tbr ,gr20 movsg psr ,gr22 @@ -272,10 +267,7 @@ __entry_kernel_external_interrupt_reentry: movsg gner0,gr4 movsg gner1,gr5 - stdi.p gr4,@(gr28,#REG_GNER0) - - # interrupts start off fully disabled in the interrupt handler - subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ + stdi gr4,@(gr28,#REG_GNER0) # set the return address sethi.p %hi(__entry_return_from_kernel_interrupt),gr4 @@ -299,45 +291,6 @@ __entry_kernel_external_interrupt_reentry: .size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt -############################################################################### -# -# deal with interrupts that were actually virtually disabled -# - we need to really disable them, flag the fact and return immediately -# - if you change this, you must alter break.S also -# -############################################################################### - .balign L1_CACHE_BYTES - .globl __entry_kernel_external_interrupt_virtually_disabled - .type __entry_kernel_external_interrupt_virtually_disabled,@function -__entry_kernel_external_interrupt_virtually_disabled: - movsg psr,gr30 - andi gr30,#~PSR_PIL,gr30 - ori gr30,#PSR_PIL_14,gr30 ; debugging interrupts only - movgs gr30,psr - subcc gr0,gr0,gr0,icc2 ; leave Z set, clear C - rett #0 - - .size __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled - -############################################################################### -# -# deal with re-enablement of interrupts that were pending when virtually re-enabled -# - set ICC2.C, re-enable the real interrupts and return -# - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI] -# - if you change this, you must alter break.S also -# -############################################################################### - .balign L1_CACHE_BYTES - .globl __entry_kernel_external_interrupt_virtual_reenable - .type __entry_kernel_external_interrupt_virtual_reenable,@function -__entry_kernel_external_interrupt_virtual_reenable: - movsg psr,gr30 - andi gr30,#~PSR_PIL,gr30 ; re-enable interrupts - movgs gr30,psr - subicc gr0,#1,gr0,icc2 ; clear Z, set C - rett #0 - - .size __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable ############################################################################### # @@ -382,7 +335,6 @@ __entry_uspace_softprog_interrupt_reentry: sethi.p %hi(__entry_return_from_user_exception),gr23 setlo %lo(__entry_return_from_user_exception),gr23 - bra __entry_common .size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt @@ -543,10 +495,7 @@ __entry_common: movsg gner0,gr4 movsg gner1,gr5 - stdi.p gr4,@(gr28,#REG_GNER0) - - # set up virtual interrupt disablement - subicc gr0,#1,gr0,icc2 /* clear Z flag, set C flag */ + stdi gr4,@(gr28,#REG_GNER0) # set up kernel global registers sethi.p %hi(__kernel_current_task),gr5 @@ -1469,27 +1418,11 @@ sys_call_table: .long sys_add_key .long sys_request_key .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get /* 290 */ - .long sys_inotify_init - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat /* 295 */ - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_newfstatat /* 300 */ - .long sys_unlinkat - .long sys_renameat - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat /* 305 */ - .long sys_fchmodat - .long sys_faccessat - .long sys_pselect6 - .long sys_ppoll + .long sys_ni_syscall // sys_vperfctr_open + .long sys_ni_syscall // sys_vperfctr_control /* 290 */ + .long sys_ni_syscall // sys_vperfctr_unlink + .long sys_ni_syscall // sys_vperfctr_iresume + .long sys_ni_syscall // sys_vperfctr_read syscall_table_size = (. - sys_call_table) diff --git a/trunk/arch/frv/kernel/head.S b/trunk/arch/frv/kernel/head.S index 29a5265489b7..c73b4fe9f6ca 100644 --- a/trunk/arch/frv/kernel/head.S +++ b/trunk/arch/frv/kernel/head.S @@ -513,9 +513,6 @@ __head_mmu_enabled: movgs gr0,ccr movgs gr0,cccr - # initialise the virtual interrupt handling - subcc gr0,gr0,gr0,icc2 /* set Z, clear C */ - #ifdef CONFIG_MMU movgs gr3,scr2 movgs gr3,scr3 diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index 27ab4c30aac6..59580c59c62c 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -287,11 +287,18 @@ asmlinkage void do_IRQ(void) struct irq_source *source; int level, cpu; - irq_enter(); - level = (__frame->tbr >> 4) & 0xf; cpu = smp_processor_id(); +#if 0 + { + static u32 irqcount; + *(volatile u32 *) 0xe1200004 = ~((irqcount++ << 8) | level); + *(volatile u16 *) 0xffc00100 = (u16) ~0x9999; + mb(); + } +#endif + if ((unsigned long) __frame - (unsigned long) (current + 1) < 512) BUG(); @@ -301,12 +308,40 @@ asmlinkage void do_IRQ(void) kstat_this_cpu.irqs[level]++; + irq_enter(); + for (source = frv_irq_levels[level].sources; source; source = source->next) source->doirq(source); + irq_exit(); + __clr_MASK(level); - irq_exit(); + /* only process softirqs if we didn't interrupt another interrupt handler */ + if ((__frame->psr & PSR_PIL) == PSR_PIL_0) + if (local_softirq_pending()) + do_softirq(); + +#ifdef CONFIG_PREEMPT + local_irq_disable(); + while (--current->preempt_count == 0) { + if (!(__frame->psr & PSR_S) || + current->need_resched == 0 || + in_interrupt()) + break; + current->preempt_count++; + local_irq_enable(); + preempt_schedule(); + local_irq_disable(); + } +#endif + +#if 0 + { + *(volatile u16 *) 0xffc00100 = (u16) ~0x6666; + mb(); + } +#endif } /* end do_IRQ() */ diff --git a/trunk/arch/frv/mm/kmap.c b/trunk/arch/frv/mm/kmap.c index c54f18e65ea6..539f45e6d15e 100644 --- a/trunk/arch/frv/mm/kmap.c +++ b/trunk/arch/frv/mm/kmap.c @@ -43,6 +43,15 @@ void iounmap(void *addr) { } +/* + * __iounmap unmaps nearly everything, so be careful + * it doesn't free currently pointer/page tables anymore but it + * wans't used anyway and might be added later. + */ +void __iounmap(void *addr, unsigned long size) +{ +} + /* * Set new cache mode for some kernel address space. * The caller must push data for that range itself, if such data may already diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 98308b018a35..80940d712acf 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -33,10 +33,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config TIME_LOW_RES - bool - default y - config ISA bool default y diff --git a/trunk/arch/h8300/Kconfig.cpu b/trunk/arch/h8300/Kconfig.cpu index 582797db9603..a380167a13cf 100644 --- a/trunk/arch/h8300/Kconfig.cpu +++ b/trunk/arch/h8300/Kconfig.cpu @@ -169,7 +169,7 @@ endif config CPU_H8300H bool - depends on (H83002 || H83007 || H83048 || H83068) + depends on (H8002 || H83007 || H83048 || H83068) default y config CPU_H8S diff --git a/trunk/arch/i386/boot/.gitignore b/trunk/arch/i386/boot/.gitignore deleted file mode 100644 index 495f20c085de..000000000000 --- a/trunk/arch/i386/boot/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -bootsect -bzImage -setup diff --git a/trunk/arch/i386/boot/tools/.gitignore b/trunk/arch/i386/boot/tools/.gitignore deleted file mode 100644 index 378eac25d311..000000000000 --- a/trunk/arch/i386/boot/tools/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/trunk/arch/i386/kernel/.gitignore b/trunk/arch/i386/kernel/.gitignore deleted file mode 100644 index 40836ad9079c..000000000000 --- a/trunk/arch/i386/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vsyscall.lds diff --git a/trunk/arch/i386/kernel/vsyscall-sysenter.S b/trunk/arch/i386/kernel/vsyscall-sysenter.S index 76b728159403..4daefb2ec1b2 100644 --- a/trunk/arch/i386/kernel/vsyscall-sysenter.S +++ b/trunk/arch/i386/kernel/vsyscall-sysenter.S @@ -7,21 +7,6 @@ * for details. */ -/* - * The caller puts arg2 in %ecx, which gets pushed. The kernel will use - * %ecx itself for arg2. The pushing is because the sysexit instruction - * (found in entry.S) requires that we clobber %ecx with the desired %esp. - * User code might expect that %ecx is unclobbered though, as it would be - * for returning via the iret instruction, so we must push and pop. - * - * The caller puts arg3 in %edx, which the sysexit instruction requires - * for %eip. Thus, exactly as for arg2, we must push and pop. - * - * Arg6 is different. The caller puts arg6 in %ebp. Since the sysenter - * instruction clobbers %esp, the user's %esp won't even survive entry - * into the kernel. We store %esp in %ebp. Code in entry.S must fetch - * arg6 from the stack. - */ .text .globl __kernel_vsyscall .type __kernel_vsyscall,@function diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c index bbcfd08378a6..e72de580ebbf 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -10,8 +10,23 @@ #include EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strpbrk); #include EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 8f44e7d2df66..b681ef34a86e 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -129,7 +129,7 @@ DEFINE_PER_CPU(int, cpu_state); /* Bitmasks of currently online, and possible CPUs */ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -cpumask_t cpu_possible_map; +cpumask_t cpu_possible_map = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; @@ -506,9 +506,6 @@ smp_build_cpu_map (void) for (cpu = 0; cpu < NR_CPUS; cpu++) { ia64_cpu_to_sapicid[cpu] = -1; -#ifdef CONFIG_HOTPLUG_CPU - cpu_set(cpu, cpu_possible_map); -#endif } ia64_cpu_to_sapicid[0] = boot_cpu_id; diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 307d01e15b2e..a094ec49ccfa 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -250,27 +250,32 @@ time_init (void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); } -/* - * Generic udelay assumes that if preemption is allowed and the thread - * migrates to another CPU, that the ITC values are synchronized across - * all CPUs. - */ -static void -ia64_itc_udelay (unsigned long usecs) -{ - unsigned long start = ia64_get_itc(); - unsigned long end = start + usecs*local_cpu_data->cyc_per_usec; - - while (time_before(ia64_get_itc(), end)) - cpu_relax(); -} - -void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay; +#define SMALLUSECS 100 void udelay (unsigned long usecs) { - (*ia64_udelay)(usecs); + unsigned long start; + unsigned long cycles; + unsigned long smallusecs; + + /* + * Execute the non-preemptible delay loop (because the ITC might + * not be synchronized between CPUS) in relatively short time + * chunks, allowing preemption between the chunks. + */ + while (usecs > 0) { + smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs; + preempt_disable(); + cycles = smallusecs*local_cpu_data->cyc_per_usec; + start = ia64_get_itc(); + + while (ia64_get_itc() - start < cycles) + cpu_relax(); + + preempt_enable(); + usecs -= smallusecs; + } } EXPORT_SYMBOL(udelay); diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index dabd6c32641e..55391901b013 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -16,7 +16,6 @@ #include /* for EXPORT_SYMBOL */ #include #include -#include /* for ssleep() */ #include #include @@ -117,13 +116,6 @@ die (const char *str, struct pt_regs *regs, long err) bust_spinlocks(0); die.lock_owner = -1; spin_unlock_irq(&die.lock); - - if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); - panic("Fatal exception"); - } - do_exit(SIGSEGV); } diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index 3edef0d32f86..3437c2390429 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -23,10 +23,6 @@ #include "xtalk/hubdev.h" #include "xtalk/xwidgetdev.h" - -extern void sn_init_cpei_timer(void); -extern void register_sn_procfs(void); - static struct list_head sn_sysdata_list; /* sysdata list struct */ @@ -44,12 +40,12 @@ struct brick { struct slab_info slab_info[MAX_SLABS + 1]; }; -int sn_ioif_inited; /* SN I/O infrastructure initialized? */ +int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ -static int max_segment_number; /* Default highest segment number */ -static int max_pcibus_number = 255; /* Default highest pci bus number */ +static int max_segment_number = 0; /* Default highest segment number */ +static int max_pcibus_number = 255; /* Default highest pci bus number */ /* * Hooks and struct for unsupported pci providers @@ -88,6 +84,7 @@ static inline u64 sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, u64 address) { + struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -97,6 +94,7 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, (u64) nasid, (u64) widget_num, (u64) device_num, (u64) address, 0, 0, 0); return ret_stuff.status; + } /* @@ -104,6 +102,7 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, */ static inline u64 sal_get_hubdev_info(u64 handle, u64 address) { + struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -119,6 +118,7 @@ static inline u64 sal_get_hubdev_info(u64 handle, u64 address) */ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) { + struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -215,7 +215,7 @@ static void __init sn_fixup_ionodes(void) struct hubdev_info *hubdev; u64 status; u64 nasid; - int i, widget, device, size; + int i, widget, device; /* * Get SGI Specific HUB chipset information. @@ -251,37 +251,48 @@ static void __init sn_fixup_ionodes(void) if (!hubdev->hdi_flush_nasid_list.widget_p) continue; - size = (HUB_WIDGET_ID_MAX + 1) * - sizeof(struct sn_flush_device_kernel *); hubdev->hdi_flush_nasid_list.widget_p = - kzalloc(size, GFP_KERNEL); - if (!hubdev->hdi_flush_nasid_list.widget_p) - BUG(); + kmalloc((HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *), + GFP_KERNEL); + memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, + (HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *)); for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { - size = DEV_PER_WIDGET * - sizeof(struct sn_flush_device_kernel); - sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); + sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET * + sizeof(struct + sn_flush_device_kernel), + GFP_KERNEL); if (!sn_flush_device_kernel) BUG(); + memset(sn_flush_device_kernel, 0x0, + DEV_PER_WIDGET * + sizeof(struct sn_flush_device_kernel)); dev_entry = sn_flush_device_kernel; for (device = 0; device < DEV_PER_WIDGET; device++,dev_entry++) { - size = sizeof(struct sn_flush_device_common); - dev_entry->common = kzalloc(size, GFP_KERNEL); + dev_entry->common = kmalloc(sizeof(struct + sn_flush_device_common), + GFP_KERNEL); if (!dev_entry->common) BUG(); + memset(dev_entry->common, 0x0, sizeof(struct + sn_flush_device_common)); if (sn_prom_feature_available( PRF_DEVICE_FLUSH_LIST)) status = sal_get_device_dmaflush_list( - nasid, widget, device, - (u64)(dev_entry->common)); + nasid, + widget, + device, + (u64)(dev_entry->common)); else status = sn_device_fixup_war(nasid, - widget, device, - dev_entry->common); + widget, + device, + dev_entry->common); if (status != SALRET_OK) panic("SAL call failed: %s\n", ia64_sal_strerror(status)); @@ -372,12 +383,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) pci_dev_get(dev); /* for the sysdata pointer */ pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_info) + if (pcidev_info <= 0) BUG(); /* Cannot afford to run out of memory */ - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!sn_irq_info) + sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (sn_irq_info <= 0) BUG(); /* Cannot afford to run out of memory */ + memset(sn_irq_info, 0, sizeof(struct sn_irq_info)); /* Call to retrieve pci device information needed by kernel. */ status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, @@ -470,13 +482,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) */ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) { - int status; + int status = 0; int nasid, cnode; struct pci_controller *controller; struct sn_pci_controller *sn_controller; struct pcibus_bussoft *prom_bussoft_ptr; struct hubdev_info *hubdev_info; - void *provider_soft; + void *provider_soft = NULL; struct sn_pcibus_provider *provider; status = sal_get_pcibus_info((u64) segment, (u64) busnum, @@ -523,8 +535,6 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) bus->sysdata = controller; if (provider->bus_fixup) provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); - else - provider_soft = NULL; if (provider_soft == NULL) { /* fixup failed or not applicable */ @@ -628,8 +638,13 @@ void sn_bus_free_sysdata(void) static int __init sn_pci_init(void) { - int i, j; + int i = 0; + int j = 0; struct pci_dev *pci_dev = NULL; + extern void sn_init_cpei_timer(void); +#ifdef CONFIG_PROC_FS + extern void register_sn_procfs(void); +#endif if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; @@ -685,29 +700,32 @@ static int __init sn_pci_init(void) */ void hubdev_init_node(nodepda_t * npda, cnodeid_t node) { - struct hubdev_info *hubdev_info; - int size; - pg_data_t *pg; - size = sizeof(struct hubdev_info); + struct hubdev_info *hubdev_info; if (node >= num_online_nodes()) /* Headless/memless IO nodes */ - pg = NODE_DATA(0); + hubdev_info = + (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(0), + sizeof(struct + hubdev_info)); else - pg = NODE_DATA(node); - - hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); - + hubdev_info = + (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(node), + sizeof(struct + hubdev_info)); npda->pdinfo = (void *)hubdev_info; + } geoid_t cnodeid_get_geoid(cnodeid_t cnode) { + struct hubdev_info *hubdev; hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); return hubdev->hdi_geoid; + } subsys_initcall(sn_pci_init); @@ -716,4 +734,3 @@ EXPORT_SYMBOL(sn_pci_unfixup_slot); EXPORT_SYMBOL(sn_pci_controller_fixup); EXPORT_SYMBOL(sn_bus_store_sysdata); EXPORT_SYMBOL(sn_bus_free_sysdata); -EXPORT_SYMBOL(sn_pcidev_info_get); diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 5b84836c2171..48645ac120fc 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second); DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); EXPORT_PER_CPU_SYMBOL(__sn_hub_info); -DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); +DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); @@ -317,7 +317,6 @@ struct pcdp_vga_device { #define PCDP_PCI_TRANS_IOPORT 0x02 #define PCDP_PCI_TRANS_MMIO 0x01 -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) static void sn_scan_pcdp(void) { @@ -359,7 +358,6 @@ sn_scan_pcdp(void) break; /* once we find the primary, we're done */ } } -#endif static unsigned long sn2_rtc_initial; diff --git a/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c index 6ae276d5d50c..81c63b2f8ae9 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. * * Module to export the system's Firmware Interface Tables, including * PROM revision numbers and banners, in /proc @@ -190,7 +190,7 @@ static int read_version_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; + int len = 0; /* data holds the NASID of the node */ len = dump_version(page, (unsigned long)data); @@ -202,7 +202,7 @@ static int read_fit_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; + int len = 0; /* data holds the NASID of the node */ len = dump_fit(page, (unsigned long)data); @@ -229,16 +229,13 @@ int __init prominfo_init(void) struct proc_dir_entry *p; cnodeid_t cnodeid; unsigned long nasid; - int size; char name[NODE_NAME_LEN]; if (!ia64_platform_is("sn2")) return 0; - size = num_online_nodes() * sizeof(struct proc_dir_entry *); - proc_entries = kzalloc(size, GFP_KERNEL); - if (!proc_entries) - return -ENOMEM; + proc_entries = kmalloc(num_online_nodes() * sizeof(struct proc_dir_entry *), + GFP_KERNEL); sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); @@ -247,12 +244,14 @@ int __init prominfo_init(void) sprintf(name, "node%d", cnodeid); *entp = proc_mkdir(name, sgi_prominfo_entry); nasid = cnodeid_to_nasid(cnodeid); - p = create_proc_read_entry("fit", 0, *entp, read_fit_entry, - (void *)nasid); + p = create_proc_read_entry( + "fit", 0, *entp, read_fit_entry, + (void *)nasid); if (p) p->owner = THIS_MODULE; - p = create_proc_read_entry("version", 0, *entp, - read_version_entry, (void *)nasid); + p = create_proc_read_entry( + "version", 0, *entp, read_version_entry, + (void *)nasid); if (p) p->owner = THIS_MODULE; entp++; @@ -264,7 +263,7 @@ int __init prominfo_init(void) void __exit prominfo_exit(void) { struct proc_dir_entry **entp; - unsigned int cnodeid; + unsigned cnodeid; char name[NODE_NAME_LEN]; entp = proc_entries; diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c index 24eefb2fc55f..f153a4c35c70 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -46,14 +46,8 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats); static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); -extern unsigned long -sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, - volatile unsigned long *, unsigned long, - volatile unsigned long *, unsigned long); -void -sn2_ptc_deadlock_recovery(short *, short, short, int, - volatile unsigned long *, unsigned long, - volatile unsigned long *, unsigned long); +void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long); /* * Note: some is the following is captured here to make degugging easier @@ -65,6 +59,16 @@ sn2_ptc_deadlock_recovery(short *, short, short, int, #define reset_max_active_on_deadlock() 1 #define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) +static inline void ptc_lock(int sh1, unsigned long *flagp) +{ + spin_lock_irqsave(PTC_LOCK(sh1), *flagp); +} + +static inline void ptc_unlock(int sh1, unsigned long flags) +{ + spin_unlock_irqrestore(PTC_LOCK(sh1), flags); +} + struct ptc_stats { unsigned long ptc_l; unsigned long change_rid; @@ -78,8 +82,6 @@ struct ptc_stats { unsigned long shub_ptc_flushes_not_my_mm; }; -#define sn2_ptctest 0 - static inline unsigned long wait_piowc(void) { volatile unsigned long *piows; @@ -198,7 +200,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, max_active = max_active_pio(shub1); itc = ia64_get_itc(); - spin_lock_irqsave(PTC_LOCK(shub1), flags); + ptc_lock(shub1, &flags); itc2 = ia64_get_itc(); __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; @@ -256,7 +258,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, ia64_srlz_d(); } - spin_unlock_irqrestore(PTC_LOCK(shub1), flags); + ptc_unlock(shub1, flags); preempt_enable(); } @@ -268,12 +270,11 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, * TLB flush transaction. The recovery sequence is somewhat tricky & is * coded in assembly language. */ - -void -sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, - volatile unsigned long *ptc0, unsigned long data0, - volatile unsigned long *ptc1, unsigned long data1) +void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0, + volatile unsigned long *ptc1, unsigned long data1) { + extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); short nasid, i; unsigned long *piows, zeroval, n; diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/trunk/arch/ia64/sn/kernel/sn2/sn_proc_fs.c index c686d9c12f7b..a06719d752a0 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_proc_fs.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_proc_fs.c @@ -6,11 +6,11 @@ * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. */ #include +#include #ifdef CONFIG_PROC_FS #include #include -#include #include static int partition_id_show(struct seq_file *s, void *p) @@ -90,10 +90,10 @@ static int coherence_id_open(struct inode *inode, struct file *file) return single_open(file, coherence_id_show, NULL); } -static struct proc_dir_entry -*sn_procfs_create_entry(const char *name, struct proc_dir_entry *parent, - int (*openfunc)(struct inode *, struct file *), - int (*releasefunc)(struct inode *, struct file *)) +static struct proc_dir_entry *sn_procfs_create_entry( + const char *name, struct proc_dir_entry *parent, + int (*openfunc)(struct inode *, struct file *), + int (*releasefunc)(struct inode *, struct file *)) { struct proc_dir_entry *e = create_proc_entry(name, 0444, parent); @@ -126,24 +126,24 @@ void register_sn_procfs(void) return; sn_procfs_create_entry("partition_id", sgi_proc_dir, - partition_id_open, single_release); + partition_id_open, single_release); sn_procfs_create_entry("system_serial_number", sgi_proc_dir, - system_serial_number_open, single_release); + system_serial_number_open, single_release); sn_procfs_create_entry("licenseID", sgi_proc_dir, - licenseID_open, single_release); + licenseID_open, single_release); e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, - sn_force_interrupt_open, single_release); + sn_force_interrupt_open, single_release); if (e) e->proc_fops->write = sn_force_interrupt_write_proc; sn_procfs_create_entry("coherence_id", sgi_proc_dir, - coherence_id_open, single_release); + coherence_id_open, single_release); sn_procfs_create_entry("sn_topology", sgi_proc_dir, - sn_topology_open, sn_topology_release); + sn_topology_open, sn_topology_release); } #endif /* CONFIG_PROC_FS */ diff --git a/trunk/arch/ia64/sn/kernel/sn2/timer.c b/trunk/arch/ia64/sn/kernel/sn2/timer.c index 56a88b6df4b4..deb9baf4d473 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/timer.c +++ b/trunk/arch/ia64/sn/kernel/sn2/timer.c @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -29,27 +28,9 @@ static struct time_interpolator sn2_interpolator = { .source = TIME_SOURCE_MMIO64 }; -/* - * sn udelay uses the RTC instead of the ITC because the ITC is not - * synchronized across all CPUs, and the thread may migrate to another CPU - * if preemption is enabled. - */ -static void -ia64_sn_udelay (unsigned long usecs) -{ - unsigned long start = rtc_time(); - unsigned long end = start + - usecs * sn_rtc_cycles_per_second / 1000000; - - while (time_before((unsigned long)rtc_time(), end)) - cpu_relax(); -} - void __init sn_timer_init(void) { sn2_interpolator.frequency = sn_rtc_cycles_per_second; sn2_interpolator.addr = RTC_COUNTER_ADDR; register_time_interpolator(&sn2_interpolator); - - ia64_udelay = &ia64_sn_udelay; } diff --git a/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c index fa7f69945917..adf5db2e2afe 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c +++ b/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c @@ -1,7 +1,7 @@ /* * * - * Copyright (c) 2005, 2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -22,6 +22,11 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c index 8a56f8b5ffa2..d263d3e8fbb9 100644 --- a/trunk/arch/ia64/sn/kernel/tiocx.c +++ b/trunk/arch/ia64/sn/kernel/tiocx.c @@ -284,10 +284,12 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq, if ((nasid & 1) == 0) return NULL; - sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL); + sn_irq_info = kmalloc(sn_irq_size, GFP_KERNEL); if (sn_irq_info == NULL) return NULL; + memset(sn_irq_info, 0x0, sn_irq_size); + status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq, req_nasid, slice); if (status) { diff --git a/trunk/arch/ia64/sn/kernel/xpc_channel.c b/trunk/arch/ia64/sn/kernel/xpc_channel.c index cdf6856ce089..36e5437a0fb6 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_channel.c +++ b/trunk/arch/ia64/sn/kernel/xpc_channel.c @@ -738,9 +738,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) /* make sure all activity has settled down first */ - if (atomic_read(&ch->references) > 0 || - ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && - !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) { + if (atomic_read(&ch->references) > 0) { return; } DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); @@ -777,7 +775,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) /* both sides are disconnected now */ - if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) { + if (ch->flags & XPC_C_CONNECTCALLOUT) { spin_unlock_irqrestore(&ch->lock, *irq_flags); xpc_disconnect_callout(ch, xpcDisconnected); spin_lock_irqsave(&ch->lock, *irq_flags); @@ -1302,7 +1300,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) "delivered=%d, partid=%d, channel=%d\n", nmsgs_sent, ch->partid, ch->number); - if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) { + if (ch->flags & XPC_C_CONNECTCALLOUT) { xpc_activate_kthreads(ch, nmsgs_sent); } } diff --git a/trunk/arch/ia64/sn/kernel/xpc_main.c b/trunk/arch/ia64/sn/kernel/xpc_main.c index 8cbf16432570..9cd460dfe27e 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_main.c +++ b/trunk/arch/ia64/sn/kernel/xpc_main.c @@ -750,16 +750,12 @@ xpc_daemonize_kthread(void *args) /* let registerer know that connection has been established */ spin_lock_irqsave(&ch->lock, irq_flags); - if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) { - ch->flags |= XPC_C_CONNECTEDCALLOUT; + if (!(ch->flags & XPC_C_CONNECTCALLOUT)) { + ch->flags |= XPC_C_CONNECTCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); xpc_connected_callout(ch); - spin_lock_irqsave(&ch->lock, irq_flags); - ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE; - spin_unlock_irqrestore(&ch->lock, irq_flags); - /* * It is possible that while the callout was being * made that the remote partition sent some messages. @@ -781,17 +777,15 @@ xpc_daemonize_kthread(void *args) if (atomic_dec_return(&ch->kthreads_assigned) == 0) { spin_lock_irqsave(&ch->lock, irq_flags); - if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && - !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { - ch->flags |= XPC_C_DISCONNECTINGCALLOUT; + if ((ch->flags & XPC_C_CONNECTCALLOUT) && + !(ch->flags & XPC_C_DISCONNECTCALLOUT)) { + ch->flags |= XPC_C_DISCONNECTCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); xpc_disconnect_callout(ch, xpcDisconnecting); - - spin_lock_irqsave(&ch->lock, irq_flags); - ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE; + } else { + spin_unlock_irqrestore(&ch->lock, irq_flags); } - spin_unlock_irqrestore(&ch->lock, irq_flags); if (atomic_dec_return(&part->nchannels_engaged) == 0) { xpc_mark_partition_disengaged(part); xpc_IPI_send_disengage(part); diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index b4b84c269210..5a36292388eb 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -335,10 +335,10 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, - pci_domain_nr(bus), bus->number, - 0, /* io */ - 0, /* read */ - port, size, __pa(val)); + pci_domain_nr(bus), bus->number, + 0, /* io */ + 0, /* read */ + port, size, __pa(val)); if (isrv.status == 0) return size; @@ -381,10 +381,10 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, - pci_domain_nr(bus), bus->number, - 0, /* io */ - 1, /* write */ - port, size, __pa(&val)); + pci_domain_nr(bus), bus->number, + 0, /* io */ + 1, /* write */ + port, size, __pa(&val)); if (isrv.status == 0) return size; diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 1f0253bfe0a0..aa3fa5152a32 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. */ #include @@ -12,7 +12,7 @@ #include #include -int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */ +int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ /* * mark_ate: Mark the ate as either free or inuse. @@ -20,12 +20,14 @@ int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */ static void mark_ate(struct ate_resource *ate_resource, int start, int number, u64 value) { + u64 *ate = ate_resource->ate; int index; int length = 0; for (index = start; length < number; index++, length++) ate[index] = value; + } /* @@ -35,6 +37,7 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number, static int find_free_ate(struct ate_resource *ate_resource, int start, int count) { + u64 *ate = ate_resource->ate; int index; int start_free; @@ -67,10 +70,12 @@ static int find_free_ate(struct ate_resource *ate_resource, int start, static inline void free_ate_resource(struct ate_resource *ate_resource, int start) { + mark_ate(ate_resource, start, ate_resource->ate[start], 0); if ((ate_resource->lowest_free_index > start) || (ate_resource->lowest_free_index < 0)) ate_resource->lowest_free_index = start; + } /* @@ -79,6 +84,7 @@ static inline void free_ate_resource(struct ate_resource *ate_resource, static inline int alloc_ate_resource(struct ate_resource *ate_resource, int ate_needed) { + int start_index; /* @@ -112,12 +118,19 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, */ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) { - int status; - unsigned long flags; + int status = 0; + u64 flag; - spin_lock_irqsave(&pcibus_info->pbi_lock, flags); + flag = pcibr_lock(pcibus_info); status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); - spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); + + if (status < 0) { + /* Failed to allocate */ + pcibr_unlock(pcibus_info, flag); + return -1; + } + + pcibr_unlock(pcibus_info, flag); return status; } @@ -169,7 +182,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V)); } - spin_lock_irqsave(&pcibus_info->pbi_lock, flags); + flags = pcibr_lock(pcibus_info); free_ate_resource(&pcibus_info->pbi_int_ate_resource, index); - spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); + pcibr_unlock(pcibus_info, flags); } diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 9f86bb6519aa..54ce5b7ceed2 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -137,12 +137,14 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, pci_addr |= PCI64_ATTR_VIRTUAL; return pci_addr; + } static dma_addr_t pcibr_dmatrans_direct32(struct pcidev_info * info, u64 paddr, size_t req_size, u64 flags) { + struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; @@ -169,6 +171,7 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, } return PCI32_DIRECT_BASE | offset; + } /* @@ -215,8 +218,9 @@ void sn_dma_flush(u64 addr) u64 flags; u64 itte; struct hubdev_info *hubinfo; - struct sn_flush_device_kernel *p; - struct sn_flush_device_common *common; + volatile struct sn_flush_device_kernel *p; + volatile struct sn_flush_device_common *common; + struct sn_flush_nasid_entry *flush_nasid_list; if (!sn_ioif_inited) @@ -306,7 +310,8 @@ void sn_dma_flush(u64 addr) (common->sfdl_slot - 1)); } } else { - spin_lock_irqsave(&p->sfdl_flush_lock, flags); + spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock, + flags); *common->sfdl_flush_addr = 0; /* force an interrupt. */ @@ -317,7 +322,8 @@ void sn_dma_flush(u64 addr) cpu_relax(); /* okay, everything is synched up. */ - spin_unlock_irqrestore(&p->sfdl_flush_lock, flags); + spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, + flags); } return; } diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 98f716bd92f0..2fac27049bf6 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -163,12 +163,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* Setup the PMU ATE map */ soft->pbi_int_ate_resource.lowest_free_index = 0; soft->pbi_int_ate_resource.ate = - kzalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); - - if (!soft->pbi_int_ate_resource.ate) { - kfree(soft); - return NULL; - } + kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); + memset(soft->pbi_int_ate_resource.ate, 0, + (soft->pbi_int_ate_size * sizeof(u64))); if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { /* TIO PCI Bridge: find nearest node with CPUs */ diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 8849439e88dd..96b919828053 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -21,10 +21,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config TIME_LOW_RES - bool - default y - config ARCH_MAY_HAVE_PC_FDC bool depends on Q40 || (BROKEN && SUN3X) diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index e50858dbc237..e2a6e8648960 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -29,10 +29,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config TIME_LOW_RES - bool - default y - source "init/Kconfig" menu "Processor type and features" diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 38c0f3360d51..6a57407df1bc 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -94,6 +94,7 @@ endif # machines may also. Since BFD is incredibly buggy with respect to # crossformat linking we rely on the elf2ecoff tool for format conversion. # +cflags-y += -I $(TOPDIR)/include/asm/gcc cflags-y += -G 0 -mno-abicalls -fno-pic -pipe LDFLAGS_vmlinux += -G 0 -static -n -nostdlib MODFLAGS += -mlong-calls diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index 092679c2dca9..5232fc752935 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -273,19 +272,46 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) static struct mips_frame_info { void *func; - unsigned long func_size; - int frame_size; + int omit_fp; /* compiled without fno-omit-frame-pointer */ + int frame_offset; int pc_offset; -} *schedule_frame, mfinfo[64]; -static int mfinfo_num; +} schedule_frame, mfinfo[] = { + { schedule, 0 }, /* must be first */ + /* arch/mips/kernel/semaphore.c */ + { __down, 1 }, + { __down_interruptible, 1 }, + /* kernel/sched.c */ +#ifdef CONFIG_PREEMPT + { preempt_schedule, 0 }, +#endif + { wait_for_completion, 0 }, + { interruptible_sleep_on, 0 }, + { interruptible_sleep_on_timeout, 0 }, + { sleep_on, 0 }, + { sleep_on_timeout, 0 }, + { yield, 0 }, + { io_schedule, 0 }, + { io_schedule_timeout, 0 }, +#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) + { __preempt_spin_lock, 0 }, + { __preempt_write_lock, 0 }, +#endif + /* kernel/timer.c */ + { schedule_timeout, 1 }, +/* { nanosleep_restart, 1 }, */ + /* lib/rwsem-spinlock.c */ + { __down_read, 1 }, + { __down_write, 1 }, +}; +static int mips_frame_info_initialized; static int __init get_frame_info(struct mips_frame_info *info) { int i; void *func = info->func; union mips_instruction *ip = (union mips_instruction *)func; info->pc_offset = -1; - info->frame_size = 0; + info->frame_offset = info->omit_fp ? 0 : -1; for (i = 0; i < 128; i++, ip++) { /* if jal, jalr, jr, stop. */ if (ip->j_format.opcode == jal_op || @@ -294,23 +320,6 @@ static int __init get_frame_info(struct mips_frame_info *info) ip->r_format.func == jr_op))) break; - if (info->func_size && i >= info->func_size / 4) - break; - if ( -#ifdef CONFIG_32BIT - ip->i_format.opcode == addiu_op && -#endif -#ifdef CONFIG_64BIT - ip->i_format.opcode == daddiu_op && -#endif - ip->i_format.rs == 29 && - ip->i_format.rt == 29) { - /* addiu/daddiu sp,sp,-imm */ - if (info->frame_size) - continue; - info->frame_size = - ip->i_format.simmediate; - } - if ( #ifdef CONFIG_32BIT ip->i_format.opcode == sw_op && @@ -318,20 +327,31 @@ static int __init get_frame_info(struct mips_frame_info *info) #ifdef CONFIG_64BIT ip->i_format.opcode == sd_op && #endif - ip->i_format.rs == 29 && - ip->i_format.rt == 31) { + ip->i_format.rs == 29) + { /* sw / sd $ra, offset($sp) */ - if (info->pc_offset != -1) - continue; - info->pc_offset = - ip->i_format.simmediate / sizeof(long); + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + continue; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sw / sd $s8, offset($sp) */ + if (ip->i_format.rt == 30) { +//#if 0 /* gcc 3.4 does aggressive optimization... */ + if (info->frame_offset != -1) + continue; +//#endif + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } } } - if (info->pc_offset == -1 || info->frame_size == 0) { - if (func == schedule) - printk("Can't analyze prologue code at %p\n", func); + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); info->pc_offset = -1; - info->frame_size = 0; + info->frame_offset = -1; + return -1; } return 0; @@ -339,36 +359,25 @@ static int __init get_frame_info(struct mips_frame_info *info) static int __init frame_info_init(void) { - int i; -#ifdef CONFIG_KALLSYMS - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; - unsigned long start, size, ofs; - extern char __sched_text_start[], __sched_text_end[]; - extern char __lock_text_start[], __lock_text_end[]; - - start = (unsigned long)__sched_text_start; - for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { - if (start == (unsigned long)schedule) - schedule_frame = &mfinfo[i]; - if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) - break; - mfinfo[i].func = (void *)(start + ofs); - mfinfo[i].func_size = size; - start += size - ofs; - if (start >= (unsigned long)__lock_text_end) - break; - if (start == (unsigned long)__sched_text_end) - start = (unsigned long)__lock_text_start; - } -#else - mfinfo[0].func = schedule; - schedule_frame = &mfinfo[0]; -#endif - for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) - get_frame_info(&mfinfo[i]); - - mfinfo_num = i; + int i, found; + for (i = 0; i < ARRAY_SIZE(mfinfo); i++) + if (get_frame_info(&mfinfo[i])) + return -1; + schedule_frame = mfinfo[0]; + /* bubble sort */ + do { + struct mips_frame_info tmp; + found = 0; + for (i = 1; i < ARRAY_SIZE(mfinfo); i++) { + if (mfinfo[i-1].func > mfinfo[i].func) { + tmp = mfinfo[i]; + mfinfo[i] = mfinfo[i-1]; + mfinfo[i-1] = tmp; + found = 1; + } + } + } while (found); + mips_frame_info_initialized = 1; return 0; } @@ -385,52 +394,47 @@ unsigned long thread_saved_pc(struct task_struct *tsk) if (t->reg31 == (unsigned long) ret_from_fork) return t->reg31; - if (!schedule_frame || schedule_frame->pc_offset < 0) + if (schedule_frame.pc_offset < 0) return 0; - return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; + return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; } /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { unsigned long stack_page; - unsigned long pc; -#ifdef CONFIG_KALLSYMS - unsigned long frame; -#endif + unsigned long frame, pc; if (!p || p == current || p->state == TASK_RUNNING) return 0; stack_page = (unsigned long)task_stack_page(p); - if (!stack_page || !mfinfo_num) + if (!stack_page || !mips_frame_info_initialized) return 0; pc = thread_saved_pc(p); -#ifdef CONFIG_KALLSYMS if (!in_sched_functions(pc)) return pc; - frame = p->thread.reg29 + schedule_frame->frame_size; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; do { int i; if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) return 0; - for (i = mfinfo_num - 1; i >= 0; i--) { + for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) { if (pc >= (unsigned long) mfinfo[i].func) break; } if (i < 0) break; - pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; - if (!mfinfo[i].frame_size) + if (mfinfo[i].omit_fp) break; - frame += mfinfo[i].frame_size; + pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; + frame = ((unsigned long *)frame)[mfinfo[i].frame_offset]; } while (in_sched_functions(pc)); -#endif return pc; } diff --git a/trunk/arch/mips/kernel/signal-common.h b/trunk/arch/mips/kernel/signal-common.h index 36bfc2588aa3..0fbc492d24b4 100644 --- a/trunk/arch/mips/kernel/signal-common.h +++ b/trunk/arch/mips/kernel/signal-common.h @@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) sp = current->sas_ss_sp + current->sas_ss_size; - return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); + return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); } static inline int install_sigtramp(unsigned int __user *tramp, diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index 8a8b8dd90417..da3271e1fdac 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -537,7 +537,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) goto badframe; - st.ss_sp = (void *)(long) sp; + st.ss_size = (long) sp; if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index 5a3776096f07..384fc4a639a4 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -108,7 +108,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) goto badframe; - st.ss_sp = (void *)(long) sp; + st.ss_size = (long) sp; if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) diff --git a/trunk/arch/mips/kernel/smp_mt.c b/trunk/arch/mips/kernel/smp_mt.c index c930364830d0..794a1c3de2a4 100644 --- a/trunk/arch/mips/kernel/smp_mt.c +++ b/trunk/arch/mips/kernel/smp_mt.c @@ -68,8 +68,6 @@ void __init sanitize_tlb_entries(void) set_c0_mvpcontrol(MVPCONTROL_VPC); - back_to_back_c0_hazard(); - /* Disable TLB sharing */ clear_c0_mvpcontrol(MVPCONTROL_STLB); @@ -104,6 +102,35 @@ void __init sanitize_tlb_entries(void) clear_c0_mvpcontrol(MVPCONTROL_VPC); } +#if 0 +/* + * Use c0_MVPConf0 to find out how many CPUs are available, setting up + * phys_cpu_present_map and the logical/physical mappings. + */ +void __init prom_build_cpu_map(void) +{ + int i, num, ncpus; + + cpus_clear(phys_cpu_present_map); + + /* assume we boot on cpu 0.... */ + cpu_set(0, phys_cpu_present_map); + __cpu_number_map[0] = 0; + __cpu_logical_map[0] = 0; + + if (cpu_has_mipsmt) { + ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1; + for (i=1, num=0; i< NR_CPUS && istart; unsigned long end = fir_args->end; + unsigned long addr, aend; if (!cpu_has_ic_fills_f_dc) { if (end - start > dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; - protected_blast_dcache_range(start, end); + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } } if (!cpu_icache_snoops_remote_store) { - if (end - start > scache_size) + if (end - start > scache_size) { r4k_blast_scache(); - else - protected_blast_scache_range(start, end); + } else { + addr = start & ~(sc_lsize - 1); + aend = (end - 1) & ~(sc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_SD */ + protected_writeback_scache_line(addr); + if (addr == aend) + break; + addr += sc_lsize; + } + } } } if (end - start > icache_size) r4k_blast_icache(); - else - protected_blast_icache_range(start, end); + else { + addr = start & ~(ic_lsize - 1); + aend = (end - 1) & ~(ic_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += ic_lsize; + } + } } static void r4k_flush_icache_range(unsigned long start, unsigned long end) @@ -587,14 +619,27 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma, static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) { + unsigned long end, a; + /* Catch bad driver code */ BUG_ON(size == 0); if (cpu_has_subset_pcaches) { - if (size >= scache_size) + unsigned long sc_lsize = cpu_scache_line_size(); + + if (size >= scache_size) { r4k_blast_scache(); - else - blast_scache_range(addr, addr + size); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } return; } @@ -606,8 +651,17 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) if (size >= dcache_size) { r4k_blast_dcache(); } else { + unsigned long dc_lsize = cpu_dcache_line_size(); + R4600_HIT_CACHEOP_WAR_IMPL; - blast_dcache_range(addr, addr + size); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } } bc_wback_inv(addr, size); @@ -615,22 +669,44 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) { + unsigned long end, a; + /* Catch bad driver code */ BUG_ON(size == 0); if (cpu_has_subset_pcaches) { - if (size >= scache_size) + unsigned long sc_lsize = cpu_scache_line_size(); + + if (size >= scache_size) { r4k_blast_scache(); - else - blast_scache_range(addr, addr + size); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } return; } if (size >= dcache_size) { r4k_blast_dcache(); } else { + unsigned long dc_lsize = cpu_dcache_line_size(); + R4600_HIT_CACHEOP_WAR_IMPL; - blast_dcache_range(addr, addr + size); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } } bc_inv(addr, size); diff --git a/trunk/arch/mips/mm/c-tx39.c b/trunk/arch/mips/mm/c-tx39.c index 7c572bea4a98..0a97a9434eba 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -44,6 +44,8 @@ __asm__ __volatile__( \ /* TX39H-style cache flush routines. */ static void tx39h_flush_icache_all(void) { + unsigned long start = KSEG0; + unsigned long end = (start + icache_size); unsigned long flags, config; /* disable icache (set ICE#) */ @@ -51,18 +53,33 @@ static void tx39h_flush_icache_all(void) config = read_c0_conf(); write_c0_conf(config & ~TX39_CONF_ICE); TX39_STOP_STREAMING(); - blast_icache16(); + + /* invalidate icache */ + while (start < end) { + cache16_unroll32(start, Index_Invalidate_I); + start += 0x200; + } + write_c0_conf(config); local_irq_restore(flags); } static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) { + unsigned long end, a; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + /* Catch bad driver code */ BUG_ON(size == 0); iob(); - blast_inv_dcache_range(addr, addr + size); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + invalidate_dcache_line(a); /* Hit_Invalidate_D */ + if (a == end) break; + a += dc_lsize; + } } @@ -224,21 +241,42 @@ static void tx39_flush_data_cache_page(unsigned long addr) static void tx39_flush_icache_range(unsigned long start, unsigned long end) { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + if (end - start > dcache_size) tx39_blast_dcache(); - else - protected_blast_dcache_range(start, end); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } if (end - start > icache_size) tx39_blast_icache(); else { unsigned long flags, config; + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); /* disable icache (set ICE#) */ local_irq_save(flags); config = read_c0_conf(); write_c0_conf(config & ~TX39_CONF_ICE); TX39_STOP_STREAMING(); - protected_blast_icache_range(start, end); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } write_c0_conf(config); local_irq_restore(flags); } @@ -273,7 +311,7 @@ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { - unsigned long end; + unsigned long end, a; if (((size | addr) & (PAGE_SIZE - 1)) == 0) { end = addr + size; @@ -284,13 +322,20 @@ static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) } else if (size > dcache_size) { tx39_blast_dcache(); } else { - blast_dcache_range(addr, addr + size); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) break; + a += dc_lsize; + } } } static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) { - unsigned long end; + unsigned long end, a; if (((size | addr) & (PAGE_SIZE - 1)) == 0) { end = addr + size; @@ -301,7 +346,14 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) } else if (size > dcache_size) { tx39_blast_dcache(); } else { - blast_inv_dcache_range(addr, addr + size); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + invalidate_dcache_line(a); /* Hit_Invalidate_D */ + if (a == end) break; + a += dc_lsize; + } } } diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index eca33cfa8a4c..7c914a4c67c3 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -29,11 +29,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config TIME_LOW_RES - bool - depends on SMP - default y - config GENERIC_ISA_DMA bool diff --git a/trunk/arch/s390/lib/delay.c b/trunk/arch/s390/lib/delay.c index 71f0a2fb3078..e96c35bddac7 100644 --- a/trunk/arch/s390/lib/delay.c +++ b/trunk/arch/s390/lib/delay.c @@ -30,7 +30,7 @@ void __delay(unsigned long loops) */ __asm__ __volatile__( "0: brct %0,0b" - : /* no outputs */ : "r" ((loops/2) + 1)); + : /* no outputs */ : "r" (loops/2) ); } /* diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig index e7fc3e500342..04494638b963 100644 --- a/trunk/arch/v850/Kconfig +++ b/trunk/arch/v850/Kconfig @@ -28,10 +28,6 @@ config GENERIC_IRQ_PROBE bool default y -config TIME_LOW_RES - bool - default y - # Turn off some random 386 crap that can affect device config config ISA bool diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index 93e44d0292ab..4e7dbcc425ff 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -645,7 +645,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag * b) The data can be used as cache to avoid read requests if we receive a * new write request for the same zone. */ -static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec) +static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) { int f, p, offs; @@ -653,15 +653,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec) p = 0; offs = 0; for (f = 0; f < pkt->frames; f++) { - if (bvec[f].bv_page != pkt->pages[p]) { - void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset; + if (pages[f] != pkt->pages[p]) { + void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; void *vto = page_address(pkt->pages[p]) + offs; memcpy(vto, vfrom, CD_FRAMESIZE); kunmap_atomic(vfrom, KM_USER0); - bvec[f].bv_page = pkt->pages[p]; - bvec[f].bv_offset = offs; + pages[f] = pkt->pages[p]; + offsets[f] = offs; } else { - BUG_ON(bvec[f].bv_offset != offs); + BUG_ON(offsets[f] != offs); } offs += CD_FRAMESIZE; if (offs >= PAGE_SIZE) { @@ -991,17 +991,18 @@ static int pkt_handle_queue(struct pktcdvd_device *pd) static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) { struct bio *bio; + struct page *pages[PACKET_MAX_SIZE]; + int offsets[PACKET_MAX_SIZE]; int f; int frames_write; - struct bio_vec *bvec = pkt->w_bio->bi_io_vec; for (f = 0; f < pkt->frames; f++) { - bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; - bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE; + pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; + offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; } /* - * Fill-in bvec with data from orig_bios. + * Fill-in pages[] and offsets[] with data from orig_bios. */ frames_write = 0; spin_lock(&pkt->lock); @@ -1023,11 +1024,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) } if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { - bvec[f].bv_page = src_bvl->bv_page; - bvec[f].bv_offset = src_bvl->bv_offset + src_offs; + pages[f] = src_bvl->bv_page; + offsets[f] = src_bvl->bv_offset + src_offs; } else { pkt_copy_bio_data(bio, segment, src_offs, - bvec[f].bv_page, bvec[f].bv_offset); + pages[f], offsets[f]); } src_offs += CD_FRAMESIZE; frames_write++; @@ -1041,7 +1042,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) BUG_ON(frames_write != pkt->write_size); if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { - pkt_make_local_copy(pkt, bvec); + pkt_make_local_copy(pkt, pages, offsets); pkt->cache_valid = 1; } else { pkt->cache_valid = 0; @@ -1054,9 +1055,17 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) pkt->w_bio->bi_bdev = pd->bdev; pkt->w_bio->bi_end_io = pkt_end_io_packet_write; pkt->w_bio->bi_private = pkt; - for (f = 0; f < pkt->frames; f++) - if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) - BUG(); + for (f = 0; f < pkt->frames; f++) { + if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && + (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) { + if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f])) + BUG(); + f++; + } else { + if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f])) + BUG(); + } + } VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); atomic_set(&pkt->io_wait, 1); @@ -1539,7 +1548,7 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) case 0x12: /* DVD-RAM */ return 0; default: - VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); + printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); return 1; } @@ -1885,8 +1894,8 @@ static int pkt_open_write(struct pktcdvd_device *pd) unsigned int write_speed, media_write_speed, read_speed; if ((ret = pkt_probe_settings(pd))) { - VPRINTK("pktcdvd: %s failed probe\n", pd->name); - return -EROFS; + DPRINTK("pktcdvd: %s failed probe\n", pd->name); + return -EIO; } if ((ret = pkt_set_write_settings(pd))) { @@ -2044,9 +2053,10 @@ static int pkt_open(struct inode *inode, struct file *file) goto out_dec; } } else { - ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE); - if (ret) + if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { + ret = -EIO; goto out_dec; + } /* * needed here as well, since ext2 (among others) may change * the blocksize at mount time @@ -2426,12 +2436,11 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u * The door gets locked when the device is opened, so we * have to unlock it or else the eject command fails. */ - if (pd->refcnt == 1) - pkt_lock_door(pd, 0); + pkt_lock_door(pd, 0); return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); default: - VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); + printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); return -ENOTTY; } diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index 09dc4b01232c..57539d8f9f7c 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/drivers/char/esp.c @@ -150,6 +150,17 @@ static void rs_wait_until_sent(struct tty_struct *, int); /* Standard COM flags (except for COM4, because of the 8514 problem) */ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the memcpy_fromfs blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char *tmp_buf; + static inline int serial_paranoia_check(struct esp_struct *info, char *name, const char *routine) { @@ -1256,7 +1267,7 @@ static int rs_write(struct tty_struct * tty, if (serial_paranoia_check(info, tty->name, "rs_write")) return 0; - if (!tty || !info->xmit_buf) + if (!tty || !info->xmit_buf || !tmp_buf) return 0; while (1) { @@ -2280,7 +2291,11 @@ static int esp_open(struct tty_struct *tty, struct file * filp) tty->driver_data = info; info->tty = tty; - spin_unlock_irqrestore(&info->lock, flags); + if (!tmp_buf) { + tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); + if (!tmp_buf) + return -ENOMEM; + } /* * Start up serial port @@ -2587,6 +2602,9 @@ static void __exit espserial_exit(void) free_pages((unsigned long)dma_buffer, get_order(DMA_BUFFER_SZ)); + if (tmp_buf) + free_page((unsigned long)tmp_buf); + while (free_pio_buf) { pio_buf = free_pio_buf->next; kfree(free_pio_buf); diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index ef140ebde117..66a2fee06eb9 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -956,18 +956,22 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) } } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { struct acpi_resource_extended_irq *irqp; - int i, irq; + int i; irqp = &res->data.extended_irq; - for (i = 0; i < irqp->interrupt_count; i++) { - irq = acpi_register_gsi(irqp->interrupts[i], - irqp->triggering, irqp->polarity); - if (irq < 0) - return AE_ERROR; - - hdp->hd_irq[hdp->hd_nirqs] = irq; - hdp->hd_nirqs++; + if (irqp->interrupt_count > 0) { + hdp->hd_nirqs = irqp->interrupt_count; + + for (i = 0; i < hdp->hd_nirqs; i++) { + int rc = + acpi_register_gsi(irqp->interrupts[i], + irqp->triggering, + irqp->polarity); + if (rc < 0) + return AE_ERROR; + hdp->hd_irq[i] = rc; + } } } diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index e9bba94fc898..a23816d3e9a1 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -1841,6 +1841,7 @@ static void release_dev(struct file * filp) tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); + up(&tty_sem); do_sleep = 0; if (tty_closing) { @@ -1868,7 +1869,6 @@ static void release_dev(struct file * filp) printk(KERN_WARNING "release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); - up(&tty_sem); schedule(); } @@ -1877,6 +1877,8 @@ static void release_dev(struct file * filp) * both sides, and we've completed the last operation that could * block, so it's safe to proceed with closing. */ + + down(&tty_sem); if (pty_master) { if (--o_tty->count < 0) { printk(KERN_WARNING "release_dev: bad pty slave count " @@ -1890,6 +1892,7 @@ static void release_dev(struct file * filp) tty->count, tty_name(tty, buf)); tty->count = 0; } + up(&tty_sem); /* * We've decremented tty->count, so we need to remove this file @@ -1934,8 +1937,6 @@ static void release_dev(struct file * filp) read_unlock(&tasklist_lock); } - up(&tty_sem); - /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) return; diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index 43b96e298363..2b286e865163 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -13,6 +13,11 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index c82f47a66e48..d393b504bf26 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -665,15 +665,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, struct ib_wc mad_wc; struct ib_send_wr *send_wr = &mad_send_wr->send_wr; - /* - * Directed route handling starts if the initial LID routed part of - * a request or the ending LID routed part of a response is empty. - * If we are at the start of the LID routed part, don't update the - * hop_ptr or hop_cnt. See section 14.2.2, Vol 1 IB spec. - */ - if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == - IB_LID_PERMISSIVE && - !smi_handle_dr_smp_send(smp, device->node_type, port_num)) { + if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { ret = -EINVAL; printk(KERN_ERR PFX "Invalid directed route\n"); goto out; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c index 2825615ce81c..f9b9b93dc501 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1029,6 +1029,25 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET); dev_lim->uar_scratch_entry_sz = size; + mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", + dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); + mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", + dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); + mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", + dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); + mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", + dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); + mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", + dev_lim->reserved_mrws, dev_lim->reserved_mtts); + mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", + dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); + mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", + dev_lim->max_pds, dev_lim->reserved_mgms); + mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", + dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); + + mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); + if (mthca_is_memfree(dev)) { MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); dev_lim->max_srq_sz = 1 << field; @@ -1074,25 +1093,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; } - mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", - dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); - mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", - dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); - mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", - dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); - mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", - dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); - mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", - dev_lim->reserved_mrws, dev_lim->reserved_mtts); - mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", - dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); - mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", - dev_lim->max_pds, dev_lim->reserved_mgms); - mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", - dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); - - mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); - out: mthca_free_mailbox(dev, mailbox); return err; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h index e481037288d6..2a165fd06e57 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h @@ -53,8 +53,8 @@ #define DRV_NAME "ib_mthca" #define PFX DRV_NAME ": " -#define DRV_VERSION "0.07" -#define DRV_RELDATE "February 13, 2006" +#define DRV_VERSION "0.06" +#define DRV_RELDATE "June 23, 2005" enum { MTHCA_FLAG_DDR_HIDDEN = 1 << 1, diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index 2f85a9a831b1..e0a5412b7e68 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -78,7 +78,6 @@ enum { IPOIB_FLAG_SUBINTERFACE = 4, IPOIB_MCAST_RUN = 5, IPOIB_STOP_REAPER = 6, - IPOIB_MCAST_STARTED = 7, IPOIB_MAX_BACKOFF_SECONDS = 16, diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index a2408d7ec598..ccaa0c387076 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -533,10 +533,8 @@ void ipoib_mcast_join_task(void *dev_ptr) } if (!priv->broadcast) { - struct ipoib_mcast *broadcast; - - broadcast = ipoib_mcast_alloc(dev, 1); - if (!broadcast) { + priv->broadcast = ipoib_mcast_alloc(dev, 1); + if (!priv->broadcast) { ipoib_warn(priv, "failed to allocate broadcast group\n"); mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) @@ -546,11 +544,10 @@ void ipoib_mcast_join_task(void *dev_ptr) return; } - spin_lock_irq(&priv->lock); - memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, + memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, sizeof (union ib_gid)); - priv->broadcast = broadcast; + spin_lock_irq(&priv->lock); __ipoib_mcast_add(dev, priv->broadcast); spin_unlock_irq(&priv->lock); } @@ -604,10 +601,6 @@ int ipoib_mcast_start_thread(struct net_device *dev) queue_work(ipoib_workqueue, &priv->mcast_task); mutex_unlock(&mcast_mutex); - spin_lock_irq(&priv->lock); - set_bit(IPOIB_MCAST_STARTED, &priv->flags); - spin_unlock_irq(&priv->lock); - return 0; } @@ -618,10 +611,6 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) ipoib_dbg_mcast(priv, "stopping multicast thread\n"); - spin_lock_irq(&priv->lock); - clear_bit(IPOIB_MCAST_STARTED, &priv->flags); - spin_unlock_irq(&priv->lock); - mutex_lock(&mcast_mutex); clear_bit(IPOIB_MCAST_RUN, &priv->flags); cancel_delayed_work(&priv->mcast_task); @@ -704,14 +693,6 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, */ spin_lock(&priv->lock); - if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || - !priv->broadcast || - !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { - ++priv->stats.tx_dropped; - dev_kfree_skb_any(skb); - goto unlock; - } - mcast = __ipoib_mcast_find(dev, mgid); if (!mcast) { /* Let's create a new send only group now */ @@ -773,7 +754,6 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); } -unlock: spin_unlock(&priv->lock); } diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index 393633681f49..f190a99604f0 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -2359,8 +2359,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) /* use queue instead of direct, if online and */ /* data is in queue or buffer is full */ - if (info->online && ((tty_buffer_request_room(tty, l) < l) || - !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { + if ((info->online && tty_buffer_request_room(tty, l) < l) || + (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { skb = alloc_skb(l, GFP_ATOMIC); if (!skb) { spin_unlock_irqrestore(&info->readlock, flags); diff --git a/trunk/drivers/video/neofb.c b/trunk/drivers/video/neofb.c index b85e2b180a44..747602aa5615 100644 --- a/trunk/drivers/video/neofb.c +++ b/trunk/drivers/video/neofb.c @@ -1334,12 +1334,6 @@ static int neofb_blank(int blank_mode, struct fb_info *info) struct neofb_par *par = info->par; int seqflags, lcdflags, dpmsflags, reg; - /* - * Reload the value stored in the register, might have been changed via - * FN keystroke - */ - par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; - switch (blank_mode) { case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ @@ -1372,7 +1366,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ - dpmsflags = 0x00; /* no hsync/vsync suppression */ + dpmsflags = 0; /* no hsync/vsync suppression */ break; case FB_BLANK_UNBLANK: /* unblank */ seqflags = 0; /* Enable sequencer */ diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 675bd2568297..d17c97d07c80 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -1442,15 +1442,13 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, &bytes_read, &smb_read_data, &buf_type); pSMBr = (struct smb_com_read_rsp *)smb_read_data; + if (copy_to_user(current_offset, + smb_read_data + 4 /* RFC1001 hdr */ + + le16_to_cpu(pSMBr->DataOffset), + bytes_read)) { + rc = -EFAULT; + } if (smb_read_data) { - if (copy_to_user(current_offset, - smb_read_data + - 4 /* RFC1001 length field */ + - le16_to_cpu(pSMBr->DataOffset), - bytes_read)) { - rc = -EFAULT; - } - if(buf_type == CIFS_SMALL_BUFFER) cifs_small_buf_release(smb_read_data); else if(buf_type == CIFS_LARGE_BUFFER) diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 0e1c95074d42..055378d2513e 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1403,7 +1403,7 @@ static void zap_threads (struct mm_struct *mm) do_each_thread(g,p) { if (mm == p->mm && p != tsk && p->ptrace && p->parent->mm == mm) { - __ptrace_detach(p, 0); + __ptrace_unlink(p); } } while_each_thread(g,p); write_unlock_irq(&tasklist_lock); diff --git a/trunk/fs/jbd/checkpoint.c b/trunk/fs/jbd/checkpoint.c index 543ed543d1e5..e6265a0b56b8 100644 --- a/trunk/fs/jbd/checkpoint.c +++ b/trunk/fs/jbd/checkpoint.c @@ -24,29 +24,75 @@ #include /* - * Unlink a buffer from a transaction. + * Unlink a buffer from a transaction checkpoint list. * * Called with j_list_lock held. */ -static inline void __buffer_unlink(struct journal_head *jh) +static void __buffer_unlink_first(struct journal_head *jh) { transaction_t *transaction; transaction = jh->b_cp_transaction; - jh->b_cp_transaction = NULL; jh->b_cpnext->b_cpprev = jh->b_cpprev; jh->b_cpprev->b_cpnext = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) + if (transaction->t_checkpoint_list == jh) { transaction->t_checkpoint_list = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) - transaction->t_checkpoint_list = NULL; + if (transaction->t_checkpoint_list == jh) + transaction->t_checkpoint_list = NULL; + } +} + +/* + * Unlink a buffer from a transaction checkpoint(io) list. + * + * Called with j_list_lock held. + */ + +static inline void __buffer_unlink(struct journal_head *jh) +{ + transaction_t *transaction; + + transaction = jh->b_cp_transaction; + + __buffer_unlink_first(jh); + if (transaction->t_checkpoint_io_list == jh) { + transaction->t_checkpoint_io_list = jh->b_cpnext; + if (transaction->t_checkpoint_io_list == jh) + transaction->t_checkpoint_io_list = NULL; + } +} + +/* + * Move a buffer from the checkpoint list to the checkpoint io list + * + * Called with j_list_lock held + */ + +static inline void __buffer_relink_io(struct journal_head *jh) +{ + transaction_t *transaction; + + transaction = jh->b_cp_transaction; + __buffer_unlink_first(jh); + + if (!transaction->t_checkpoint_io_list) { + jh->b_cpnext = jh->b_cpprev = jh; + } else { + jh->b_cpnext = transaction->t_checkpoint_io_list; + jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; + jh->b_cpprev->b_cpnext = jh; + jh->b_cpnext->b_cpprev = jh; + } + transaction->t_checkpoint_io_list = jh; } /* * Try to release a checkpointed buffer from its transaction. - * Returns 1 if we released it. + * Returns 1 if we released it and 2 if we also released the + * whole transaction. + * * Requires j_list_lock * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it */ @@ -57,12 +103,11 @@ static int __try_to_free_cp_buf(struct journal_head *jh) if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) { JBUFFER_TRACE(jh, "remove from checkpoint list"); - __journal_remove_checkpoint(jh); + ret = __journal_remove_checkpoint(jh) + 1; jbd_unlock_bh_state(bh); journal_remove_journal_head(bh); BUFFER_TRACE(bh, "release"); __brelse(bh); - ret = 1; } else { jbd_unlock_bh_state(bh); } @@ -117,83 +162,53 @@ static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh) } /* - * Clean up a transaction's checkpoint list. - * - * We wait for any pending IO to complete and make sure any clean - * buffers are removed from the transaction. - * - * Return 1 if we performed any actions which might have destroyed the - * checkpoint. (journal_remove_checkpoint() deletes the transaction when - * the last checkpoint buffer is cleansed) + * Clean up transaction's list of buffers submitted for io. + * We wait for any pending IO to complete and remove any clean + * buffers. Note that we take the buffers in the opposite ordering + * from the one in which they were submitted for IO. * * Called with j_list_lock held. */ -static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) + +static void __wait_cp_io(journal_t *journal, transaction_t *transaction) { - struct journal_head *jh, *next_jh, *last_jh; + struct journal_head *jh; struct buffer_head *bh; - int ret = 0; - - assert_spin_locked(&journal->j_list_lock); - jh = transaction->t_checkpoint_list; - if (!jh) - return 0; - - last_jh = jh->b_cpprev; - next_jh = jh; - do { - jh = next_jh; + tid_t this_tid; + int released = 0; + + this_tid = transaction->t_tid; +restart: + /* Didn't somebody clean up the transaction in the meanwhile */ + if (journal->j_checkpoint_transactions != transaction || + transaction->t_tid != this_tid) + return; + while (!released && transaction->t_checkpoint_io_list) { + jh = transaction->t_checkpoint_io_list; bh = jh2bh(jh); + if (!jbd_trylock_bh_state(bh)) { + jbd_sync_bh(journal, bh); + spin_lock(&journal->j_list_lock); + goto restart; + } if (buffer_locked(bh)) { atomic_inc(&bh->b_count); spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); wait_on_buffer(bh); /* the journal_head may have gone by now */ BUFFER_TRACE(bh, "brelse"); __brelse(bh); - goto out_return_1; - } - - /* - * This is foul - */ - if (!jbd_trylock_bh_state(bh)) { - jbd_sync_bh(journal, bh); - goto out_return_1; + spin_lock(&journal->j_list_lock); + goto restart; } - - if (jh->b_transaction != NULL) { - transaction_t *t = jh->b_transaction; - tid_t tid = t->t_tid; - - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - log_start_commit(journal, tid); - log_wait_commit(journal, tid); - goto out_return_1; - } - /* - * AKPM: I think the buffer_jbddirty test is redundant - it - * shouldn't have NULL b_transaction? + * Now in whatever state the buffer currently is, we know that + * it has been written out and so we can drop it from the list */ - next_jh = jh->b_cpnext; - if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) { - BUFFER_TRACE(bh, "remove from checkpoint"); - __journal_remove_checkpoint(jh); - jbd_unlock_bh_state(bh); - journal_remove_journal_head(bh); - __brelse(bh); - ret = 1; - } else { - jbd_unlock_bh_state(bh); - } - } while (jh != last_jh); - - return ret; -out_return_1: - spin_lock(&journal->j_list_lock); - return 1; + released = __journal_remove_checkpoint(jh); + jbd_unlock_bh_state(bh); + } } #define NR_BATCH 64 @@ -203,9 +218,7 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) { int i; - spin_unlock(&journal->j_list_lock); ll_rw_block(SWRITE, *batch_count, bhs); - spin_lock(&journal->j_list_lock); for (i = 0; i < *batch_count; i++) { struct buffer_head *bh = bhs[i]; clear_buffer_jwrite(bh); @@ -221,19 +234,46 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) * Return 1 if something happened which requires us to abort the current * scan of the checkpoint list. * - * Called with j_list_lock held. + * Called with j_list_lock held and drops it if 1 is returned * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it */ -static int __flush_buffer(journal_t *journal, struct journal_head *jh, - struct buffer_head **bhs, int *batch_count, - int *drop_count) +static int __process_buffer(journal_t *journal, struct journal_head *jh, + struct buffer_head **bhs, int *batch_count) { struct buffer_head *bh = jh2bh(jh); int ret = 0; - if (buffer_dirty(bh) && !buffer_locked(bh) && jh->b_jlist == BJ_None) { - J_ASSERT_JH(jh, jh->b_transaction == NULL); + if (buffer_locked(bh)) { + get_bh(bh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + wait_on_buffer(bh); + /* the journal_head may have gone by now */ + BUFFER_TRACE(bh, "brelse"); + put_bh(bh); + ret = 1; + } + else if (jh->b_transaction != NULL) { + transaction_t *t = jh->b_transaction; + tid_t tid = t->t_tid; + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + log_start_commit(journal, tid); + log_wait_commit(journal, tid); + ret = 1; + } + else if (!buffer_dirty(bh)) { + J_ASSERT_JH(jh, !buffer_jbddirty(bh)); + BUFFER_TRACE(bh, "remove from checkpoint"); + __journal_remove_checkpoint(jh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + journal_remove_journal_head(bh); + put_bh(bh); + ret = 1; + } + else { /* * Important: we are about to write the buffer, and * possibly block, while still holding the journal lock. @@ -246,45 +286,30 @@ static int __flush_buffer(journal_t *journal, struct journal_head *jh, J_ASSERT_BH(bh, !buffer_jwrite(bh)); set_buffer_jwrite(bh); bhs[*batch_count] = bh; + __buffer_relink_io(jh); jbd_unlock_bh_state(bh); (*batch_count)++; if (*batch_count == NR_BATCH) { + spin_unlock(&journal->j_list_lock); __flush_batch(journal, bhs, batch_count); ret = 1; } - } else { - int last_buffer = 0; - if (jh->b_cpnext == jh) { - /* We may be about to drop the transaction. Tell the - * caller that the lists have changed. - */ - last_buffer = 1; - } - if (__try_to_free_cp_buf(jh)) { - (*drop_count)++; - ret = last_buffer; - } } return ret; } /* - * Perform an actual checkpoint. We don't write out only enough to - * satisfy the current blocked requests: rather we submit a reasonably - * sized chunk of the outstanding data to disk at once for - * efficiency. __log_wait_for_space() will retry if we didn't free enough. + * Perform an actual checkpoint. We take the first transaction on the + * list of transactions to be checkpointed and send all its buffers + * to disk. We submit larger chunks of data at once. * - * However, we _do_ take into account the amount requested so that once - * the IO has been queued, we can return as soon as enough of it has - * completed to disk. - * * The journal should be locked before calling this function. */ int log_do_checkpoint(journal_t *journal) { + transaction_t *transaction; + tid_t this_tid; int result; - int batch_count = 0; - struct buffer_head *bhs[NR_BATCH]; jbd_debug(1, "Start checkpoint\n"); @@ -299,79 +324,70 @@ int log_do_checkpoint(journal_t *journal) return result; /* - * OK, we need to start writing disk blocks. Try to free up a - * quarter of the log in a single checkpoint if we can. + * OK, we need to start writing disk blocks. Take one transaction + * and write it. */ + spin_lock(&journal->j_list_lock); + if (!journal->j_checkpoint_transactions) + goto out; + transaction = journal->j_checkpoint_transactions; + this_tid = transaction->t_tid; +restart: /* - * AKPM: check this code. I had a feeling a while back that it - * degenerates into a busy loop at unmount time. + * If someone cleaned up this transaction while we slept, we're + * done (maybe it's a new transaction, but it fell at the same + * address). */ - spin_lock(&journal->j_list_lock); - while (journal->j_checkpoint_transactions) { - transaction_t *transaction; - struct journal_head *jh, *last_jh, *next_jh; - int drop_count = 0; - int cleanup_ret, retry = 0; - tid_t this_tid; - - transaction = journal->j_checkpoint_transactions; - this_tid = transaction->t_tid; - jh = transaction->t_checkpoint_list; - last_jh = jh->b_cpprev; - next_jh = jh; - do { + if (journal->j_checkpoint_transactions == transaction && + transaction->t_tid == this_tid) { + int batch_count = 0; + struct buffer_head *bhs[NR_BATCH]; + struct journal_head *jh; + int retry = 0; + + while (!retry && transaction->t_checkpoint_list) { struct buffer_head *bh; - jh = next_jh; - next_jh = jh->b_cpnext; + jh = transaction->t_checkpoint_list; bh = jh2bh(jh); if (!jbd_trylock_bh_state(bh)) { jbd_sync_bh(journal, bh); - spin_lock(&journal->j_list_lock); retry = 1; break; } - retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count); - if (cond_resched_lock(&journal->j_list_lock)) { + retry = __process_buffer(journal, jh, bhs, + &batch_count); + if (!retry && + lock_need_resched(&journal->j_list_lock)) { + spin_unlock(&journal->j_list_lock); retry = 1; break; } - } while (jh != last_jh && !retry); + } if (batch_count) { + if (!retry) { + spin_unlock(&journal->j_list_lock); + retry = 1; + } __flush_batch(journal, bhs, &batch_count); - retry = 1; } + if (retry) { + spin_lock(&journal->j_list_lock); + goto restart; + } /* - * If someone cleaned up this transaction while we slept, we're - * done - */ - if (journal->j_checkpoint_transactions != transaction) - break; - if (retry) - continue; - /* - * Maybe it's a new transaction, but it fell at the same - * address - */ - if (transaction->t_tid != this_tid) - continue; - /* - * We have walked the whole transaction list without - * finding anything to write to disk. We had better be - * able to make some progress or we are in trouble. + * Now we have cleaned up the first transaction's checkpoint + * list. Let's clean up the second one. */ - cleanup_ret = __cleanup_transaction(journal, transaction); - J_ASSERT(drop_count != 0 || cleanup_ret != 0); - if (journal->j_checkpoint_transactions != transaction) - break; + __wait_cp_io(journal, transaction); } +out: spin_unlock(&journal->j_list_lock); result = cleanup_journal_tail(journal); if (result < 0) return result; - return 0; } @@ -455,6 +471,53 @@ int cleanup_journal_tail(journal_t *journal) /* Checkpoint list management */ +/* + * journal_clean_one_cp_list + * + * Find all the written-back checkpoint buffers in the given list and release them. + * + * Called with the journal locked. + * Called with j_list_lock held. + * Returns number of bufers reaped (for debug) + */ + +static int journal_clean_one_cp_list(struct journal_head *jh, int *released) +{ + struct journal_head *last_jh; + struct journal_head *next_jh = jh; + int ret, freed = 0; + + *released = 0; + if (!jh) + return 0; + + last_jh = jh->b_cpprev; + do { + jh = next_jh; + next_jh = jh->b_cpnext; + /* Use trylock because of the ranking */ + if (jbd_trylock_bh_state(jh2bh(jh))) { + ret = __try_to_free_cp_buf(jh); + if (ret) { + freed++; + if (ret == 2) { + *released = 1; + return freed; + } + } + } + /* + * This function only frees up some memory if possible so we + * dont have an obligation to finish processing. Bail out if + * preemption requested: + */ + if (need_resched()) + return freed; + } while (jh != last_jh); + + return freed; +} + /* * journal_clean_checkpoint_list * @@ -462,46 +525,38 @@ int cleanup_journal_tail(journal_t *journal) * * Called with the journal locked. * Called with j_list_lock held. - * Returns number of bufers reaped (for debug) + * Returns number of buffers reaped (for debug) */ int __journal_clean_checkpoint_list(journal_t *journal) { transaction_t *transaction, *last_transaction, *next_transaction; - int ret = 0; + int ret = 0, released; transaction = journal->j_checkpoint_transactions; - if (transaction == 0) + if (!transaction) goto out; last_transaction = transaction->t_cpprev; next_transaction = transaction; do { - struct journal_head *jh; - transaction = next_transaction; next_transaction = transaction->t_cpnext; - jh = transaction->t_checkpoint_list; - if (jh) { - struct journal_head *last_jh = jh->b_cpprev; - struct journal_head *next_jh = jh; - - do { - jh = next_jh; - next_jh = jh->b_cpnext; - /* Use trylock because of the ranknig */ - if (jbd_trylock_bh_state(jh2bh(jh))) - ret += __try_to_free_cp_buf(jh); - /* - * This function only frees up some memory - * if possible so we dont have an obligation - * to finish processing. Bail out if preemption - * requested: - */ - if (need_resched()) - goto out; - } while (jh != last_jh); - } + ret += journal_clean_one_cp_list(transaction-> + t_checkpoint_list, &released); + if (need_resched()) + goto out; + if (released) + continue; + /* + * It is essential that we are as careful as in the case of + * t_checkpoint_list with removing the buffer from the list as + * we can possibly see not yet submitted buffers on io_list + */ + ret += journal_clean_one_cp_list(transaction-> + t_checkpoint_io_list, &released); + if (need_resched()) + goto out; } while (transaction != last_transaction); out: return ret; @@ -516,18 +571,22 @@ int __journal_clean_checkpoint_list(journal_t *journal) * buffer updates committed in that transaction have safely been stored * elsewhere on disk. To achieve this, all of the buffers in a * transaction need to be maintained on the transaction's checkpoint - * list until they have been rewritten, at which point this function is + * lists until they have been rewritten, at which point this function is * called to remove the buffer from the existing transaction's - * checkpoint list. + * checkpoint lists. + * + * The function returns 1 if it frees the transaction, 0 otherwise. * * This function is called with the journal locked. * This function is called with j_list_lock held. + * This function is called with jbd_lock_bh_state(jh2bh(jh)) */ -void __journal_remove_checkpoint(struct journal_head *jh) +int __journal_remove_checkpoint(struct journal_head *jh) { transaction_t *transaction; journal_t *journal; + int ret = 0; JBUFFER_TRACE(jh, "entry"); @@ -538,8 +597,10 @@ void __journal_remove_checkpoint(struct journal_head *jh) journal = transaction->t_journal; __buffer_unlink(jh); + jh->b_cp_transaction = NULL; - if (transaction->t_checkpoint_list != NULL) + if (transaction->t_checkpoint_list != NULL || + transaction->t_checkpoint_io_list != NULL) goto out; JBUFFER_TRACE(jh, "transaction has no more buffers"); @@ -565,8 +626,10 @@ void __journal_remove_checkpoint(struct journal_head *jh) /* Just in case anybody was waiting for more transactions to be checkpointed... */ wake_up(&journal->j_wait_logspace); + ret = 1; out: JBUFFER_TRACE(jh, "exit"); + return ret; } /* @@ -628,6 +691,7 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction) J_ASSERT(transaction->t_shadow_list == NULL); J_ASSERT(transaction->t_log_list == NULL); J_ASSERT(transaction->t_checkpoint_list == NULL); + J_ASSERT(transaction->t_checkpoint_io_list == NULL); J_ASSERT(transaction->t_updates == 0); J_ASSERT(journal->j_committing_transaction != transaction); J_ASSERT(journal->j_running_transaction != transaction); diff --git a/trunk/fs/jbd/commit.c b/trunk/fs/jbd/commit.c index 002ad2bbc769..29e62d98bae6 100644 --- a/trunk/fs/jbd/commit.c +++ b/trunk/fs/jbd/commit.c @@ -829,7 +829,8 @@ void journal_commit_transaction(journal_t *journal) journal->j_committing_transaction = NULL; spin_unlock(&journal->j_state_lock); - if (commit_transaction->t_checkpoint_list == NULL) { + if (commit_transaction->t_checkpoint_list == NULL && + commit_transaction->t_checkpoint_io_list == NULL) { __journal_drop_transaction(journal, commit_transaction); } else { if (journal->j_checkpoint_transactions == NULL) { diff --git a/trunk/fs/lockd/clntlock.c b/trunk/fs/lockd/clntlock.c index da6354baa0b8..3eaf6e701087 100644 --- a/trunk/fs/lockd/clntlock.c +++ b/trunk/fs/lockd/clntlock.c @@ -111,10 +111,9 @@ long nlmclnt_block(struct nlm_rqst *req, long timeout) /* * The server lockd has called us back to tell us the lock was granted */ -u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) +u32 +nlmclnt_grant(struct nlm_lock *lock) { - const struct file_lock *fl = &lock->fl; - const struct nfs_fh *fh = &lock->fh; struct nlm_wait *block; u32 res = nlm_lck_denied; @@ -123,20 +122,14 @@ u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) * Warning: must not use cookie to match it! */ list_for_each_entry(block, &nlm_blocked, b_list) { - struct file_lock *fl_blocked = block->b_lock; - - if (!nlm_compare_locks(fl_blocked, fl)) - continue; - if (!nlm_cmp_addr(&block->b_host->h_addr, addr)) - continue; - if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode) ,fh) != 0) - continue; - /* Alright, we found a lock. Set the return status - * and wake up the caller - */ - block->b_status = NLM_LCK_GRANTED; - wake_up(&block->b_wait); - res = nlm_granted; + if (nlm_compare_locks(block->b_lock, &lock->fl)) { + /* Alright, we found a lock. Set the return status + * and wake up the caller + */ + block->b_status = NLM_LCK_GRANTED; + wake_up(&block->b_wait); + res = nlm_granted; + } } return res; } diff --git a/trunk/fs/lockd/svc4proc.c b/trunk/fs/lockd/svc4proc.c index b10f913aa06a..4063095d849e 100644 --- a/trunk/fs/lockd/svc4proc.c +++ b/trunk/fs/lockd/svc4proc.c @@ -228,7 +228,7 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); - resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock); + resp->status = nlmclnt_grant(&argp->lock); dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); return rpc_success; } diff --git a/trunk/fs/lockd/svcproc.c b/trunk/fs/lockd/svcproc.c index 35681d9cf1fc..3bc437e0cf5b 100644 --- a/trunk/fs/lockd/svcproc.c +++ b/trunk/fs/lockd/svcproc.c @@ -256,7 +256,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); - resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock); + resp->status = nlmclnt_grant(&argp->lock); dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); return rpc_success; } diff --git a/trunk/include/asm-alpha/mman.h b/trunk/include/asm-alpha/mman.h index a21515c16a43..f6439532a262 100644 --- a/trunk/include/asm-alpha/mman.h +++ b/trunk/include/asm-alpha/mman.h @@ -43,8 +43,6 @@ #define MADV_SPACEAVAIL 5 /* ensure resources are available */ #define MADV_DONTNEED 6 /* don't need these pages */ #define MADV_REMOVE 7 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-arm/mman.h b/trunk/include/asm-arm/mman.h index 693ed859e632..f0bebca2ac21 100644 --- a/trunk/include/asm-arm/mman.h +++ b/trunk/include/asm-arm/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-arm26/mman.h b/trunk/include/asm-arm26/mman.h index 2096c50df888..0ed7780541fa 100644 --- a/trunk/include/asm-arm26/mman.h +++ b/trunk/include/asm-arm26/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-cris/mman.h b/trunk/include/asm-cris/mman.h index deddfb239ff5..5a382b8bf3f7 100644 --- a/trunk/include/asm-cris/mman.h +++ b/trunk/include/asm-cris/mman.h @@ -38,8 +38,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-frv/atomic.h b/trunk/include/asm-frv/atomic.h index 5d9f84bfdcad..a59f684b4f33 100644 --- a/trunk/include/asm-frv/atomic.h +++ b/trunk/include/asm-frv/atomic.h @@ -220,9 +220,9 @@ extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsig switch (sizeof(__xg_orig)) { \ case 4: \ asm volatile( \ - "swap%I0 %M0,%1" \ - : "+m"(*__xg_ptr), "=r"(__xg_orig) \ - : "1"(x) \ + "swap%I0 %2,%M0" \ + : "+m"(*__xg_ptr), "=&r"(__xg_orig) \ + : "r"(x) \ : "memory" \ ); \ break; \ diff --git a/trunk/include/asm-frv/cacheflush.h b/trunk/include/asm-frv/cacheflush.h index eaa5826bc1c8..3007deccb490 100644 --- a/trunk/include/asm-frv/cacheflush.h +++ b/trunk/include/asm-frv/cacheflush.h @@ -87,17 +87,5 @@ static inline void flush_icache_page(struct vm_area_struct *vma, struct page *pa flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE); } -/* - * permit ptrace to access another process's address space through the icache - * and the dcache - */ -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ -do { \ - memcpy((dst), (src), (len)); \ - flush_icache_user_range((vma), (page), (vaddr), (len)); \ -} while(0) - -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - memcpy((dst), (src), (len)) #endif /* _ASM_CACHEFLUSH_H */ diff --git a/trunk/include/asm-frv/io.h b/trunk/include/asm-frv/io.h index 01247cb2bc39..075369b1a34b 100644 --- a/trunk/include/asm-frv/io.h +++ b/trunk/include/asm-frv/io.h @@ -251,6 +251,7 @@ static inline void writel(uint32_t datum, volatile void __iomem *addr) #define IOMAP_WRITETHROUGH 3 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); +extern void __iounmap(void __iomem *addr, unsigned long size); static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) { diff --git a/trunk/include/asm-frv/mman.h b/trunk/include/asm-frv/mman.h index d3bca306da82..8af4a41c255e 100644 --- a/trunk/include/asm-frv/mman.h +++ b/trunk/include/asm-frv/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-frv/spr-regs.h b/trunk/include/asm-frv/spr-regs.h index c2a541ef828d..ef472f058d9c 100644 --- a/trunk/include/asm-frv/spr-regs.h +++ b/trunk/include/asm-frv/spr-regs.h @@ -98,7 +98,6 @@ #define TBR_TT_TRAP0 (0x80 << 4) #define TBR_TT_TRAP1 (0x81 << 4) #define TBR_TT_TRAP2 (0x82 << 4) -#define TBR_TT_TRAP3 (0x83 << 4) #define TBR_TT_TRAP126 (0xfe << 4) #define TBR_TT_BREAK (0xff << 4) diff --git a/trunk/include/asm-frv/system.h b/trunk/include/asm-frv/system.h index f72ff0c4dc0b..d2aea70a5f64 100644 --- a/trunk/include/asm-frv/system.h +++ b/trunk/include/asm-frv/system.h @@ -40,84 +40,8 @@ do { \ /* * interrupt flag manipulation - * - use virtual interrupt management since touching the PSR is slow - * - ICC2.Z: T if interrupts virtually disabled - * - ICC2.C: F if interrupts really disabled - * - if Z==1 upon interrupt: - * - C is set to 0 - * - interrupts are really disabled - * - entry.S returns immediately - * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts - * - if taken, the trap: - * - sets ICC2.C - * - enables interrupts */ -#define local_irq_disable() \ -do { \ - /* set Z flag, but don't change the C flag */ \ - asm volatile(" andcc gr0,gr0,gr0,icc2 \n" \ - : \ - : \ - : "memory", "icc2" \ - ); \ -} while(0) - -#define local_irq_enable() \ -do { \ - /* clear Z flag and then test the C flag */ \ - asm volatile(" oricc gr0,#1,gr0,icc2 \n" \ - " tihi icc2,gr0,#2 \n" \ - : \ - : \ - : "memory", "icc2" \ - ); \ -} while(0) - -#define local_save_flags(flags) \ -do { \ - typecheck(unsigned long, flags); \ - asm volatile("movsg ccr,%0" \ - : "=r"(flags) \ - : \ - : "memory"); \ - \ - /* shift ICC2.Z to bit 0 */ \ - flags >>= 26; \ - \ - /* make flags 1 if interrupts disabled, 0 otherwise */ \ - flags &= 1UL; \ -} while(0) - -#define irqs_disabled() \ - ({unsigned long flags; local_save_flags(flags); flags; }) - -#define local_irq_save(flags) \ -do { \ - typecheck(unsigned long, flags); \ - local_save_flags(flags); \ - local_irq_disable(); \ -} while(0) - -#define local_irq_restore(flags) \ -do { \ - typecheck(unsigned long, flags); \ - \ - /* load the Z flag by turning 1 if disabled into 0 if disabled \ - * and thus setting the Z flag but not the C flag */ \ - asm volatile(" xoricc %0,#1,gr0,icc2 \n" \ - /* then test Z=0 and C=0 */ \ - " tihi icc2,gr0,#2 \n" \ - : \ - : "r"(flags) \ - : "memory", "icc2" \ - ); \ - \ -} while(0) - -/* - * real interrupt flag manipulation - */ -#define __local_irq_disable() \ +#define local_irq_disable() \ do { \ unsigned long psr; \ asm volatile(" movsg psr,%0 \n" \ @@ -129,7 +53,7 @@ do { \ : "memory"); \ } while(0) -#define __local_irq_enable() \ +#define local_irq_enable() \ do { \ unsigned long psr; \ asm volatile(" movsg psr,%0 \n" \ @@ -140,7 +64,7 @@ do { \ : "memory"); \ } while(0) -#define __local_save_flags(flags) \ +#define local_save_flags(flags) \ do { \ typecheck(unsigned long, flags); \ asm("movsg psr,%0" \ @@ -149,7 +73,7 @@ do { \ : "memory"); \ } while(0) -#define __local_irq_save(flags) \ +#define local_irq_save(flags) \ do { \ unsigned long npsr; \ typecheck(unsigned long, flags); \ @@ -162,7 +86,7 @@ do { \ : "memory"); \ } while(0) -#define __local_irq_restore(flags) \ +#define local_irq_restore(flags) \ do { \ typecheck(unsigned long, flags); \ asm volatile(" movgs %0,psr \n" \ @@ -171,7 +95,7 @@ do { \ : "memory"); \ } while(0) -#define __irqs_disabled() \ +#define irqs_disabled() \ ((__get_PSR() & PSR_PIL) >= PSR_PIL_14) /* diff --git a/trunk/include/asm-frv/uaccess.h b/trunk/include/asm-frv/uaccess.h index a1d140438863..b6bcbe01f6ee 100644 --- a/trunk/include/asm-frv/uaccess.h +++ b/trunk/include/asm-frv/uaccess.h @@ -306,4 +306,7 @@ extern long strnlen_user(const char *src, long count); extern unsigned long search_exception_table(unsigned long addr); +#define copy_to_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len) +#define copy_from_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len) + #endif /* _ASM_UACCESS_H */ diff --git a/trunk/include/asm-frv/unistd.h b/trunk/include/asm-frv/unistd.h index 322531caa484..4d994d2e99e3 100644 --- a/trunk/include/asm-frv/unistd.h +++ b/trunk/include/asm-frv/unistd.h @@ -295,29 +295,13 @@ #define __NR_add_key 286 #define __NR_request_key 287 #define __NR_keyctl 288 -#define __NR_ioprio_set 289 -#define __NR_ioprio_get 290 -#define __NR_inotify_init 291 -#define __NR_inotify_add_watch 292 -#define __NR_inotify_rm_watch 293 -#define __NR_migrate_pages 294 -#define __NR_openat 295 -#define __NR_mkdirat 296 -#define __NR_mknodat 297 -#define __NR_fchownat 298 -#define __NR_futimesat 299 -#define __NR_newfstatat 300 -#define __NR_unlinkat 301 -#define __NR_renameat 302 -#define __NR_linkat 303 -#define __NR_symlinkat 304 -#define __NR_readlinkat 305 -#define __NR_fchmodat 306 -#define __NR_faccessat 307 -#define __NR_pselect6 308 -#define __NR_ppoll 309 +#define __NR_vperfctr_open 289 +#define __NR_vperfctr_control (__NR_perfctr_info+1) +#define __NR_vperfctr_unlink (__NR_perfctr_info+2) +#define __NR_vperfctr_iresume (__NR_perfctr_info+3) +#define __NR_vperfctr_read (__NR_perfctr_info+4) -#define NR_syscalls 310 +#define NR_syscalls 294 /* * process the return value of a syscall, consigning it to one of two possible fates diff --git a/trunk/include/asm-h8300/mman.h b/trunk/include/asm-h8300/mman.h index ac0346f7d11d..744a8fb485c2 100644 --- a/trunk/include/asm-h8300/mman.h +++ b/trunk/include/asm-h8300/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-i386/mman.h b/trunk/include/asm-i386/mman.h index ab2339a1d807..ba4941e6f643 100644 --- a/trunk/include/asm-i386/mman.h +++ b/trunk/include/asm-i386/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-i386/topology.h b/trunk/include/asm-i386/topology.h index aa958c6ee83e..af503a122b23 100644 --- a/trunk/include/asm-i386/topology.h +++ b/trunk/include/asm-i386/topology.h @@ -27,7 +27,7 @@ #ifndef _ASM_I386_TOPOLOGY_H #define _ASM_I386_TOPOLOGY_H -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP #define topology_physical_package_id(cpu) \ (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu]) #define topology_core_id(cpu) \ diff --git a/trunk/include/asm-ia64/machvec_sn2.h b/trunk/include/asm-ia64/machvec_sn2.h index 03d00faf03b5..e1b6cd63f49e 100644 --- a/trunk/include/asm-ia64/machvec_sn2.h +++ b/trunk/include/asm-ia64/machvec_sn2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2003, 2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -20,6 +20,11 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan diff --git a/trunk/include/asm-ia64/mman.h b/trunk/include/asm-ia64/mman.h index 357ebb780cc0..828beb24a20e 100644 --- a/trunk/include/asm-ia64/mman.h +++ b/trunk/include/asm-ia64/mman.h @@ -44,8 +44,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-ia64/sn/arch.h b/trunk/include/asm-ia64/sn/arch.h index 91c31be87b13..1a3831c04af6 100644 --- a/trunk/include/asm-ia64/sn/arch.h +++ b/trunk/include/asm-ia64/sn/arch.h @@ -70,7 +70,7 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); * Compact node ID to nasid mappings kept in the per-cpu data areas of each * cpu. */ -DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); +DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); #define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0])) diff --git a/trunk/include/asm-ia64/sn/bte.h b/trunk/include/asm-ia64/sn/bte.h index 5335d87ca5f8..01e5b4103235 100644 --- a/trunk/include/asm-ia64/sn/bte.h +++ b/trunk/include/asm-ia64/sn/bte.h @@ -46,7 +46,7 @@ #define BTES_PER_NODE (is_shub2() ? 4 : 2) #define MAX_BTES_PER_NODE 4 -#define BTE2OFF_CTRL 0 +#define BTE2OFF_CTRL (0) #define BTE2OFF_SRC (SH2_BT_ENG_SRC_ADDR_0 - SH2_BT_ENG_CSR_0) #define BTE2OFF_DEST (SH2_BT_ENG_DEST_ADDR_0 - SH2_BT_ENG_CSR_0) #define BTE2OFF_NOTIFY (SH2_BT_ENG_NOTIF_ADDR_0 - SH2_BT_ENG_CSR_0) @@ -75,11 +75,11 @@ : base + (BTEOFF_NOTIFY/8)) /* Define hardware modes */ -#define BTE_NOTIFY IBCT_NOTIFY +#define BTE_NOTIFY (IBCT_NOTIFY) #define BTE_NORMAL BTE_NOTIFY #define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE) /* Use a reserved bit to let the caller specify a wait for any BTE */ -#define BTE_WACQUIRE 0x4000 +#define BTE_WACQUIRE (0x4000) /* Use the BTE on the node with the destination memory */ #define BTE_USE_DEST (BTE_WACQUIRE << 1) /* Use any available BTE interface on any node for the transfer */ diff --git a/trunk/include/asm-ia64/sn/pcibr_provider.h b/trunk/include/asm-ia64/sn/pcibr_provider.h index a601d3af39b6..9334078b089a 100644 --- a/trunk/include/asm-ia64/sn/pcibr_provider.h +++ b/trunk/include/asm-ia64/sn/pcibr_provider.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved. */ #ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H #define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H @@ -115,6 +115,18 @@ struct pcibus_info { spinlock_t pbi_lock; }; +/* + * pcibus_info structure locking macros + */ +inline static unsigned long +pcibr_lock(struct pcibus_info *pcibus_info) +{ + unsigned long flag; + spin_lock_irqsave(&pcibus_info->pbi_lock, flag); + return(flag); +} +#define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag) + extern int pcibr_init_provider(void); extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *); extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); diff --git a/trunk/include/asm-ia64/sn/sn_feature_sets.h b/trunk/include/asm-ia64/sn/sn_feature_sets.h index ff33e3bd3f8e..9ca642cad338 100644 --- a/trunk/include/asm-ia64/sn/sn_feature_sets.h +++ b/trunk/include/asm-ia64/sn/sn_feature_sets.h @@ -12,6 +12,9 @@ */ +#include +#include + /* --------------------- PROM Features -----------------------------*/ extern int sn_prom_feature_available(int id); diff --git a/trunk/include/asm-ia64/sn/xpc.h b/trunk/include/asm-ia64/sn/xpc.h index df7f5f4f3cde..0c36928ffd8b 100644 --- a/trunk/include/asm-ia64/sn/xpc.h +++ b/trunk/include/asm-ia64/sn/xpc.h @@ -508,24 +508,19 @@ struct xpc_channel { #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ -#define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */ -#define XPC_C_CONNECTEDCALLOUT_MADE \ - 0x00000080 /* connected callout completed */ -#define XPC_C_CONNECTED 0x00000100 /* local channel is connected */ -#define XPC_C_CONNECTING 0x00000200 /* channel is being connected */ - -#define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */ -#define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */ -#define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */ -#define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */ - -#define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */ -#define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */ -#define XPC_C_DISCONNECTINGCALLOUT \ - 0x00010000 /* disconnecting callout initiated */ -#define XPC_C_DISCONNECTINGCALLOUT_MADE \ - 0x00020000 /* disconnecting callout completed */ -#define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */ +#define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */ +#define XPC_C_CONNECTED 0x00000080 /* local channel is connected */ +#define XPC_C_CONNECTING 0x00000100 /* channel is being connected */ + +#define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */ +#define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */ +#define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */ +#define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */ + +#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ +#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ +#define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */ +#define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */ diff --git a/trunk/include/asm-ia64/timex.h b/trunk/include/asm-ia64/timex.h index 05a6baf8a472..414aae060440 100644 --- a/trunk/include/asm-ia64/timex.h +++ b/trunk/include/asm-ia64/timex.h @@ -15,8 +15,6 @@ typedef unsigned long cycles_t; -extern void (*ia64_udelay)(unsigned long usecs); - /* * For performance reasons, we don't want to define CLOCK_TICK_TRATE as * local_cpu_data->itc_rate. Fortunately, we don't have to, either: according to George diff --git a/trunk/include/asm-m32r/mman.h b/trunk/include/asm-m32r/mman.h index 6b02fe3fcff2..12e29747bc84 100644 --- a/trunk/include/asm-m32r/mman.h +++ b/trunk/include/asm-m32r/mman.h @@ -38,8 +38,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-m68k/mman.h b/trunk/include/asm-m68k/mman.h index efd12bc4ccb7..ea262ab88b3b 100644 --- a/trunk/include/asm-m68k/mman.h +++ b/trunk/include/asm-m68k/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-mips/cpu.h b/trunk/include/asm-mips/cpu.h index 818b9a97e214..934e063e79f1 100644 --- a/trunk/include/asm-mips/cpu.h +++ b/trunk/include/asm-mips/cpu.h @@ -204,9 +204,9 @@ */ #define MIPS_CPU_ISA_I 0x00000001 #define MIPS_CPU_ISA_II 0x00000002 -#define MIPS_CPU_ISA_III 0x00000004 -#define MIPS_CPU_ISA_IV 0x00000008 -#define MIPS_CPU_ISA_V 0x00000010 +#define MIPS_CPU_ISA_III 0x00000003 +#define MIPS_CPU_ISA_IV 0x00000004 +#define MIPS_CPU_ISA_V 0x00000005 #define MIPS_CPU_ISA_M32R1 0x00000020 #define MIPS_CPU_ISA_M32R2 0x00000040 #define MIPS_CPU_ISA_M64R1 0x00000080 diff --git a/trunk/include/asm-mips/gcc/sgidefs.h b/trunk/include/asm-mips/gcc/sgidefs.h new file mode 100644 index 000000000000..05994371a2af --- /dev/null +++ b/trunk/include/asm-mips/gcc/sgidefs.h @@ -0,0 +1,17 @@ +/* + * include/sgidefs.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * This file is here to satisfy GCC's expectations. + */ +#ifndef __SGIDEFS_H +#define __SGIDEFS_H + +#include + +#endif /* __SGIDEFS_H */ diff --git a/trunk/include/asm-mips/mach-generic/timex.h b/trunk/include/asm-mips/mach-generic/timex.h index 48b4cfaa0d50..c6a2e5f0574a 100644 --- a/trunk/include/asm-mips/mach-generic/timex.h +++ b/trunk/include/asm-mips/mach-generic/timex.h @@ -3,11 +3,20 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 2005 by Ralf Baechle + * Copyright (C) 2003 by Ralf Baechle */ #ifndef __ASM_MACH_GENERIC_TIMEX_H #define __ASM_MACH_GENERIC_TIMEX_H +#include + +/* + * Last remaining user of the i8254 PIC, will be converted, too ... + */ +#ifdef CONFIG_SNI_RM200_PCI +#define CLOCK_TICK_RATE 1193182 +#else #define CLOCK_TICK_RATE 500000 +#endif #endif /* __ASM_MACH_GENERIC_TIMEX_H */ diff --git a/trunk/include/asm-mips/mach-rm200/timex.h b/trunk/include/asm-mips/mach-rm200/timex.h deleted file mode 100644 index 11ff6cb0f214..000000000000 --- a/trunk/include/asm-mips/mach-rm200/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2005 by Ralf Baechle - */ -#ifndef __ASM_MACH_RM200_TIMEX_H -#define __ASM_MACH_RM200_TIMEX_H - -#define CLOCK_TICK_RATE 1193182 - -#endif /* __ASM_MACH_RM200_TIMEX_H */ diff --git a/trunk/include/asm-mips/mman.h b/trunk/include/asm-mips/mman.h index 6d01e26830fa..dd17c8bd62a1 100644 --- a/trunk/include/asm-mips/mman.h +++ b/trunk/include/asm-mips/mman.h @@ -66,8 +66,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-mips/r4kcache.h b/trunk/include/asm-mips/r4kcache.h index 9632c27dad15..cc53196efa40 100644 --- a/trunk/include/asm-mips/r4kcache.h +++ b/trunk/include/asm-mips/r4kcache.h @@ -14,7 +14,6 @@ #include #include -#include /* * This macro return a properly sign-extended address suitable as base address @@ -79,25 +78,22 @@ static inline void flush_scache_line(unsigned long addr) cache_op(Hit_Writeback_Inv_SD, addr); } -#define protected_cache_op(op,addr) \ - __asm__ __volatile__( \ - " .set push \n" \ - " .set noreorder \n" \ - " .set mips3 \n" \ - "1: cache %0, (%1) \n" \ - "2: .set pop \n" \ - " .section __ex_table,\"a\" \n" \ - " "STR(PTR)" 1b, 2b \n" \ - " .previous" \ - : \ - : "i" (op), "r" (addr)) - /* * The next two are for badland addresses like signal trampolines. */ static inline void protected_flush_icache_line(unsigned long addr) { - protected_cache_op(Hit_Invalidate_I, addr); + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set mips3 \n" + "1: cache %0, (%1) \n" + "2: .set pop \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 2b \n" + " .previous" + : + : "i" (Hit_Invalidate_I), "r" (addr)); } /* @@ -108,12 +104,32 @@ static inline void protected_flush_icache_line(unsigned long addr) */ static inline void protected_writeback_dcache_line(unsigned long addr) { - protected_cache_op(Hit_Writeback_Inv_D, addr); + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set mips3 \n" + "1: cache %0, (%1) \n" + "2: .set pop \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 2b \n" + " .previous" + : + : "i" (Hit_Writeback_Inv_D), "r" (addr)); } static inline void protected_writeback_scache_line(unsigned long addr) { - protected_cache_op(Hit_Writeback_Inv_SD, addr); + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set mips3 \n" + "1: cache %0, (%1) \n" + "2: .set pop \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 2b \n" + " .previous" + : + : "i" (Hit_Writeback_Inv_SD), "r" (addr)); } /* @@ -279,28 +295,4 @@ __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) -/* build blast_xxx_range, protected_blast_xxx_range */ -#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ -static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ - unsigned long end) \ -{ \ - unsigned long lsize = cpu_##desc##_line_size(); \ - unsigned long addr = start & ~(lsize - 1); \ - unsigned long aend = (end - 1) & ~(lsize - 1); \ - while (1) { \ - prot##cache_op(hitop, addr); \ - if (addr == aend) \ - break; \ - addr += lsize; \ - } \ -} - -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) -__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) -/* blast_inv_dcache_range */ -__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) - #endif /* _ASM_R4KCACHE_H */ diff --git a/trunk/include/asm-mips/uaccess.h b/trunk/include/asm-mips/uaccess.h index 7a553e9d44d3..91d813a37823 100644 --- a/trunk/include/asm-mips/uaccess.h +++ b/trunk/include/asm-mips/uaccess.h @@ -266,8 +266,6 @@ do { \ */ #define __get_user_asm_ll32(val, addr) \ { \ - unsigned long long __gu_tmp; \ - \ __asm__ __volatile__( \ "1: lw %1, (%3) \n" \ "2: lw %D1, 4(%3) \n" \ @@ -282,9 +280,8 @@ do { \ " " __UA_ADDR " 1b, 4b \n" \ " " __UA_ADDR " 2b, 4b \n" \ " .previous \n" \ - : "=r" (__gu_err), "=&r" (__gu_tmp) \ + : "=r" (__gu_err), "=&r" (val) \ : "0" (0), "r" (addr), "i" (-EFAULT)); \ - (val) = __gu_tmp; \ } /* diff --git a/trunk/include/asm-mips/unistd.h b/trunk/include/asm-mips/unistd.h index 769305d20108..e7ff9b187783 100644 --- a/trunk/include/asm-mips/unistd.h +++ b/trunk/include/asm-mips/unistd.h @@ -1184,8 +1184,10 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION -# ifdef CONFIG_32BIT +# ifndef __mips64 # define __ARCH_WANT_STAT64 +# endif +# ifdef CONFIG_32BIT # define __ARCH_WANT_SYS_TIME # endif # ifdef CONFIG_MIPS32_O32 diff --git a/trunk/include/asm-parisc/mman.h b/trunk/include/asm-parisc/mman.h index a381cf5c8f55..736b0abcac05 100644 --- a/trunk/include/asm-parisc/mman.h +++ b/trunk/include/asm-parisc/mman.h @@ -49,8 +49,6 @@ #define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */ #define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */ #define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-powerpc/mman.h b/trunk/include/asm-powerpc/mman.h index fcff25d13f13..a2e34c21b44f 100644 --- a/trunk/include/asm-powerpc/mman.h +++ b/trunk/include/asm-powerpc/mman.h @@ -45,8 +45,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-s390/mman.h b/trunk/include/asm-s390/mman.h index d41ca1477010..c8d5409b5d56 100644 --- a/trunk/include/asm-s390/mman.h +++ b/trunk/include/asm-s390/mman.h @@ -44,8 +44,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-sh/mman.h b/trunk/include/asm-sh/mman.h index 0e08d0573abc..693bd55a3710 100644 --- a/trunk/include/asm-sh/mman.h +++ b/trunk/include/asm-sh/mman.h @@ -36,8 +36,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-sparc/mman.h b/trunk/include/asm-sparc/mman.h index 4a298b2be859..98435ad8619e 100644 --- a/trunk/include/asm-sparc/mman.h +++ b/trunk/include/asm-sparc/mman.h @@ -55,8 +55,6 @@ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ #define MADV_REMOVE 0x6 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-sparc64/mman.h b/trunk/include/asm-sparc64/mman.h index d705ec92da8b..cb4b6156194d 100644 --- a/trunk/include/asm-sparc64/mman.h +++ b/trunk/include/asm-sparc64/mman.h @@ -55,8 +55,6 @@ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ #define MADV_REMOVE 0x6 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-v850/mman.h b/trunk/include/asm-v850/mman.h index 7b851c310e41..edc79965193a 100644 --- a/trunk/include/asm-v850/mman.h +++ b/trunk/include/asm-v850/mman.h @@ -33,8 +33,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-x86_64/mman.h b/trunk/include/asm-x86_64/mman.h index b699a38c1c3c..d0e97b74f735 100644 --- a/trunk/include/asm-x86_64/mman.h +++ b/trunk/include/asm-x86_64/mman.h @@ -37,8 +37,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/asm-xtensa/mman.h b/trunk/include/asm-xtensa/mman.h index e2d7afb679c8..082a7504925e 100644 --- a/trunk/include/asm-xtensa/mman.h +++ b/trunk/include/asm-xtensa/mman.h @@ -73,8 +73,6 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/trunk/include/linux/jbd.h b/trunk/include/linux/jbd.h index 41ee79962bb2..0fe4aa891ddc 100644 --- a/trunk/include/linux/jbd.h +++ b/trunk/include/linux/jbd.h @@ -497,6 +497,12 @@ struct transaction_s */ struct journal_head *t_checkpoint_list; + /* + * Doubly-linked circular list of all buffers submitted for IO while + * checkpointing. [j_list_lock] + */ + struct journal_head *t_checkpoint_io_list; + /* * Doubly-linked circular list of temporary buffers currently undergoing * IO in the log [j_list_lock] @@ -846,7 +852,7 @@ extern void journal_commit_transaction(journal_t *); /* Checkpoint list management */ int __journal_clean_checkpoint_list(journal_t *journal); -void __journal_remove_checkpoint(struct journal_head *); +int __journal_remove_checkpoint(struct journal_head *); void __journal_insert_checkpoint(struct journal_head *, transaction_t *); /* Buffer IO */ diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index ef21ed296039..920766cea79c 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -149,7 +149,7 @@ struct nlm_rqst * nlmclnt_alloc_call(void); int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_rqst *req); long nlmclnt_block(struct nlm_rqst *req, long timeout); -u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); +u32 nlmclnt_grant(struct nlm_lock *); void nlmclnt_recovery(struct nlm_host *, u32); int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); int nlmclnt_setgrantargs(struct nlm_rqst *, struct nlm_lock *); @@ -204,7 +204,7 @@ nlmsvc_file_inode(struct nlm_file *file) * Compare two host addresses (needs modifying for ipv6) */ static __inline__ int -nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) +nlm_cmp_addr(struct sockaddr_in *sin1, struct sockaddr_in *sin2) { return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; } @@ -214,7 +214,7 @@ nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) * When the second lock is of type F_UNLCK, this acts like a wildcard. */ static __inline__ int -nlm_compare_locks(const struct file_lock *fl1, const struct file_lock *fl2) +nlm_compare_locks(struct file_lock *fl1, struct file_lock *fl2) { return fl1->fl_pid == fl2->fl_pid && fl1->fl_start == fl2->fl_start diff --git a/trunk/include/linux/netfilter_ipv4.h b/trunk/include/linux/netfilter_ipv4.h index 43c09d790b83..fdc4a9527343 100644 --- a/trunk/include/linux/netfilter_ipv4.h +++ b/trunk/include/linux/netfilter_ipv4.h @@ -79,7 +79,7 @@ enum nf_ip_hook_priorities { #ifdef __KERNEL__ extern int ip_route_me_harder(struct sk_buff **pskb); -extern int ip_xfrm_me_harder(struct sk_buff **pskb); + #endif /*__KERNEL__*/ #endif /*__LINUX_IP_NETFILTER_H*/ diff --git a/trunk/include/linux/ptrace.h b/trunk/include/linux/ptrace.h index 0d36750fc0f1..9d5cd106b344 100644 --- a/trunk/include/linux/ptrace.h +++ b/trunk/include/linux/ptrace.h @@ -84,7 +84,6 @@ extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __us extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); extern int ptrace_attach(struct task_struct *tsk); extern int ptrace_detach(struct task_struct *, unsigned int); -extern void __ptrace_detach(struct task_struct *, unsigned int); extern void ptrace_disable(struct task_struct *); extern int ptrace_check_attach(struct task_struct *task, int kill); extern int ptrace_request(struct task_struct *child, long request, long addr, long data); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index b6f51e3a38ec..9c1da0269a18 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -697,8 +697,11 @@ struct task_struct { int lock_depth; /* BKL lock depth */ -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) + int last_waker_cpu; /* CPU that last woke this task up */ +#if defined(__ARCH_WANT_UNLOCKED_CTXSW) int oncpu; +#endif #endif int prio, static_prio; struct list_head run_list; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index fbea12d7a943..8e88b374cee9 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -1123,8 +1123,8 @@ static task_t *copy_process(unsigned long clone_flags, p->real_parent = current; p->parent = p->real_parent; - spin_lock(¤t->sighand->siglock); if (clone_flags & CLONE_THREAD) { + spin_lock(¤t->sighand->siglock); /* * Important: if an exit-all has been started then * do not create this new thread - the whole thread @@ -1162,6 +1162,8 @@ static task_t *copy_process(unsigned long clone_flags, */ p->it_prof_expires = jiffies_to_cputime(1); } + + spin_unlock(¤t->sighand->siglock); } /* @@ -1173,6 +1175,8 @@ static task_t *copy_process(unsigned long clone_flags, if (unlikely(p->ptrace & PT_PTRACED)) __ptrace_link(p, current->parent); + attach_pid(p, PIDTYPE_PID, p->pid); + attach_pid(p, PIDTYPE_TGID, p->tgid); if (thread_group_leader(p)) { p->signal->tty = current->signal->tty; p->signal->pgrp = process_group(current); @@ -1182,12 +1186,9 @@ static task_t *copy_process(unsigned long clone_flags, if (p->pid) __get_cpu_var(process_counts)++; } - attach_pid(p, PIDTYPE_TGID, p->tgid); - attach_pid(p, PIDTYPE_PID, p->pid); nr_threads++; total_forks++; - spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); proc_fork_connector(p); return p; diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 5ae51f1bc7c8..2b6e1757aedd 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -418,19 +418,8 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) /* Switch the timer base, if necessary: */ new_base = switch_hrtimer_base(timer, base); - if (mode == HRTIMER_REL) { + if (mode == HRTIMER_REL) tim = ktime_add(tim, new_base->get_time()); - /* - * CONFIG_TIME_LOW_RES is a temporary way for architectures - * to signal that they simply return xtime in - * do_gettimeoffset(). In this case we want to round up by - * resolution when starting a relative timer, to avoid short - * timeouts. This will go away with the GTOD framework. - */ -#ifdef CONFIG_TIME_LOW_RES - tim = ktime_add(tim, base->resolution); -#endif - } timer->expires = tim; enqueue_hrtimer(timer, new_base); diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index d95a72c9279d..5f33cdb6fff5 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -72,8 +72,8 @@ void ptrace_untrace(task_t *child) */ void __ptrace_unlink(task_t *child) { - BUG_ON(!child->ptrace); - + if (!child->ptrace) + BUG(); child->ptrace = 0; if (!list_empty(&child->ptrace_list)) { list_del_init(&child->ptrace_list); @@ -184,27 +184,22 @@ int ptrace_attach(struct task_struct *task) return retval; } -void __ptrace_detach(struct task_struct *child, unsigned int data) -{ - child->exit_code = data; - /* .. re-parent .. */ - __ptrace_unlink(child); - /* .. and wake it up. */ - if (child->exit_state != EXIT_ZOMBIE) - wake_up_process(child); -} - int ptrace_detach(struct task_struct *child, unsigned int data) { if (!valid_signal(data)) - return -EIO; + return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); + /* .. re-parent .. */ + child->exit_code = data; + write_lock_irq(&tasklist_lock); - if (child->ptrace) - __ptrace_detach(child, data); + __ptrace_unlink(child); + /* .. and wake it up. */ + if (child->exit_state != EXIT_ZOMBIE) + wake_up_process(child); write_unlock_irq(&tasklist_lock); return 0; @@ -247,7 +242,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in if (write) { copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes); - set_page_dirty_lock(page); + if (!PageCompound(page)) + set_page_dirty_lock(page); } else { copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 66d957227de9..87d93be336a1 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -1204,6 +1204,9 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) } } + if (p->last_waker_cpu != this_cpu) + goto out_set_cpu; + if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) goto out_set_cpu; @@ -1274,6 +1277,8 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) cpu = task_cpu(p); } + p->last_waker_cpu = this_cpu; + out_activate: #endif /* CONFIG_SMP */ if (old_state == TASK_UNINTERRUPTIBLE) { @@ -1355,9 +1360,12 @@ void fastcall sched_fork(task_t *p, int clone_flags) #ifdef CONFIG_SCHEDSTATS memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) + p->last_waker_cpu = cpu; +#if defined(__ARCH_WANT_UNLOCKED_CTXSW) p->oncpu = 0; #endif +#endif #ifdef CONFIG_PREEMPT /* Want to start with kernel preemption disabled. */ task_thread_info(p)->preempt_count = 1; diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 508707704d2c..67f29516662a 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -85,7 +85,7 @@ void free_huge_page(struct page *page) BUG_ON(page_count(page)); INIT_LIST_HEAD(&page->lru); - page[1].lru.next = NULL; /* reset dtor */ + page[1].mapping = NULL; spin_lock(&hugetlb_lock); enqueue_huge_page(page); @@ -105,7 +105,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr) } spin_unlock(&hugetlb_lock); set_page_count(page, 1); - page[1].lru.next = (void *)free_huge_page; /* set dtor */ + page[1].mapping = (void *)free_huge_page; for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) clear_user_highpage(&page[i], addr); return page; diff --git a/trunk/mm/madvise.c b/trunk/mm/madvise.c index af3d573b0141..ae0ae3ea299a 100644 --- a/trunk/mm/madvise.c +++ b/trunk/mm/madvise.c @@ -22,23 +22,16 @@ static long madvise_behavior(struct vm_area_struct * vma, struct mm_struct * mm = vma->vm_mm; int error = 0; pgoff_t pgoff; - int new_flags = vma->vm_flags; + int new_flags = vma->vm_flags & ~VM_READHINTMASK; switch (behavior) { - case MADV_NORMAL: - new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ; - break; case MADV_SEQUENTIAL: - new_flags = (new_flags & ~VM_RAND_READ) | VM_SEQ_READ; + new_flags |= VM_SEQ_READ; break; case MADV_RANDOM: - new_flags = (new_flags & ~VM_SEQ_READ) | VM_RAND_READ; - break; - case MADV_DONTFORK: - new_flags |= VM_DONTCOPY; + new_flags |= VM_RAND_READ; break; - case MADV_DOFORK: - new_flags &= ~VM_DONTCOPY; + default: break; } @@ -184,12 +177,6 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, long error; switch (behavior) { - case MADV_DOFORK: - if (vma->vm_flags & VM_IO) { - error = -EINVAL; - break; - } - case MADV_DONTFORK: case MADV_NORMAL: case MADV_SEQUENTIAL: case MADV_RANDOM: diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 62c122528587..dde04ff4be31 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -56,7 +56,6 @@ long nr_swap_pages; int percpu_pagelist_fraction; static void fastcall free_hot_cold_page(struct page *page, int cold); -static void __free_pages_ok(struct page *page, unsigned int order); /* * results with 256, 32 in the lowmem_reserve sysctl: @@ -170,23 +169,20 @@ static void bad_page(struct page *page) * All pages have PG_compound set. All pages have their ->private pointing at * the head page (even the head page has this). * - * The first tail page's ->lru.next holds the address of the compound page's - * put_page() function. Its ->lru.prev holds the order of allocation. - * This usage means that zero-order pages may not be compound. + * The first tail page's ->mapping, if non-zero, holds the address of the + * compound page's put_page() function. + * + * The order of the allocation is stored in the first tail page's ->index + * This is only for debug at present. This usage means that zero-order pages + * may not be compound. */ - -static void free_compound_page(struct page *page) -{ - __free_pages_ok(page, (unsigned long)page[1].lru.prev); -} - static void prep_compound_page(struct page *page, unsigned long order) { int i; int nr_pages = 1 << order; - page[1].lru.next = (void *)free_compound_page; /* set dtor */ - page[1].lru.prev = (void *)order; + page[1].mapping = NULL; + page[1].index = order; for (i = 0; i < nr_pages; i++) { struct page *p = page + i; @@ -200,7 +196,7 @@ static void destroy_compound_page(struct page *page, unsigned long order) int i; int nr_pages = 1 << order; - if (unlikely((unsigned long)page[1].lru.prev != order)) + if (unlikely(page[1].index != order)) bad_page(page); for (i = 0; i < nr_pages; i++) { diff --git a/trunk/mm/swap.c b/trunk/mm/swap.c index cce3dda59c59..76247424dea1 100644 --- a/trunk/mm/swap.c +++ b/trunk/mm/swap.c @@ -40,7 +40,7 @@ static void put_compound_page(struct page *page) if (put_page_testzero(page)) { void (*dtor)(struct page *page); - dtor = (void (*)(struct page *))page[1].lru.next; + dtor = (void (*)(struct page *))page[1].mapping; (*dtor)(page); } } diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 35cf3a074087..cc047f7fb6ef 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -67,7 +67,7 @@ void br_stp_disable_bridge(struct net_bridge *br) { struct net_bridge_port *p; - spin_lock_bh(&br->lock); + spin_lock(&br->lock); list_for_each_entry(p, &br->port_list, list) { if (p->state != BR_STATE_DISABLED) br_stp_disable_port(p); @@ -76,7 +76,7 @@ void br_stp_disable_bridge(struct net_bridge *br) br->topology_change = 0; br->topology_change_detected = 0; - spin_unlock_bh(&br->lock); + spin_unlock(&br->lock); del_timer_sync(&br->hello_timer); del_timer_sync(&br->topology_change_timer); diff --git a/trunk/net/ipv4/netfilter.c b/trunk/net/ipv4/netfilter.c index ed42cdc57cd9..52a3d7c57907 100644 --- a/trunk/net/ipv4/netfilter.c +++ b/trunk/net/ipv4/netfilter.c @@ -78,47 +78,6 @@ int ip_route_me_harder(struct sk_buff **pskb) } EXPORT_SYMBOL(ip_route_me_harder); -#ifdef CONFIG_XFRM -int ip_xfrm_me_harder(struct sk_buff **pskb) -{ - struct flowi fl; - unsigned int hh_len; - struct dst_entry *dst; - - if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) - return 0; - if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0) - return -1; - - dst = (*pskb)->dst; - if (dst->xfrm) - dst = ((struct xfrm_dst *)dst)->route; - dst_hold(dst); - - if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0) - return -1; - - dst_release((*pskb)->dst); - (*pskb)->dst = dst; - - /* Change in oif may mean change in hh_len. */ - hh_len = (*pskb)->dst->dev->hard_header_len; - if (skb_headroom(*pskb) < hh_len) { - struct sk_buff *nskb; - - nskb = skb_realloc_headroom(*pskb, hh_len); - if (!nskb) - return -1; - if ((*pskb)->sk) - skb_set_owner_w(nskb, (*pskb)->sk); - kfree_skb(*pskb); - *pskb = nskb; - } - return 0; -} -EXPORT_SYMBOL(ip_xfrm_me_harder); -#endif - void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); EXPORT_SYMBOL(ip_nat_decode_session); diff --git a/trunk/net/ipv4/netfilter/ip_nat_standalone.c b/trunk/net/ipv4/netfilter/ip_nat_standalone.c index 7c3f7d380240..92c54999a19d 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_nat_standalone.c @@ -235,19 +235,19 @@ ip_nat_out(unsigned int hooknum, return NF_ACCEPT; ret = ip_nat_fn(hooknum, pskb, in, out, okfn); -#ifdef CONFIG_XFRM if (ret != NF_DROP && ret != NF_STOLEN && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); if (ct->tuplehash[dir].tuple.src.ip != ct->tuplehash[!dir].tuple.dst.ip +#ifdef CONFIG_XFRM || ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all +#endif ) - return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP; + return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; } -#endif return ret; }