diff --git a/[refs] b/[refs] index c80d4bcd493d..d971e45416bf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: abde3dff2496d9d44a218cf8e2a17c2383f20b22 +refs/heads/master: d2c7ddd6261eb885091cf6ddbcfae01f4216fb8e diff --git a/trunk/Documentation/local_ops.txt b/trunk/Documentation/local_ops.txt index 4269a1105b37..1a45f11e645e 100644 --- a/trunk/Documentation/local_ops.txt +++ b/trunk/Documentation/local_ops.txt @@ -45,6 +45,29 @@ long fails. The definition looks like : typedef struct { atomic_long_t a; } local_t; +* Rules to follow when using local atomic operations + +- Variables touched by local ops must be per cpu variables. +- _Only_ the CPU owner of these variables must write to them. +- This CPU can use local ops from any context (process, irq, softirq, nmi, ...) + to update its local_t variables. +- Preemption (or interrupts) must be disabled when using local ops in + process context to make sure the process won't be migrated to a + different CPU between getting the per-cpu variable and doing the + actual local op. +- When using local ops in interrupt context, no special care must be + taken on a mainline kernel, since they will run on the local CPU with + preemption already disabled. I suggest, however, to explicitly + disable preemption anyway to make sure it will still work correctly on + -rt kernels. +- Reading the local cpu variable will provide the current copy of the + variable. +- Reads of these variables can be done from any CPU, because updates to + "long", aligned, variables are always atomic. Since no memory + synchronization is done by the writer CPU, an outdated copy of the + variable can be read when reading some _other_ cpu's variables. + + * Rules to follow when using local atomic operations - Variables touched by local ops must be per cpu variables. diff --git a/trunk/arch/alpha/math-emu/math.c b/trunk/arch/alpha/math-emu/math.c index 58c2669a1dd4..ae79dd970b02 100644 --- a/trunk/arch/alpha/math-emu/math.c +++ b/trunk/arch/alpha/math-emu/math.c @@ -225,7 +225,7 @@ alpha_fp_emul (unsigned long pc) FP_UNPACK_SP(SB, &vb); DR_c = DB_c; DR_s = DB_s; - DR_e = DB_e + (1024 - 128); + DR_e = DB_e; DR_f = SB_f << (52 - 23); goto pack_d; } diff --git a/trunk/arch/cris/arch-v10/vmlinux.lds.S b/trunk/arch/cris/arch-v10/vmlinux.lds.S index 97a7876ed681..9859d49d088b 100644 --- a/trunk/arch/cris/arch-v10/vmlinux.lds.S +++ b/trunk/arch/cris/arch-v10/vmlinux.lds.S @@ -9,8 +9,7 @@ */ #include -#include - + jiffies = jiffies_64; SECTIONS { @@ -24,7 +23,7 @@ SECTIONS _stext = .; __stext = .; .text : { - TEXT_TEXT + *(.text) SCHED_TEXT LOCK_TEXT *(.fixup) @@ -50,10 +49,10 @@ SECTIONS __edata = . ; /* End of data section */ _edata = . ; - . = ALIGN(PAGE_SIZE); /* init_task and stack, must be aligned */ + . = ALIGN(8192); /* init_task and stack, must be aligned */ .data.init_task : { *(.data.init_task) } - . = ALIGN(PAGE_SIZE); /* Init code and data */ + . = ALIGN(8192); /* Init code and data */ __init_begin = .; .init.text : { _sinittext = .; @@ -67,7 +66,13 @@ SECTIONS __setup_end = .; .initcall.init : { __initcall_start = .; - INITCALLS + *(.initcall1.init); + *(.initcall2.init); + *(.initcall3.init); + *(.initcall4.init); + *(.initcall5.init); + *(.initcall6.init); + *(.initcall7.init); __initcall_end = .; } @@ -83,18 +88,16 @@ SECTIONS __initramfs_start = .; *(.init.ramfs) __initramfs_end = .; + /* We fill to the next page, so we can discard all init + pages without needing to consider what payload might be + appended to the kernel image. */ + FILL (0); + . = ALIGN (8192); } #endif + __vmlinux_end = .; /* last address of the physical file */ - - /* - * We fill to the next page, so we can discard all init - * pages without needing to consider what payload might be - * appended to the kernel image. - */ - . = ALIGN(PAGE_SIZE); - - __init_end = .; + __init_end = .; __data_end = . ; /* Move to _edata ? */ __bss_start = .; /* BSS */ diff --git a/trunk/arch/sparc64/kernel/sun4v_tlb_miss.S b/trunk/arch/sparc64/kernel/sun4v_tlb_miss.S index fd9430562e0b..9871dbb1ab42 100644 --- a/trunk/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/trunk/arch/sparc64/kernel/sun4v_tlb_miss.S @@ -215,7 +215,6 @@ sun4v_itlb_error: 1: ba,pt %xcc, etrap 2: or %g7, %lo(2b), %g7 - mov %l4, %o1 call sun4v_itlb_error_report add %sp, PTREGS_OFF, %o0 @@ -242,7 +241,6 @@ sun4v_dtlb_error: 1: ba,pt %xcc, etrap 2: or %g7, %lo(2b), %g7 - mov %l4, %o1 call sun4v_dtlb_error_report add %sp, PTREGS_OFF, %o0 diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index 2b6abf633343..04998388259f 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -1950,8 +1950,6 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc); - printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]); - print_symbol(KERN_EMERG "SUN4V-ITLB: O7<%s>\n", regs->u_regs[UREG_I7]); printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx, @@ -1973,8 +1971,6 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc); - printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]); - print_symbol(KERN_EMERG "SUN4V-DTLB: O7<%s>\n", regs->u_regs[UREG_I7]); printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx, diff --git a/trunk/drivers/cpufreq/cpufreq_conservative.c b/trunk/drivers/cpufreq/cpufreq_conservative.c index 5d3a04ba6ad2..1bba99747f5b 100644 --- a/trunk/drivers/cpufreq/cpufreq_conservative.c +++ b/trunk/drivers/cpufreq/cpufreq_conservative.c @@ -603,9 +603,5 @@ MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " "optimised for use in a battery environment"); MODULE_LICENSE ("GPL"); -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE -fs_initcall(cpufreq_gov_dbs_init); -#else module_init(cpufreq_gov_dbs_init); -#endif module_exit(cpufreq_gov_dbs_exit); diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index d2af20dda382..369f44595150 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -610,9 +610,6 @@ MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " "Low Latency Frequency Transition capable processors"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -fs_initcall(cpufreq_gov_dbs_init); -#else module_init(cpufreq_gov_dbs_init); -#endif module_exit(cpufreq_gov_dbs_exit); + diff --git a/trunk/drivers/cpufreq/cpufreq_userspace.c b/trunk/drivers/cpufreq/cpufreq_userspace.c index f8cdde4bf6cd..51bedab6c808 100644 --- a/trunk/drivers/cpufreq/cpufreq_userspace.c +++ b/trunk/drivers/cpufreq/cpufreq_userspace.c @@ -231,9 +231,5 @@ MODULE_AUTHOR ("Dominik Brodowski , Russell King netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -3929,14 +3929,17 @@ e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring[0] is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); + tx_cleaned = e1000_clean_tx_irq(adapter, + &adapter->tx_ring[0]); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { if (likely(adapter->itr_setting & 3)) diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 4a6fc7453776..2ab3bfbb8a63 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -1384,7 +1384,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) { struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); struct net_device *poll_dev = adapter->netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -1394,12 +1394,15 @@ static int e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - e1000_clean_tx_irq(adapter); + tx_cleaned = e1000_clean_tx_irq(adapter); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { if (adapter->itr_setting & 3) diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index a56491617661..de3f45e4c5ae 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -1468,13 +1468,16 @@ static int ixgbe_clean(struct napi_struct *napi, int budget) struct ixgbe_adapter *adapter = container_of(napi, struct ixgbe_adapter, napi); struct net_device *netdev = adapter->netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* In non-MSIX case, there is no multi-Tx/Rx queue */ - ixgbe_clean_tx_irq(adapter, adapter->tx_ring); + tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { netif_rx_complete(netdev, napi); diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index 6b9840cce0f4..f7b8648acbfa 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -215,7 +215,6 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of IO " "resources: %d \n", PNP_MAX_PORT); - warned = 1; } } @@ -243,7 +242,6 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of mem " "resources: %d\n", PNP_MAX_MEM); - warned = 1; } } diff --git a/trunk/drivers/video/modedb.c b/trunk/drivers/video/modedb.c index 08d072552233..8d81ef019c6c 100644 --- a/trunk/drivers/video/modedb.c +++ b/trunk/drivers/video/modedb.c @@ -259,10 +259,6 @@ static const struct fb_videomode modedb[] = { /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ - NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, - 0, FB_VMODE_NONINTERLACED }, }; diff --git a/trunk/fs/hfs/btree.c b/trunk/fs/hfs/btree.c index 110dd3515dc8..31284c77bba8 100644 --- a/trunk/fs/hfs/btree.c +++ b/trunk/fs/hfs/btree.c @@ -61,7 +61,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke mapping = tree->inode->i_mapping; page = read_mapping_page(mapping, 0, NULL); if (IS_ERR(page)) - goto free_inode; + goto free_tree; /* Load the header */ head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); @@ -99,12 +99,11 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke page_cache_release(page); return tree; -fail_page: + fail_page: page_cache_release(page); -free_inode: + free_tree: tree->inode->i_mapping->a_ops = &hfs_aops; iput(tree->inode); -free_tree: kfree(tree); return NULL; } diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index 038ed7436199..08ff6c7028cc 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -288,12 +288,10 @@ handle_t *journal_start(journal_t *journal, int nblocks) jbd_free_handle(handle); current->journal_info = NULL; handle = ERR_PTR(err); - goto out; } lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_); -out: return handle; } diff --git a/trunk/include/asm-cris/page.h b/trunk/include/asm-cris/page.h index b84353ef6998..0648e3153f81 100644 --- a/trunk/include/asm-cris/page.h +++ b/trunk/include/asm-cris/page.h @@ -4,11 +4,14 @@ #ifdef __KERNEL__ #include -#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 13 -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#else +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif #define PAGE_MASK (~(PAGE_SIZE-1)) #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index bb7df2a28bd7..c6a4f8aebeba 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -451,11 +451,13 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, enum umh_wait wait) { DECLARE_COMPLETION_ONSTACK(done); - int retval = 0; + int retval; helper_lock(); - if (sub_info->path[0] == '\0') + if (sub_info->path[0] == '\0') { + retval = 0; goto out; + } if (!khelper_wq || usermodehelper_disabled) { retval = -EBUSY; @@ -466,14 +468,13 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, sub_info->wait = wait; queue_work(khelper_wq, &sub_info->work); - if (wait == UMH_NO_WAIT) /* task has freed sub_info */ - goto unlock; + if (wait == UMH_NO_WAIT) /* task has freed sub_info */ + return 0; wait_for_completion(&done); retval = sub_info->retval; -out: + out: call_usermodehelper_freeinfo(sub_info); -unlock: helper_unlock(); return retval; } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 6dd1cd88bfb6..4bf0b6d0eb2a 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -392,7 +392,6 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ return NULL; } -#ifdef CONFIG_DEBUG_VM /* * Add some anal sanity checks for now. Eventually, * we should just do "return pfn_to_page(pfn)", but @@ -403,7 +402,6 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ print_bad_pte(vma, pte, addr); return NULL; } -#endif /* * NOTE! We still have PageReserved() pages in the page diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index b2838c24e582..e1028fae3ebb 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -2566,7 +2566,7 @@ static void __meminit zone_init_free_lists(struct pglist_data *pgdat, memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY) #endif -static int zone_batchsize(struct zone *zone) +static int __devinit zone_batchsize(struct zone *zone) { int batch;