Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 30 Oct 2006 01:25:48 +0000 (17:25 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 30 Oct 2006 01:25:48 +0000 (17:25 -0800)
* master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] 3914/1: [Jornada7xx] - Typo Fix in cpu-sa1110.c (b != B)
  [ARM] 3913/1: n2100: fix IRQ routing for second ethernet port
  [ARM] Add KBUILD_IMAGE target support
  [ARM] Fix suspend oops caused by PXA2xx PCMCIA driver
  [ARM] Fix i2c-pxa slave mode support
  [ARM] 3900/1: Fix VFP Division by Zero exception handling.
  [ARM] 3899/1: Fix the normalization of the denormal double precision number.
  [ARM] 3909/1: Disable UWIND_INFO for ARM (again)
  [ARM] Add __must_check to uaccess functions
  [ARM] Add realview SMP default configuration
  [ARM] Fix SMP irqflags support

68 files changed:
arch/i386/kernel/setup.c
arch/i386/mach-visws/visws_apic.c
arch/m68k/kernel/vmlinux-std.lds
arch/m68k/kernel/vmlinux-sun3.lds
arch/s390/appldata/appldata_base.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/signal.c
arch/s390/kernel/traps.c
drivers/base/Kconfig
drivers/block/cciss.c
drivers/char/watchdog/sc1200wdt.c
drivers/ide/pci/generic.c
drivers/ieee1394/ohci1394.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/misc/ioc4.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/pcmcia/at91_cf.c
drivers/pcmcia/au1000_generic.c
drivers/pcmcia/ds.c
drivers/pcmcia/i82092.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/yenta_socket.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device.h
drivers/s390/crypto/ap_bus.c
fs/block_dev.c
fs/dcache.c
fs/ext4/resize.c
fs/hugetlbfs/inode.c
fs/jbd/transaction.c
fs/jbd2/transaction.c
fs/splice.c
include/asm-i386/mach-visws/do_timer.h [deleted file]
include/asm-i386/mach-visws/mach_apic.h
include/linux/compat.h
include/linux/mmzone.h
include/linux/pagemap.h
include/linux/sched.h
include/linux/taskstats_kern.h
include/linux/vmalloc.h
kernel/compat.c
kernel/cpu.c
kernel/exit.c
kernel/fork.c
kernel/module.c
kernel/taskstats.c
kernel/time/ntp.c
kernel/tsacct.c
kernel/workqueue.c
lib/string.c
mm/filemap.c
mm/hugetlb.c
mm/page_alloc.c
mm/sparse.c
mm/vmalloc.c
mm/vmscan.c
mm/vmstat.c

index 519e63c..141041d 100644 (file)
@@ -846,7 +846,7 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
 static int __init
 efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
 {
-       memory_present(0, start, end);
+       memory_present(0, PFN_UP(start), PFN_DOWN(end));
        return 0;
 }
 
index 07097ed..38c2b13 100644 (file)
@@ -122,7 +122,7 @@ static void end_cobalt_irq(unsigned int irq)
        spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static struct hw_interrupt_type cobalt_irq_type = {
+static struct irq_chip cobalt_irq_type = {
        .typename =     "Cobalt-APIC",
        .startup =      startup_cobalt_irq,
        .shutdown =     disable_cobalt_irq,
@@ -159,7 +159,7 @@ static void end_piix4_master_irq(unsigned int irq)
        spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static struct hw_interrupt_type piix4_master_irq_type = {
+static struct irq_chip piix4_master_irq_type = {
        .typename =     "PIIX4-master",
        .startup =      startup_piix4_master_irq,
        .ack =          ack_cobalt_irq,
@@ -167,9 +167,8 @@ static struct hw_interrupt_type piix4_master_irq_type = {
 };
 
 
-static struct hw_interrupt_type piix4_virtual_irq_type = {
+static struct irq_chip piix4_virtual_irq_type = {
        .typename =     "PIIX4-virtual",
-       .startup =      startup_8259A_irq,
        .shutdown =     disable_8259A_irq,
        .enable =       enable_8259A_irq,
        .disable =      disable_8259A_irq,
index 69d1d3d..d279445 100644 (file)
@@ -54,13 +54,7 @@ SECTIONS
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-       *(.initcall1.init)
-       *(.initcall2.init)
-       *(.initcall3.init)
-       *(.initcall4.init)
-       *(.initcall5.init)
-       *(.initcall6.init)
-       *(.initcall7.init)
+       INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
index 65cc39c..2550b4a 100644 (file)
@@ -48,13 +48,7 @@ __init_begin = .;
        __setup_end = .;
        __initcall_start = .;
        .initcall.init : {
-               *(.initcall1.init)
-               *(.initcall2.init)
-               *(.initcall3.init)
-               *(.initcall4.init)
-               *(.initcall5.init)
-               *(.initcall6.init)
-               *(.initcall7.init)
+               INITCALLS
        }
        __initcall_end = .;
        __con_initcall_start = .;
index 45c9fa7..af1e8fc 100644 (file)
@@ -310,6 +310,7 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp,
        if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) {
                return -EFAULT;
        }
+       interval = 0;
        sscanf(buf, "%i", &interval);
        if (interval <= 0) {
                P_ERROR("Timer CPU interval has to be > 0!\n");
index 2001767..5b33f82 100644 (file)
@@ -757,7 +757,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
                            put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
                                error = -EFAULT;
                }
-               copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+               if (copy_to_user(args->__unused, tmp.__unused,
+                                sizeof(tmp.__unused)))
+                       error = -EFAULT;
        }
        return error;
 }
index d49b876..861888a 100644 (file)
@@ -169,12 +169,12 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
                compat_old_sigset_t mask;
                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(sa_handler, &act->sa_handler) ||
-                   __get_user(sa_restorer, &act->sa_restorer))
+                   __get_user(sa_restorer, &act->sa_restorer) ||
+                   __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+                   __get_user(mask, &act->sa_mask))
                        return -EFAULT;
                new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
                new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
-               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               __get_user(mask, &act->sa_mask);
                siginitset(&new_ka.sa.sa_mask, mask);
         }
 
@@ -185,10 +185,10 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
                sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
                    __put_user(sa_handler, &oact->sa_handler) ||
-                   __put_user(sa_restorer, &oact->sa_restorer))
+                   __put_user(sa_restorer, &oact->sa_restorer) ||
+                   __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+                   __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
                        return -EFAULT;
-               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
         }
 
        return ret;
index cb0efae..71e54ef 100644 (file)
@@ -1664,4 +1664,4 @@ sys_getcpu_wrapper:
        llgtr   %r2,%r2                 # unsigned *
        llgtr   %r3,%r3                 # unsigned *
        llgtr   %r4,%r4                 # struct getcpu_cache *
-       jg      sys_tee
+       jg      sys_getcpu
index 4392a77..4c8a795 100644 (file)
@@ -80,10 +80,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
                old_sigset_t mask;
                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+                   __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+                   __get_user(mask, &act->sa_mask))
                        return -EFAULT;
-               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               __get_user(mask, &act->sa_mask);
                siginitset(&new_ka.sa.sa_mask, mask);
        }
 
@@ -92,10 +92,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
        if (!ret && oact) {
                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+                   __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+                   __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
                        return -EFAULT;
-               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
        }
 
        return ret;
index 66375a5..92ecffb 100644 (file)
@@ -462,7 +462,8 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                local_irq_enable();
 
        if (regs->psw.mask & PSW_MASK_PSTATE) {
-               get_user(*((__u16 *) opcode), (__u16 __user *) location);
+               if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
+                       return;
                if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
                        if (current->ptrace & PT_PTRACED)
                                force_sig(SIGTRAP, current);
@@ -470,20 +471,25 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                                signal = SIGILL;
 #ifdef CONFIG_MATHEMU
                } else if (opcode[0] == 0xb3) {
-                       get_user(*((__u16 *) (opcode+2)), location+1);
+                       if (get_user(*((__u16 *) (opcode+2)), location+1))
+                               return;
                        signal = math_emu_b3(opcode, regs);
                 } else if (opcode[0] == 0xed) {
-                       get_user(*((__u32 *) (opcode+2)),
-                                (__u32 __user *)(location+1));
+                       if (get_user(*((__u32 *) (opcode+2)),
+                                    (__u32 __user *)(location+1)))
+                               return;
                        signal = math_emu_ed(opcode, regs);
                } else if (*((__u16 *) opcode) == 0xb299) {
-                       get_user(*((__u16 *) (opcode+2)), location+1);
+                       if (get_user(*((__u16 *) (opcode+2)), location+1))
+                               return;
                        signal = math_emu_srnm(opcode, regs);
                } else if (*((__u16 *) opcode) == 0xb29c) {
-                       get_user(*((__u16 *) (opcode+2)), location+1);
+                       if (get_user(*((__u16 *) (opcode+2)), location+1))
+                               return;
                        signal = math_emu_stfpc(opcode, regs);
                } else if (*((__u16 *) opcode) == 0xb29d) {
-                       get_user(*((__u16 *) (opcode+2)), location+1);
+                       if (get_user(*((__u16 *) (opcode+2)), location+1))
+                               return;
                        signal = math_emu_lfpc(opcode, regs);
 #endif
                } else
index 0b4e224..1429f3a 100644 (file)
@@ -37,8 +37,8 @@ config DEBUG_DRIVER
 
          If you are unsure about this, say N here.
 
-endmenu
-
 config SYS_HYPERVISOR
        bool
        default n
+
+endmenu
index bc66026..6ffe2b2 100644 (file)
@@ -1992,8 +1992,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
                *block_size = BLOCK_SIZE;
        }
        if (*total_size != (__u32) 0)
-               printk(KERN_INFO "      blocks= %lld block_size= %d\n",
-               *total_size, *block_size);
+               printk(KERN_INFO "      blocks= %llu block_size= %d\n",
+               (unsigned long long)*total_size, *block_size);
        kfree(buf);
        return;
 }
@@ -2027,8 +2027,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size,
                *total_size = 0;
                *block_size = BLOCK_SIZE;
        }
-       printk(KERN_INFO "      blocks= %lld block_size= %d\n",
-              *total_size, *block_size);
+       printk(KERN_INFO "      blocks= %llu block_size= %d\n",
+              (unsigned long long)*total_size, *block_size);
        kfree(buf);
        return;
 }
index d8d0f28..e323983 100644 (file)
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
        if (io == -1) {
                printk(KERN_ERR PFX "io parameter must be specified\n");
                ret = -EINVAL;
-               goto out_clean;
+               goto out_pnp;
        }
 
 #if defined CONFIG_PNP
@@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void)
        if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
                printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
                ret = -EBUSY;
-               goto out_clean;
+               goto out_pnp;
        }
 
        ret = sc1200wdt_probe();
@@ -435,6 +435,11 @@ out_rbt:
 out_io:
        release_region(io, io_len);
 
+out_pnp:
+#if defined CONFIG_PNP
+       if (isapnp)
+               pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
        goto out_clean;
 }
 
index ad418ce..e72ab36 100644 (file)
@@ -247,8 +247,10 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi
            (!(PCI_FUNC(dev->devfn) & 1)))
                goto out;
 
-       if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
-               goto out;
+       if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
+               if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+                       goto out;
+       }
 
        if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
                pci_read_config_word(dev, PCI_COMMAND, &command);
index dea1352..6e8ea91 100644 (file)
@@ -3552,12 +3552,21 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        int err;
 
+       printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
+              OHCI1394_DRIVER_NAME);
+
        err = pci_save_state(pdev);
-       if (err)
-               goto out;
+       if (err) {
+               printk(KERN_ERR "%s: pci_save_state failed with %d\n",
+                      OHCI1394_DRIVER_NAME, err);
+               return err;
+       }
        err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#ifdef OHCI1394_DEBUG
        if (err)
-               goto out;
+               printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n",
+                      OHCI1394_DRIVER_NAME, err);
+#endif /* OHCI1394_DEBUG */
 
 /* PowerMac suspend code comes last */
 #ifdef CONFIG_PPC_PMAC
@@ -3570,8 +3579,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
                        pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
        }
 #endif /* CONFIG_PPC_PMAC */
-out:
-       return err;
+
+       return 0;
 }
 #endif /* CONFIG_PM */
 
index 7daa7b1..50ab4a9 100644 (file)
@@ -2003,6 +2003,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
        kobject_init(&rdev->kobj);
 
        rdev->desc_nr = -1;
+       rdev->saved_raid_disk = -1;
        rdev->flags = 0;
        rdev->data_offset = 0;
        rdev->sb_events = 0;
@@ -4044,11 +4045,8 @@ static int update_size(mddev_t *mddev, unsigned long size)
                return -EBUSY;
        ITERATE_RDEV(mddev,rdev,tmp) {
                sector_t avail;
-               if (rdev->sb_offset > rdev->data_offset)
-                       avail = (rdev->sb_offset*2) - rdev->data_offset;
-               else
-                       avail = get_capacity(rdev->bdev->bd_disk)
-                               - rdev->data_offset;
+               avail = rdev->size * 2;
+
                if (fit && (size == 0 || size > avail/2))
                        size = avail/2;
                if (avail < ((sector_t)size << 1))
index a6260f0..14da37f 100644 (file)
@@ -277,6 +277,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
                        set_bit(Faulty, &rdev->flags);
                        set_bit(MD_CHANGE_DEVS, &mddev->flags);
                        conf->working_disks--;
+                       mddev->degraded++;
                        printk(KERN_ALERT "multipath: IO failure on %s,"
                                " disabling IO path. \n Operation continuing"
                                " on %d IO paths.\n",
@@ -336,6 +337,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                                blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
                        conf->working_disks++;
+                       mddev->degraded--;
                        rdev->raid_disk = path;
                        set_bit(In_sync, &rdev->flags);
                        rcu_assign_pointer(p->rdev, rdev);
index dc9d2de..656fae9 100644 (file)
@@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk,
                                               "raid1:%s: read error corrected "
                                               "(%d sectors at %llu on %s)\n",
                                               mdname(mddev), s,
-                                              (unsigned long long)sect +
-                                                  rdev->data_offset,
+                                              (unsigned long long)(sect +
+                                                  rdev->data_offset),
                                               bdevname(rdev->bdev, b));
                                }
                        }
index 74f17a9..7492d60 100644 (file)
@@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
                                               "raid10:%s: read error corrected"
                                               " (%d sectors at %llu on %s)\n",
                                               mdname(mddev), s,
-                                              (unsigned long long)sect+
-                                                   rdev->data_offset,
+                                              (unsigned long long)(sect+
+                                                   rdev->data_offset),
                                               bdevname(rdev->bdev, b));
 
                                rdev_dec_pending(rdev, mddev);
index 79354bb..b995a15 100644 (file)
@@ -210,8 +210,8 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
 
                do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
                printk(KERN_DEBUG
-                      "IOC4 %s: PCI clock is %lld ns.\n",
-                      pci_name(idd->idd_pdev), ns);
+                      "IOC4 %s: PCI clock is %llu ns.\n",
+                      pci_name(idd->idd_pdev), (unsigned long long)ns);
        }
 
        /* Remember results.  We store the extint clock period rather
index 686d895..f63909e 100644 (file)
@@ -887,6 +887,13 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
        PCMCIA_DEVICE_PROD_ID123(
                "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02",
                0xc7b8df9d, 0x1700d087, 0x4b74baa0),
+       PCMCIA_DEVICE_PROD_ID123(
+               "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio",
+               "Ver. 1.00",
+               0x5cd01705, 0x4271660f, 0x9d08ee12),
+       PCMCIA_DEVICE_PROD_ID123(
+               "corega", "WL PCCL-11", "ISL37300P",
+               0xa21501a, 0x59868926, 0xc9049a39),
        PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
index 7f5df9a..3bcb7dc 100644 (file)
@@ -241,12 +241,6 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        csa = at91_sys_read(AT91_EBI_CSA);
        at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
 
-       /* force poweron defaults for these pins ... */
-       (void) at91_set_A_periph(AT91_PIN_PC9, 0);      /* A25/CFRNW */
-       (void) at91_set_A_periph(AT91_PIN_PC10, 0);     /* NCS4/CFCS */
-       (void) at91_set_A_periph(AT91_PIN_PC11, 0);     /* NCS5/CFCE1 */
-       (void) at91_set_A_periph(AT91_PIN_PC12, 0);     /* NCS6/CFCE2 */
-
        /* nWAIT is _not_ a default setting */
        (void) at91_set_A_periph(AT91_PIN_PC6, 1);      /*  nWAIT */
 
@@ -316,12 +310,14 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        return 0;
 
 fail2:
-       iounmap((void __iomem *) cf->socket.io_offset);
        release_mem_region(io->start, io->end + 1 - io->start);
 fail1:
+       if (cf->socket.io_offset)
+               iounmap((void __iomem *) cf->socket.io_offset);
        if (board->irq_pin)
                free_irq(board->irq_pin, cf);
 fail0a:
+       device_init_wakeup(&pdev->dev, 0);
        free_irq(board->det_pin, cf);
        device_init_wakeup(&pdev->dev, 0);
 fail0:
@@ -360,26 +356,20 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
        struct at91_cf_data     *board = cf->board;
 
        pcmcia_socket_dev_suspend(&pdev->dev, mesg);
-       if (device_may_wakeup(&pdev->dev))
+       if (device_may_wakeup(&pdev->dev)) {
                enable_irq_wake(board->det_pin);
-       else {
+               if (board->irq_pin)
+                       enable_irq_wake(board->irq_pin);
+       } else {
                disable_irq_wake(board->det_pin);
-               disable_irq(board->det_pin);
+               if (board->irq_pin)
+                       disable_irq_wake(board->irq_pin);
        }
-       if (board->irq_pin)
-               disable_irq(board->irq_pin);
        return 0;
 }
 
 static int at91_cf_resume(struct platform_device *pdev)
 {
-       struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
-       struct at91_cf_data     *board = cf->board;
-
-       if (board->irq_pin)
-               enable_irq(board->irq_pin);
-       if (!device_may_wakeup(&pdev->dev))
-               enable_irq(board->det_pin);
        pcmcia_socket_dev_resume(&pdev->dev);
        return 0;
 }
index d5dd0ce..551bde5 100644 (file)
@@ -351,6 +351,7 @@ struct skt_dev_info {
 int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
 {
        struct skt_dev_info *sinfo;
+       struct au1000_pcmcia_socket *skt;
        int ret, i;
 
        sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
@@ -365,7 +366,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
         * Initialise the per-socket structure.
         */
        for (i = 0; i < nr; i++) {
-               struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+               skt = PCMCIA_SOCKET(i);
                memset(skt, 0, sizeof(*skt));
 
                skt->socket.resource_ops = &pccard_static_ops;
@@ -438,17 +439,29 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
        dev_set_drvdata(dev, sinfo);
        return 0;
 
-       do {
-               struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+out_err:
+       flush_scheduled_work();
+       ops->hw_shutdown(skt);
+       while (i-- > 0) {
+               skt = PCMCIA_SOCKET(i);
 
                del_timer_sync(&skt->poll_timer);
                pcmcia_unregister_socket(&skt->socket);
-out_err:
                flush_scheduled_work();
+               if (i == 0) {
+                       iounmap(skt->virt_io + (u32)mips_io_port_base);
+                       skt->virt_io = NULL;
+               }
+#ifndef CONFIG_MIPS_XXS1500
+               else {
+                       iounmap(skt->virt_io + (u32)mips_io_port_base);
+                       skt->virt_io = NULL;
+               }
+#endif
                ops->hw_shutdown(skt);
 
-               i--;
-       } while (i > 0);
+       }
        kfree(sinfo);
 out:
        return ret;
index 74b3124..0f70192 100644 (file)
@@ -717,6 +717,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
 static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
 {
        int no_devices=0;
+       int ret = 0;
        unsigned long flags;
 
        /* must be called with skt_mutex held */
@@ -729,7 +730,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
         * missing resource information or other trouble, we need to
         * do this now. */
        if (no_devices) {
-               int ret = pcmcia_card_add(skt);
+               ret = pcmcia_card_add(skt);
                if (ret)
                        return;
        }
@@ -741,7 +742,9 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
 
        /* we re-scan all devices, not just the ones connected to this
         * socket. This does not matter, though. */
-       bus_rescan_devices(&pcmcia_bus_type);
+       ret = bus_rescan_devices(&pcmcia_bus_type);
+       if (ret)
+               printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
 }
 
 static inline int pcmcia_devmatch(struct pcmcia_device *dev,
@@ -1001,6 +1004,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+       int ret;
 
        if (!count)
                return -EINVAL;
@@ -1009,7 +1013,10 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
        p_dev->allow_func_id_match = 1;
        mutex_unlock(&p_dev->socket->skt_mutex);
 
-       bus_rescan_devices(&pcmcia_bus_type);
+       ret = bus_rescan_devices(&pcmcia_bus_type);
+       if (ret)
+               printk(KERN_INFO "pcmcia: bus_rescan_devices failed after "
+                      "allowing func_id matches\n");
 
        return count;
 }
@@ -1292,10 +1299,22 @@ struct bus_type pcmcia_bus_type = {
 
 static int __init init_pcmcia_bus(void)
 {
+       int ret;
+
        spin_lock_init(&pcmcia_dev_list_lock);
 
-       bus_register(&pcmcia_bus_type);
-       class_interface_register(&pcmcia_bus_interface);
+       ret = bus_register(&pcmcia_bus_type);
+       if (ret < 0) {
+               printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
+               return ret;
+       }
+       ret = class_interface_register(&pcmcia_bus_interface);
+       if (ret < 0) {
+               printk(KERN_WARNING
+                       "pcmcia: class_interface_register error: %d\n", ret);
+               bus_unregister(&pcmcia_bus_type);
+               return ret;
+       }
 
        pcmcia_setup_ioctl();
 
index 82715f4..c2ea07a 100644 (file)
@@ -41,6 +41,7 @@ static struct pci_device_id i82092aa_pci_ids[] = {
 };
 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
 
+#ifdef CONFIG_PM
 static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
 {
        return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -50,14 +51,17 @@ static int i82092aa_socket_resume (struct pci_dev *dev)
 {
        return pcmcia_socket_dev_resume(&dev->dev);
 }
+#endif
 
 static struct pci_driver i82092aa_pci_drv = {
        .name           = "i82092aa",
        .id_table       = i82092aa_pci_ids,
        .probe          = i82092aa_pci_probe,
        .remove         = __devexit_p(i82092aa_pci_remove),
+#ifdef CONFIG_PM
        .suspend        = i82092aa_socket_suspend,
        .resume         = i82092aa_socket_resume,
+#endif
 };
 
 
@@ -705,10 +709,7 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_
 
 static int i82092aa_module_init(void)
 {
-       enter("i82092aa_module_init");
-       pci_register_driver(&i82092aa_pci_drv);
-       leave("i82092aa_module_init");
-       return 0;
+       return pci_register_driver(&i82092aa_pci_drv);
 }
 
 static void i82092aa_module_exit(void)
index e070a28..3b72be8 100644 (file)
@@ -427,7 +427,7 @@ static int voltage_set(int slot, int vcc, int vpp)
                        reg |= BCSR1_PCCVCC1;
                        break;
                default:
-                       return 1;
+                       goto out_unmap;
        }
 
        switch(vpp) {
@@ -438,15 +438,15 @@ static int voltage_set(int slot, int vcc, int vpp)
                        if(vcc == vpp)
                                reg |= BCSR1_PCCVPP1;
                        else
-                               return 1;
+                               goto out_unmap;
                        break;
                case 120:
                        if ((vcc == 33) || (vcc == 50))
                                reg |= BCSR1_PCCVPP0;
                        else
-                               return 1;
+                               goto out_unmap;
                default:
-                       return 1;
+                       goto out_unmap;
        }
 
        /* first, turn off all power */
@@ -457,6 +457,10 @@ static int voltage_set(int slot, int vcc, int vpp)
 
        iounmap(bcsr_io);
        return 0;
+
+out_unmap:
+       iounmap(bcsr_io);
+       return 1;
 }
 
 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
index c8e838c..06bf7f4 100644 (file)
@@ -309,9 +309,10 @@ static int __devinit omap_cf_probe(struct device *dev)
        return 0;
 
 fail2:
-       iounmap((void __iomem *) cf->socket.io_offset);
        release_mem_region(cf->phys_cf, SZ_8K);
 fail1:
+       if (cf->socket.io_offset)
+               iounmap((void __iomem *) cf->socket.io_offset);
        free_irq(irq, cf);
 fail0:
        kfree(cf);
index 9ad18e6..310ede5 100644 (file)
@@ -128,9 +128,12 @@ static int proc_read_drivers(char *buf, char **start, off_t pos,
                             int count, int *eof, void *data)
 {
        char *p = buf;
+       int rc;
 
-       bus_for_each_drv(&pcmcia_bus_type, NULL,
-                        (void *) &p, proc_read_drivers_callback);
+       rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
+                             (void *) &p, proc_read_drivers_callback);
+       if (rc < 0)
+               return rc;
 
        return (p - buf);
 }
@@ -269,8 +272,10 @@ rescan:
         * Prevent this racing with a card insertion.
         */
        mutex_lock(&s->skt_mutex);
-       bus_rescan_devices(&pcmcia_bus_type);
+       ret = bus_rescan_devices(&pcmcia_bus_type);
        mutex_unlock(&s->skt_mutex);
+       if (ret)
+               goto err_put_module;
 
        /* check whether the driver indeed matched. I don't care if this
         * is racy or not, because it can only happen on cardmgr access
index 74cebd4..b9201c2 100644 (file)
@@ -95,7 +95,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
         * potential conflicts, just the most obvious ones.
         */
        for (i = 0; i < MAX_IO_WIN; i++)
-               if ((s->io[i].res) &&
+               if ((s->io[i].res) && *base &&
                    ((s->io[i].res->start & (align-1)) == *base))
                        return 1;
        for (i = 0; i < MAX_IO_WIN; i++) {
index c83a0a6..a70f97f 100644 (file)
@@ -755,6 +755,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
        kfree(socket);
 }
 
+#ifdef CONFIG_PM
 static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
 {
        return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -764,6 +765,7 @@ static int pd6729_socket_resume(struct pci_dev *dev)
 {
        return pcmcia_socket_dev_resume(&dev->dev);
 }
+#endif
 
 static struct pci_device_id pd6729_pci_ids[] = {
        {
@@ -781,8 +783,10 @@ static struct pci_driver pd6729_pci_drv = {
        .id_table       = pd6729_pci_ids,
        .probe          = pd6729_pci_probe,
        .remove         = __devexit_p(pd6729_pci_remove),
+#ifdef CONFIG_PM
        .suspend        = pd6729_socket_suspend,
        .resume         = pd6729_socket_resume,
+#endif
 };
 
 static int pd6729_module_init(void)
index 3627e52..e433704 100644 (file)
@@ -824,3 +824,4 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
 
        return 0;
 }
+EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
index 26229d9..da471bd 100644 (file)
@@ -1197,8 +1197,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
        ret = pcmcia_register_socket(&socket->socket);
        if (ret == 0) {
                /* Add the yenta register attributes */
-               device_create_file(&dev->dev, &dev_attr_yenta_registers);
-               goto out;
+               ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
+               if (ret == 0)
+                       goto out;
+
+               /* error path... */
+               pcmcia_unregister_socket(&socket->socket);
        }
 
  unmap:
@@ -1213,7 +1217,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
        return ret;
 }
 
-
+#ifdef CONFIG_PM
 static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
 {
        struct yenta_socket *socket = pci_get_drvdata(dev);
@@ -1248,12 +1252,18 @@ static int yenta_dev_resume (struct pci_dev *dev)
        struct yenta_socket *socket = pci_get_drvdata(dev);
 
        if (socket) {
+               int rc;
+
                pci_set_power_state(dev, 0);
                /* FIXME: pci_restore_state needs to have a better interface */
                pci_restore_state(dev);
                pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
                pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
-               pci_enable_device(dev);
+
+               rc = pci_enable_device(dev);
+               if (rc)
+                       return rc;
+
                pci_set_master(dev);
 
                if (socket->type && socket->type->restore_state)
@@ -1262,7 +1272,7 @@ static int yenta_dev_resume (struct pci_dev *dev)
 
        return pcmcia_socket_dev_resume(&dev->dev);
 }
-
+#endif
 
 #define CB_ID(vend,dev,type)                           \
        {                                               \
@@ -1359,8 +1369,10 @@ static struct pci_driver yenta_cardbus_driver = {
        .id_table       = yenta_table,
        .probe          = yenta_probe,
        .remove         = __devexit_p(yenta_close),
+#ifdef CONFIG_PM
        .suspend        = yenta_dev_suspend,
        .resume         = yenta_dev_resume,
+#endif
 };
 
 
index a2dee5b..ad7f7e1 100644 (file)
@@ -271,10 +271,6 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
                /* Reset intparm to zeroes. */
                sch->schib.pmcw.intparm = 0;
                cio_modify(sch);
-
-               /* Probe if necessary. */
-               if (action == UNREGISTER_PROBE)
-                       ret = css_probe_device(sch->schid);
                break;
        case REPROBE:
                device_trigger_reprobe(sch);
@@ -283,6 +279,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
                break;
        }
        spin_unlock_irqrestore(&sch->lock, flags);
+       /* Probe if necessary. */
+       if (action == UNREGISTER_PROBE)
+               ret = css_probe_device(sch->schid);
 
        return ret;
 }
index 94bdd4d..39c98f9 100644 (file)
@@ -532,8 +532,7 @@ device_remove_files(struct device *dev)
 
 /* this is a simple abstraction for device_register that sets the
  * correct bus type and adds the bus specific files */
-int
-ccw_device_register(struct ccw_device *cdev)
+static int ccw_device_register(struct ccw_device *cdev)
 {
        struct device *dev = &cdev->dev;
        int ret;
index c6140cc..9233b5c 100644 (file)
@@ -78,7 +78,6 @@ void io_subchannel_recog_done(struct ccw_device *cdev);
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-int ccw_device_register(struct ccw_device *);
 void ccw_device_do_unreg_rereg(void *);
 void ccw_device_call_sch_unregister(void *);
 
index c5ccd20..79d89c3 100644 (file)
@@ -739,11 +739,16 @@ static void ap_scan_bus(void *data)
                dev = bus_find_device(&ap_bus_type, NULL,
                                      (void *)(unsigned long)qid,
                                      __ap_scan_bus);
+               rc = ap_query_queue(qid, &queue_depth, &device_type);
+               if (dev && rc) {
+                       put_device(dev);
+                       device_unregister(dev);
+                       continue;
+               }
                if (dev) {
                        put_device(dev);
                        continue;
                }
-               rc = ap_query_queue(qid, &queue_depth, &device_type);
                if (rc)
                        continue;
                rc = ap_init_queue(qid);
index bc8f27c..702b88c 100644 (file)
@@ -1131,6 +1131,8 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        filp->f_flags |= O_LARGEFILE;
 
        bdev = bd_acquire(inode);
+       if (bdev == NULL)
+               return -ENOMEM;
 
        res = do_open(bdev, filp, BD_MUTEX_NORMAL);
        if (res)
index a1ff91e..fd4a428 100644 (file)
@@ -478,11 +478,12 @@ static void prune_dcache(int count, struct super_block *sb)
                        up_read(s_umount);
                }
                spin_unlock(&dentry->d_lock);
-               /* Cannot remove the first dentry, and it isn't appropriate
-                * to move it to the head of the list, so give up, and try
-                * later
+               /*
+                * Insert dentry at the head of the list as inserting at the
+                * tail leads to a cycle.
                 */
-               break;
+               list_add(&dentry->d_lru, &dentry_unused);
+               dentry_stat.nr_unused++;
        }
        spin_unlock(&dcache_lock);
 }
@@ -556,6 +557,7 @@ repeat:
 static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 {
        struct dentry *parent;
+       unsigned detached = 0;
 
        BUG_ON(!IS_ROOT(dentry));
 
@@ -620,7 +622,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                                atomic_dec(&parent->d_count);
 
                        list_del(&dentry->d_u.d_child);
-                       dentry_stat.nr_dentry--;        /* For d_free, below */
+                       detached++;
 
                        inode = dentry->d_inode;
                        if (inode) {
@@ -638,7 +640,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                         * otherwise we ascend to the parent and move to the
                         * next sibling if there is one */
                        if (!parent)
-                               return;
+                               goto out;
 
                        dentry = parent;
 
@@ -647,6 +649,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                dentry = list_entry(dentry->d_subdirs.next,
                                    struct dentry, d_u.d_child);
        }
+out:
+       /* several dentries were freed, need to correct nr_dentry */
+       spin_lock(&dcache_lock);
+       dentry_stat.nr_dentry -= detached;
+       spin_unlock(&dcache_lock);
 }
 
 /*
index 1e95780..4fe49c3 100644 (file)
@@ -69,44 +69,49 @@ static int verify_group_input(struct super_block *sb,
        else if (outside(input->block_bitmap, start, end))
                ext4_warning(sb, __FUNCTION__,
                             "Block bitmap not in group (block %llu)",
-                            input->block_bitmap);
+                            (unsigned long long)input->block_bitmap);
        else if (outside(input->inode_bitmap, start, end))
                ext4_warning(sb, __FUNCTION__,
                             "Inode bitmap not in group (block %llu)",
-                            input->inode_bitmap);
+                            (unsigned long long)input->inode_bitmap);
        else if (outside(input->inode_table, start, end) ||
                 outside(itend - 1, start, end))
                ext4_warning(sb, __FUNCTION__,
                             "Inode table not in group (blocks %llu-%llu)",
-                            input->inode_table, itend - 1);
+                            (unsigned long long)input->inode_table, itend - 1);
        else if (input->inode_bitmap == input->block_bitmap)
                ext4_warning(sb, __FUNCTION__,
                             "Block bitmap same as inode bitmap (%llu)",
-                            input->block_bitmap);
+                            (unsigned long long)input->block_bitmap);
        else if (inside(input->block_bitmap, input->inode_table, itend))
                ext4_warning(sb, __FUNCTION__,
                             "Block bitmap (%llu) in inode table (%llu-%llu)",
-                            input->block_bitmap, input->inode_table, itend-1);
+                            (unsigned long long)input->block_bitmap,
+                            (unsigned long long)input->inode_table, itend - 1);
        else if (inside(input->inode_bitmap, input->inode_table, itend))
                ext4_warning(sb, __FUNCTION__,
                             "Inode bitmap (%llu) in inode table (%llu-%llu)",
-                            input->inode_bitmap, input->inode_table, itend-1);
+                            (unsigned long long)input->inode_bitmap,
+                            (unsigned long long)input->inode_table, itend - 1);
        else if (inside(input->block_bitmap, start, metaend))
                ext4_warning(sb, __FUNCTION__,
                             "Block bitmap (%llu) in GDT table"
                             " (%llu-%llu)",
-                            input->block_bitmap, start, metaend - 1);
+                            (unsigned long long)input->block_bitmap,
+                            start, metaend - 1);
        else if (inside(input->inode_bitmap, start, metaend))
                ext4_warning(sb, __FUNCTION__,
                             "Inode bitmap (%llu) in GDT table"
                             " (%llu-%llu)",
-                            input->inode_bitmap, start, metaend - 1);
+                            (unsigned long long)input->inode_bitmap,
+                            start, metaend - 1);
        else if (inside(input->inode_table, start, metaend) ||
                 inside(itend - 1, start, metaend))
                ext4_warning(sb, __FUNCTION__,
                             "Inode table (%llu-%llu) overlaps"
                             "GDT table (%llu-%llu)",
-                            input->inode_table, itend - 1, start, metaend - 1);
+                            (unsigned long long)input->inode_table,
+                            itend - 1, start, metaend - 1);
        else
                err = 0;
        brelse(bh);
index 4ee3f00..0bea6a6 100644 (file)
@@ -271,26 +271,24 @@ static void hugetlbfs_drop_inode(struct inode *inode)
                hugetlbfs_forget_inode(inode);
 }
 
-/*
- * h_pgoff is in HPAGE_SIZE units.
- * vma->vm_pgoff is in PAGE_SIZE units.
- */
 static inline void
-hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
+hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
 {
        struct vm_area_struct *vma;
        struct prio_tree_iter iter;
 
-       vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
-               unsigned long h_vm_pgoff;
+       vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
                unsigned long v_offset;
 
-               h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
-               v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT;
                /*
-                * Is this VMA fully outside the truncation point?
+                * Can the expression below overflow on 32-bit arches?
+                * No, because the prio_tree returns us only those vmas
+                * which overlap the truncated area starting at pgoff,
+                * and no vma on a 32-bit arch can span beyond the 4GB.
                 */
-               if (h_vm_pgoff >= h_pgoff)
+               if (vma->vm_pgoff < pgoff)
+                       v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT;
+               else
                        v_offset = 0;
 
                __unmap_hugepage_range(vma,
@@ -303,14 +301,14 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
  */
 static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
 {
-       unsigned long pgoff;
+       pgoff_t pgoff;
        struct address_space *mapping = inode->i_mapping;
 
        if (offset > inode->i_size)
                return -EINVAL;
 
        BUG_ON(offset & ~HPAGE_MASK);
-       pgoff = offset >> HPAGE_SHIFT;
+       pgoff = offset >> PAGE_SHIFT;
 
        inode->i_size = offset;
        spin_lock(&mapping->i_mmap_lock);
@@ -624,7 +622,6 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
                                do_div(size, 100);
                                rest++;
                        }
-                       size &= HPAGE_MASK;
                        pconfig->nr_blocks = (size >> HPAGE_SHIFT);
                        value = rest;
                } else if (!strcmp(opt,"nr_inodes")) {
index d5c6304..4f82bcd 100644 (file)
@@ -967,6 +967,13 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
         */
        jbd_lock_bh_state(bh);
        spin_lock(&journal->j_list_lock);
+
+       /* Now that we have bh_state locked, are we really still mapped? */
+       if (!buffer_mapped(bh)) {
+               JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+               goto no_journal;
+       }
+
        if (jh->b_transaction) {
                JBUFFER_TRACE(jh, "has transaction");
                if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
                                sync_dirty_buffer(bh);
                                jbd_lock_bh_state(bh);
                                spin_lock(&journal->j_list_lock);
+                               /* Since we dropped the lock... */
+                               if (!buffer_mapped(bh)) {
+                                       JBUFFER_TRACE(jh, "buffer got unmapped");
+                                       goto no_journal;
+                               }
                                /* The buffer may become locked again at any
                                   time if it is redirtied */
                        }
@@ -1824,6 +1836,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                        }
                }
        } else if (transaction == journal->j_committing_transaction) {
+               JBUFFER_TRACE(jh, "on committing transaction");
                if (jh->b_jlist == BJ_Locked) {
                        /*
                         * The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                 * can remove it's next_transaction pointer from the
                 * running transaction if that is set, but nothing
                 * else. */
-               JBUFFER_TRACE(jh, "on committing transaction");
                set_buffer_freed(bh);
                if (jh->b_next_transaction) {
                        J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                 * i_size already for this truncate so recovery will not
                 * expose the disk blocks we are discarding here.) */
                J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+               JBUFFER_TRACE(jh, "on running transaction");
                may_free = __dispose_buffer(jh, transaction);
        }
 
index b6cf2be..c051a94 100644 (file)
@@ -967,6 +967,13 @@ int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
         */
        jbd_lock_bh_state(bh);
        spin_lock(&journal->j_list_lock);
+
+       /* Now that we have bh_state locked, are we really still mapped? */
+       if (!buffer_mapped(bh)) {
+               JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+               goto no_journal;
+       }
+
        if (jh->b_transaction) {
                JBUFFER_TRACE(jh, "has transaction");
                if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@ int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
                                sync_dirty_buffer(bh);
                                jbd_lock_bh_state(bh);
                                spin_lock(&journal->j_list_lock);
+                               /* Since we dropped the lock... */
+                               if (!buffer_mapped(bh)) {
+                                       JBUFFER_TRACE(jh, "buffer got unmapped");
+                                       goto no_journal;
+                               }
                                /* The buffer may become locked again at any
                                   time if it is redirtied */
                        }
@@ -1824,6 +1836,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                        }
                }
        } else if (transaction == journal->j_committing_transaction) {
+               JBUFFER_TRACE(jh, "on committing transaction");
                if (jh->b_jlist == BJ_Locked) {
                        /*
                         * The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                 * can remove it's next_transaction pointer from the
                 * running transaction if that is set, but nothing
                 * else. */
-               JBUFFER_TRACE(jh, "on committing transaction");
                set_buffer_freed(bh);
                if (jh->b_next_transaction) {
                        J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
                 * i_size already for this truncate so recovery will not
                 * expose the disk blocks we are discarding here.) */
                J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+               JBUFFER_TRACE(jh, "on running transaction");
                may_free = __dispose_buffer(jh, transaction);
        }
 
index 49fb9f1..8d70595 100644 (file)
@@ -74,7 +74,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
                wait_on_page_writeback(page);
 
                if (PagePrivate(page))
-                       try_to_release_page(page, mapping_gfp_mask(mapping));
+                       try_to_release_page(page, GFP_KERNEL);
 
                /*
                 * If we succeeded in removing the mapping, set LRU flag
@@ -333,7 +333,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                                break;
 
                        error = add_to_page_cache_lru(page, mapping, index,
-                                             mapping_gfp_mask(mapping));
+                                             GFP_KERNEL);
                        if (unlikely(error)) {
                                page_cache_release(page);
                                if (error == -EEXIST)
@@ -557,7 +557,6 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 {
        struct file *file = sd->file;
        struct address_space *mapping = file->f_mapping;
-       gfp_t gfp_mask = mapping_gfp_mask(mapping);
        unsigned int offset, this_len;
        struct page *page;
        pgoff_t index;
@@ -591,7 +590,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
                        goto find_page;
 
                page = buf->page;
-               if (add_to_page_cache(page, mapping, index, gfp_mask)) {
+               if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
                        unlock_page(page);
                        goto find_page;
                }
@@ -613,7 +612,7 @@ find_page:
                         * This will also lock the page
                         */
                        ret = add_to_page_cache_lru(page, mapping, index,
-                                                   gfp_mask);
+                                                   GFP_KERNEL);
                        if (unlikely(ret))
                                goto out;
                }
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
deleted file mode 100644 (file)
index 21cd696..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* defines for inline arch setup functions */
-
-#include <asm/fixmap.h>
-#include <asm/i8259.h>
-#include "cobalt.h"
-
-static inline void do_timer_interrupt_hook(void)
-{
-       /* Clear the interrupt */
-       co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
-
-       do_timer(1);
-#ifndef CONFIG_SMP
-       update_process_times(user_mode_vm(irq_regs));
-#endif
-/*
- * In the SMP case we use the local APIC timer interrupt to do the
- * profiling, except when we simulate SMP mode on a uniprocessor
- * system, in that case we have to call the local interrupt handler.
- */
-#ifndef CONFIG_X86_LOCAL_APIC
-       profile_tick(CPU_PROFILING);
-#else
-       if (!using_apic_timer)
-               smp_local_timer_interrupt();
-#endif
-}
-
-static inline int do_timer_overflow(int count)
-{
-       int i;
-
-       spin_lock(&i8259A_lock);
-       /*
-        * This is tricky when I/O APICs are used;
-        * see do_timer_interrupt().
-        */
-       i = inb(0x20);
-       spin_unlock(&i8259A_lock);
-       
-       /* assumption about timer being IRQ0 */
-       if (i & 0x01) {
-               /*
-                * We cannot detect lost timer interrupts ... 
-                * well, that's why we call them lost, don't we? :)
-                * [hmm, on the Pentium and Alpha we can ... sort of]
-                */
-               count -= LATCH;
-       } else {
-               printk("do_slow_gettimeoffset(): hardware timer problem?\n");
-       }
-       return count;
-}
index de438c7..18afe6b 100644 (file)
@@ -51,6 +51,11 @@ static inline void clustered_apic_check(void)
 {
 }
 
+static inline int apicid_to_node(int logical_apicid)
+{
+       return 0;
+}
+
 /* Mapping from cpu number to logical apicid */
 static inline int cpu_to_logical_apicid(int cpu)
 {
index f4ebf96..f155319 100644 (file)
@@ -196,7 +196,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
 #define BITS_TO_COMPAT_LONGS(bits) \
        (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG)
 
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
                       unsigned long bitmap_size);
 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
                       unsigned long bitmap_size);
index ed0762b..e06683e 100644 (file)
@@ -218,13 +218,9 @@ struct zone {
         * under - it drives the swappiness decision: whether to unmap mapped
         * pages.
         *
-        * temp_priority is used to remember the scanning priority at which
-        * this zone was successfully refilled to free_pages == pages_high.
-        *
-        * Access to both these fields is quite racy even on uniprocessor.  But
+        * Access to both this field is quite racy even on uniprocessor.  But
         * it is expected to average out OK.
         */
-       int temp_priority;
        int prev_priority;
 
 
index 64f9509..c3e255b 100644 (file)
@@ -52,19 +52,23 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
 void release_pages(struct page **pages, int nr, int cold);
 
 #ifdef CONFIG_NUMA
-extern struct page *page_cache_alloc(struct address_space *x);
-extern struct page *page_cache_alloc_cold(struct address_space *x);
+extern struct page *__page_cache_alloc(gfp_t gfp);
 #else
+static inline struct page *__page_cache_alloc(gfp_t gfp)
+{
+       return alloc_pages(gfp, 0);
+}
+#endif
+
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
-       return alloc_pages(mapping_gfp_mask(x), 0);
+       return __page_cache_alloc(mapping_gfp_mask(x));
 }
 
 static inline struct page *page_cache_alloc_cold(struct address_space *x)
 {
-       return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
+       return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
 }
-#endif
 
 typedef int filler_t(void *, struct page *);
 
index 6735c1c..eafe4a7 100644 (file)
@@ -466,7 +466,6 @@ struct signal_struct {
        struct pacct_struct pacct;      /* per-process accounting information */
 #endif
 #ifdef CONFIG_TASKSTATS
-       spinlock_t stats_lock;
        struct taskstats *stats;
 #endif
 };
index 16894b7..6562a20 100644 (file)
@@ -23,25 +23,26 @@ static inline void taskstats_exit_free(struct taskstats *tidstats)
 
 static inline void taskstats_tgid_init(struct signal_struct *sig)
 {
-       spin_lock_init(&sig->stats_lock);
        sig->stats = NULL;
 }
 
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
 {
+       struct signal_struct *sig = tsk->signal;
        struct taskstats *stats;
-       unsigned long flags;
 
-       stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
-       if (!stats)
+       if (sig->stats != NULL)
                return;
 
-       spin_lock_irqsave(&sig->stats_lock, flags);
+       /* No problem if kmem_cache_zalloc() fails */
+       stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+
+       spin_lock_irq(&tsk->sighand->siglock);
        if (!sig->stats) {
                sig->stats = stats;
                stats = NULL;
        }
-       spin_unlock_irqrestore(&sig->stats_lock, flags);
+       spin_unlock_irq(&tsk->sighand->siglock);
 
        if (stats)
                kmem_cache_free(taskstats_cache, stats);
@@ -49,23 +50,13 @@ static inline void taskstats_tgid_alloc(struct signal_struct *sig)
 
 static inline void taskstats_tgid_free(struct signal_struct *sig)
 {
-       struct taskstats *stats = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sig->stats_lock, flags);
-       if (sig->stats) {
-               stats = sig->stats;
-               sig->stats = NULL;
-       }
-       spin_unlock_irqrestore(&sig->stats_lock, flags);
-       if (stats)
-               kmem_cache_free(taskstats_cache, stats);
+       if (sig->stats)
+               kmem_cache_free(taskstats_cache, sig->stats);
 }
 
 extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
 extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
 extern void taskstats_init_early(void);
-extern void taskstats_tgid_alloc(struct signal_struct *);
 #else
 static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
 {}
@@ -77,7 +68,7 @@ static inline void taskstats_exit_send(struct task_struct *tsk,
 {}
 static inline void taskstats_tgid_init(struct signal_struct *sig)
 {}
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
 {}
 static inline void taskstats_tgid_free(struct signal_struct *sig)
 {}
index ce5f148..dc9a29d 100644 (file)
@@ -60,7 +60,8 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
 extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                        unsigned long start, unsigned long end);
 extern struct vm_struct *get_vm_area_node(unsigned long size,
-                                       unsigned long flags, int node);
+                                         unsigned long flags, int node,
+                                         gfp_t gfp_mask);
 extern struct vm_struct *remove_vm_area(void *addr);
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
                        struct page ***pages);
index 75573e5..d4898aa 100644 (file)
@@ -678,7 +678,7 @@ int get_compat_sigevent(struct sigevent *event,
                ? -EFAULT : 0;
 }
 
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
                       unsigned long bitmap_size)
 {
        int i, j;
index 27dd3ee..663c920 100644 (file)
@@ -150,18 +150,18 @@ static int _cpu_down(unsigned int cpu)
        p = __stop_machine_run(take_cpu_down, NULL, cpu);
        mutex_unlock(&cpu_bitmask_lock);
 
-       if (IS_ERR(p)) {
+       if (IS_ERR(p) || cpu_online(cpu)) {
                /* CPU didn't die: tell everyone.  Can't complain. */
                if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
                                (void *)(long)cpu) == NOTIFY_BAD)
                        BUG();
 
-               err = PTR_ERR(p);
-               goto out_allowed;
-       }
-
-       if (cpu_online(cpu))
+               if (IS_ERR(p)) {
+                       err = PTR_ERR(p);
+                       goto out_allowed;
+               }
                goto out_thread;
+       }
 
        /* Wait for it to sleep (leaving idle task). */
        while (!idle_cpu(cpu))
index f250a5e..06de6c4 100644 (file)
@@ -128,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk)
        flush_sigqueue(&tsk->pending);
        if (sig) {
                flush_sigqueue(&sig->shared_pending);
+               taskstats_tgid_free(sig);
                __cleanup_signal(sig);
        }
 }
index 29ebb30..3da978e 100644 (file)
@@ -830,7 +830,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
        if (clone_flags & CLONE_THREAD) {
                atomic_inc(&current->signal->count);
                atomic_inc(&current->signal->live);
-               taskstats_tgid_alloc(current->signal);
+               taskstats_tgid_alloc(current);
                return 0;
        }
        sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
@@ -897,7 +897,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
 void __cleanup_signal(struct signal_struct *sig)
 {
        exit_thread_group_keys(sig);
-       taskstats_tgid_free(sig);
        kmem_cache_free(signal_cachep, sig);
 }
 
index 67009bd..5072a94 100644 (file)
@@ -1342,7 +1342,7 @@ static void set_license(struct module *mod, const char *license)
 
        if (!license_is_gpl_compatible(license)) {
                if (!(tainted & TAINT_PROPRIETARY_MODULE))
-                       printk(KERN_WARNING "%s: module license '%s' taints"
+                       printk(KERN_WARNING "%s: module license '%s' taints "
                                "kernel.\n", mod->name, license);
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
        }
index 5d6a8c5..2039585 100644 (file)
@@ -77,7 +77,8 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
        /*
         * If new attributes are added, please revisit this allocation
         */
-       skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
+       size = nlmsg_total_size(genlmsg_total_size(size));
+       skb = nlmsg_new(size, GFP_KERNEL);
        if (!skb)
                return -ENOMEM;
 
@@ -174,21 +175,19 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
        up_write(&listeners->sem);
 }
 
-static int fill_pid(pid_t pid, struct task_struct *pidtsk,
+static int fill_pid(pid_t pid, struct task_struct *tsk,
                struct taskstats *stats)
 {
        int rc = 0;
-       struct task_struct *tsk = pidtsk;
 
-       if (!pidtsk) {
-               read_lock(&tasklist_lock);
+       if (!tsk) {
+               rcu_read_lock();
                tsk = find_task_by_pid(pid);
-               if (!tsk) {
-                       read_unlock(&tasklist_lock);
+               if (tsk)
+                       get_task_struct(tsk);
+               rcu_read_unlock();
+               if (!tsk)
                        return -ESRCH;
-               }
-               get_task_struct(tsk);
-               read_unlock(&tasklist_lock);
        } else
                get_task_struct(tsk);
 
@@ -214,39 +213,30 @@ static int fill_pid(pid_t pid, struct task_struct *pidtsk,
 
 }
 
-static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+static int fill_tgid(pid_t tgid, struct task_struct *first,
                struct taskstats *stats)
 {
-       struct task_struct *tsk, *first;
+       struct task_struct *tsk;
        unsigned long flags;
+       int rc = -ESRCH;
 
        /*
         * Add additional stats from live tasks except zombie thread group
         * leaders who are already counted with the dead tasks
         */
-       first = tgidtsk;
-       if (!first) {
-               read_lock(&tasklist_lock);
+       rcu_read_lock();
+       if (!first)
                first = find_task_by_pid(tgid);
-               if (!first) {
-                       read_unlock(&tasklist_lock);
-                       return -ESRCH;
-               }
-               get_task_struct(first);
-               read_unlock(&tasklist_lock);
-       } else
-               get_task_struct(first);
 
-       /* Start with stats from dead tasks */
-       spin_lock_irqsave(&first->signal->stats_lock, flags);
+       if (!first || !lock_task_sighand(first, &flags))
+               goto out;
+
        if (first->signal->stats)
                memcpy(stats, first->signal->stats, sizeof(*stats));
-       spin_unlock_irqrestore(&first->signal->stats_lock, flags);
 
        tsk = first;
-       read_lock(&tasklist_lock);
        do {
-               if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+               if (tsk->exit_state)
                        continue;
                /*
                 * Accounting subsystem can call its functions here to
@@ -257,15 +247,18 @@ static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
                delayacct_add_tsk(stats, tsk);
 
        } while_each_thread(first, tsk);
-       read_unlock(&tasklist_lock);
-       stats->version = TASKSTATS_VERSION;
 
+       unlock_task_sighand(first, &flags);
+       rc = 0;
+out:
+       rcu_read_unlock();
+
+       stats->version = TASKSTATS_VERSION;
        /*
         * Accounting subsytems can also add calls here to modify
         * fields of taskstats.
         */
-
-       return 0;
+       return rc;
 }
 
 
@@ -273,7 +266,7 @@ static void fill_tgid_exit(struct task_struct *tsk)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+       spin_lock_irqsave(&tsk->sighand->siglock, flags);
        if (!tsk->signal->stats)
                goto ret;
 
@@ -285,7 +278,7 @@ static void fill_tgid_exit(struct task_struct *tsk)
         */
        delayacct_add_tsk(tsk->signal->stats, tsk);
 ret:
-       spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+       spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
        return;
 }
 
@@ -419,7 +412,7 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
        return send_reply(rep_skb, info->snd_pid);
 
 nla_put_failure:
-       return genlmsg_cancel(rep_skb, reply);
+       rc = genlmsg_cancel(rep_skb, reply);
 err:
        nlmsg_free(rep_skb);
        return rc;
@@ -461,15 +454,10 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
        size_t size;
        int is_thread_group;
        struct nlattr *na;
-       unsigned long flags;
 
        if (!family_registered || !tidstats)
                return;
 
-       spin_lock_irqsave(&tsk->signal->stats_lock, flags);
-       is_thread_group = tsk->signal->stats ? 1 : 0;
-       spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
-
        rc = 0;
        /*
         * Size includes space for nested attributes
@@ -477,6 +465,7 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
        size = nla_total_size(sizeof(u32)) +
                nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
 
+       is_thread_group = (tsk->signal->stats != NULL);
        if (is_thread_group)
                size = 2 * size;        /* PID + STATS + TGID + STATS */
 
@@ -519,7 +508,6 @@ send:
 
 nla_put_failure:
        genlmsg_cancel(rep_skb, reply);
-       goto ret;
 err_skb:
        nlmsg_free(rep_skb);
 ret:
index 47195fa..3afeaa3 100644 (file)
@@ -161,9 +161,9 @@ void second_overflow(void)
                        time_adjust += MAX_TICKADJ;
                        tick_length -= MAX_TICKADJ_SCALED;
                } else {
-                       time_adjust = 0;
                        tick_length += (s64)(time_adjust * NSEC_PER_USEC /
                                             HZ) << TICK_LENGTH_SHIFT;
+                       time_adjust = 0;
                }
        }
 }
index db44322..65a5036 100644 (file)
@@ -36,7 +36,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
 
        /* calculate task elapsed time in timespec */
        do_posix_clock_monotonic_gettime(&uptime);
-       ts = timespec_sub(uptime, current->group_leader->start_time);
+       ts = timespec_sub(uptime, tsk->start_time);
        /* rebase elapsed time to usec */
        ac_etime = timespec_to_ns(&ts);
        do_div(ac_etime, NSEC_PER_USEC);
@@ -58,7 +58,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
        stats->ac_uid    = tsk->uid;
        stats->ac_gid    = tsk->gid;
        stats->ac_pid    = tsk->pid;
-       stats->ac_ppid   = (tsk->parent) ? tsk->parent->pid : 0;
+       rcu_read_lock();
+       stats->ac_ppid   = pid_alive(tsk) ?
+                               rcu_dereference(tsk->real_parent)->tgid : 0;
+       rcu_read_unlock();
        stats->ac_utime  = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
        stats->ac_stime  = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
        stats->ac_minflt = tsk->min_flt;
index 3df9bfc..17c2f03 100644 (file)
@@ -99,7 +99,7 @@ static void __queue_work(struct cpu_workqueue_struct *cwq,
  * @wq: workqueue to use
  * @work: work to queue
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  *
  * We queue the work to the CPU it was submitted, but there is no
  * guarantee that it will be processed by that CPU.
@@ -138,7 +138,7 @@ static void delayed_work_timer_fn(unsigned long __data)
  * @work: work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  */
 int fastcall queue_delayed_work(struct workqueue_struct *wq,
                        struct work_struct *work, unsigned long delay)
@@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(queue_delayed_work);
  * @work: work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  */
 int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
                        struct work_struct *work, unsigned long delay)
index 6307726..a485d75 100644 (file)
@@ -320,7 +320,7 @@ char *strstrip(char *s)
                return s;
 
        end = s + size - 1;
-       while (end != s && isspace(*end))
+       while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';
 
index cb26e33..7b84dc8 100644 (file)
@@ -467,25 +467,15 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
 }
 
 #ifdef CONFIG_NUMA
-struct page *page_cache_alloc(struct address_space *x)
+struct page *__page_cache_alloc(gfp_t gfp)
 {
        if (cpuset_do_page_mem_spread()) {
                int n = cpuset_mem_spread_node();
-               return alloc_pages_node(n, mapping_gfp_mask(x), 0);
+               return alloc_pages_node(n, gfp, 0);
        }
-       return alloc_pages(mapping_gfp_mask(x), 0);
+       return alloc_pages(gfp, 0);
 }
-EXPORT_SYMBOL(page_cache_alloc);
-
-struct page *page_cache_alloc_cold(struct address_space *x)
-{
-       if (cpuset_do_page_mem_spread()) {
-               int n = cpuset_mem_spread_node();
-               return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0);
-       }
-       return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
-}
-EXPORT_SYMBOL(page_cache_alloc_cold);
+EXPORT_SYMBOL(__page_cache_alloc);
 #endif
 
 static int __sleep_on_page_lock(void *word)
@@ -826,7 +816,6 @@ struct page *
 grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
 {
        struct page *page = find_get_page(mapping, index);
-       gfp_t gfp_mask;
 
        if (page) {
                if (!TestSetPageLocked(page))
@@ -834,9 +823,8 @@ grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
                page_cache_release(page);
                return NULL;
        }
-       gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS;
-       page = alloc_pages(gfp_mask, 0);
-       if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) {
+       page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS);
+       if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) {
                page_cache_release(page);
                page = NULL;
        }
index 2dbec90..a088f59 100644 (file)
@@ -478,6 +478,9 @@ int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 retry:
        page = find_lock_page(mapping, idx);
        if (!page) {
+               size = i_size_read(mapping->host) >> HPAGE_SHIFT;
+               if (idx >= size)
+                       goto out;
                if (hugetlb_get_quota(mapping))
                        goto out;
                page = alloc_huge_page(vma, address);
index f5fc454..b55bb35 100644 (file)
@@ -2261,7 +2261,7 @@ unsigned long __init __absent_pages_in_range(int nid,
 
        /* Account for ranges past physical memory on this node */
        if (range_end_pfn > prev_end_pfn)
-               hole_pages = range_end_pfn -
+               hole_pages += range_end_pfn -
                                max(range_start_pfn, prev_end_pfn);
 
        return hole_pages;
@@ -2407,7 +2407,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
                zone->zone_pgdat = pgdat;
                zone->free_pages = 0;
 
-               zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
+               zone->prev_priority = DEF_PRIORITY;
 
                zone_pcp_init(zone);
                INIT_LIST_HEAD(&zone->active_list);
index 86c52ab..b3c82ba 100644 (file)
@@ -211,7 +211,7 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
        struct page *page, *ret;
        unsigned long memmap_size = sizeof(struct page) * nr_pages;
 
-       page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
+       page = alloc_pages(GFP_KERNEL|__GFP_NOWARN, get_order(memmap_size));
        if (page)
                goto got_map_page;
 
index 1133dd3..46606c1 100644 (file)
@@ -160,13 +160,15 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
        return err;
 }
 
-struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
-                               unsigned long start, unsigned long end, int node)
+static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
+                                           unsigned long start, unsigned long end,
+                                           int node, gfp_t gfp_mask)
 {
        struct vm_struct **p, *tmp, *area;
        unsigned long align = 1;
        unsigned long addr;
 
+       BUG_ON(in_interrupt());
        if (flags & VM_IOREMAP) {
                int bit = fls(size);
 
@@ -180,7 +182,7 @@ struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
        addr = ALIGN(start, align);
        size = PAGE_ALIGN(size);
 
-       area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
+       area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);
        if (unlikely(!area))
                return NULL;
 
@@ -236,7 +238,7 @@ out:
 struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                unsigned long start, unsigned long end)
 {
-       return __get_vm_area_node(size, flags, start, end, -1);
+       return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL);
 }
 
 /**
@@ -253,9 +255,11 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
        return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
 }
 
-struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
+struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
+                                  int node, gfp_t gfp_mask)
 {
-       return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
+       return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node,
+                                 gfp_mask);
 }
 
 /* Caller must hold vmlist_lock */
@@ -487,7 +491,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
        if (!size || (size >> PAGE_SHIFT) > num_physpages)
                return NULL;
 
-       area = get_vm_area_node(size, VM_ALLOC, node);
+       area = get_vm_area_node(size, VM_ALLOC, node, gfp_mask);
        if (!area)
                return NULL;
 
index f05527b..518540a 100644 (file)
@@ -723,6 +723,20 @@ done:
        return nr_reclaimed;
 }
 
+/*
+ * We are about to scan this zone at a certain priority level.  If that priority
+ * level is smaller (ie: more urgent) than the previous priority, then note
+ * that priority level within the zone.  This is done so that when the next
+ * process comes in to scan this zone, it will immediately start out at this
+ * priority level rather than having to build up its own scanning priority.
+ * Here, this priority affects only the reclaim-mapped threshold.
+ */
+static inline void note_zone_scanning_priority(struct zone *zone, int priority)
+{
+       if (priority < zone->prev_priority)
+               zone->prev_priority = priority;
+}
+
 static inline int zone_is_near_oom(struct zone *zone)
 {
        return zone->pages_scanned >= (zone->nr_active + zone->nr_inactive)*3;
@@ -746,7 +760,7 @@ static inline int zone_is_near_oom(struct zone *zone)
  * But we had to alter page->flags anyway.
  */
 static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
-                               struct scan_control *sc)
+                               struct scan_control *sc, int priority)
 {
        unsigned long pgmoved;
        int pgdeactivate = 0;
@@ -770,7 +784,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
                 * `distress' is a measure of how much trouble we're having
                 * reclaiming pages.  0 -> no problems.  100 -> great trouble.
                 */
-               distress = 100 >> zone->prev_priority;
+               distress = 100 >> min(zone->prev_priority, priority);
 
                /*
                 * The point of this algorithm is to decide when to start
@@ -922,7 +936,7 @@ static unsigned long shrink_zone(int priority, struct zone *zone,
                        nr_to_scan = min(nr_active,
                                        (unsigned long)sc->swap_cluster_max);
                        nr_active -= nr_to_scan;
-                       shrink_active_list(nr_to_scan, zone, sc);
+                       shrink_active_list(nr_to_scan, zone, sc, priority);
                }
 
                if (nr_inactive) {
@@ -972,9 +986,7 @@ static unsigned long shrink_zones(int priority, struct zone **zones,
                if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
-               zone->temp_priority = priority;
-               if (zone->prev_priority > priority)
-                       zone->prev_priority = priority;
+               note_zone_scanning_priority(zone, priority);
 
                if (zone->all_unreclaimable && priority != DEF_PRIORITY)
                        continue;       /* Let kswapd poll it */
@@ -1024,7 +1036,6 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
                if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
-               zone->temp_priority = DEF_PRIORITY;
                lru_pages += zone->nr_active + zone->nr_inactive;
        }
 
@@ -1065,13 +1076,22 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
        if (!sc.all_unreclaimable)
                ret = 1;
 out:
+       /*
+        * Now that we've scanned all the zones at this priority level, note
+        * that level within the zone so that the next thread which performs
+        * scanning of this zone will immediately start out at this priority
+        * level.  This affects only the decision whether or not to bring
+        * mapped pages onto the inactive list.
+        */
+       if (priority < 0)
+               priority = 0;
        for (i = 0; zones[i] != 0; i++) {
                struct zone *zone = zones[i];
 
                if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
-               zone->prev_priority = zone->temp_priority;
+               zone->prev_priority = priority;
        }
        return ret;
 }
@@ -1111,6 +1131,11 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order)
                .swap_cluster_max = SWAP_CLUSTER_MAX,
                .swappiness = vm_swappiness,
        };
+       /*
+        * temp_priority is used to remember the scanning priority at which
+        * this zone was successfully refilled to free_pages == pages_high.
+        */
+       int temp_priority[MAX_NR_ZONES];
 
 loop_again:
        total_scanned = 0;
@@ -1118,11 +1143,8 @@ loop_again:
        sc.may_writepage = !laptop_mode;
        count_vm_event(PAGEOUTRUN);
 
-       for (i = 0; i < pgdat->nr_zones; i++) {
-               struct zone *zone = pgdat->node_zones + i;
-
-               zone->temp_priority = DEF_PRIORITY;
-       }
+       for (i = 0; i < pgdat->nr_zones; i++)
+               temp_priority[i] = DEF_PRIORITY;
 
        for (priority = DEF_PRIORITY; priority >= 0; priority--) {
                int end_zone = 0;       /* Inclusive.  0 = ZONE_DMA */
@@ -1183,10 +1205,9 @@ scan:
                        if (!zone_watermark_ok(zone, order, zone->pages_high,
                                               end_zone, 0))
                                all_zones_ok = 0;
-                       zone->temp_priority = priority;
-                       if (zone->prev_priority > priority)
-                               zone->prev_priority = priority;
+                       temp_priority[i] = priority;
                        sc.nr_scanned = 0;
+                       note_zone_scanning_priority(zone, priority);
                        nr_reclaimed += shrink_zone(priority, zone, &sc);
                        reclaim_state->reclaimed_slab = 0;
                        nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
@@ -1226,10 +1247,15 @@ scan:
                        break;
        }
 out:
+       /*
+        * Note within each zone the priority level at which this zone was
+        * brought into a happy state.  So that the next thread which scans this
+        * zone will start out at that priority level.
+        */
        for (i = 0; i < pgdat->nr_zones; i++) {
                struct zone *zone = pgdat->node_zones + i;
 
-               zone->prev_priority = zone->temp_priority;
+               zone->prev_priority = temp_priority[i];
        }
        if (!all_zones_ok) {
                cond_resched();
@@ -1358,7 +1384,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int pass,
                        if (zone->nr_scan_active >= nr_pages || pass > 3) {
                                zone->nr_scan_active = 0;
                                nr_to_scan = min(nr_pages, zone->nr_active);
-                               shrink_active_list(nr_to_scan, zone, sc);
+                               shrink_active_list(nr_to_scan, zone, sc, prio);
                        }
                }
 
@@ -1614,6 +1640,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
                 */
                priority = ZONE_RECLAIM_PRIORITY;
                do {
+                       note_zone_scanning_priority(zone, priority);
                        nr_reclaimed += shrink_zone(priority, zone, &sc);
                        priority--;
                } while (priority >= 0 && nr_reclaimed < nr_pages);
index 45b124e..8614e8f 100644 (file)
@@ -587,11 +587,9 @@ static int zoneinfo_show(struct seq_file *m, void *arg)
                seq_printf(m,
                           "\n  all_unreclaimable: %u"
                           "\n  prev_priority:     %i"
-                          "\n  temp_priority:     %i"
                           "\n  start_pfn:         %lu",
                           zone->all_unreclaimable,
                           zone->prev_priority,
-                          zone->temp_priority,
                           zone->zone_start_pfn);
                spin_unlock_irqrestore(&zone->lock, flags);
                seq_putc(m, '\n');