Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 28 Nov 2005 23:02:30 +0000 (15:02 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 28 Nov 2005 23:02:30 +0000 (15:02 -0800)
85 files changed:
arch/frv/kernel/semaphore.c
arch/frv/mb93090-mb00/pci-irq.c
arch/frv/mm/init.c
arch/frv/mm/pgalloc.c
arch/m32r/kernel/io_mappi3.c
arch/m32r/kernel/setup_mappi3.c
arch/m32r/kernel/sys_m32r.c
arch/powerpc/Makefile
arch/powerpc/kernel/vdso.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/sysdev/dart.h
arch/powerpc/sysdev/u3_iommu.c
arch/sparc/mm/generic.c
arch/sparc64/mm/generic.c
drivers/char/drm/drm_lock.c
drivers/char/mem.c
drivers/cpufreq/cpufreq.c
drivers/infiniband/core/mad.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6main.c
drivers/media/video/Kconfig
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/saa7134/Kconfig
drivers/media/video/saa7134/Makefile
drivers/message/i2o/pci.c
drivers/pcmcia/m32r_cfc.c
drivers/scsi/dpt_i2o.c
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_rotate.h
fs/9p/vfs_inode.c
fs/dquot.c
fs/ext3/resize.c
fs/fuse/dir.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/proc/task_mmu.c
fs/reiserfs/inode.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_iomap.h
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_vnodeops.c
include/asm-frv/hardirq.h
include/asm-frv/ide.h
include/asm-frv/page.h
include/asm-frv/semaphore.h
include/asm-frv/thread_info.h
include/asm-m32r/atomic.h
include/asm-m32r/ide.h
include/asm-m32r/mappi3/mappi3_pld.h
include/asm-m32r/system.h
include/asm-powerpc/iommu.h
include/asm-powerpc/page_64.h
include/asm-powerpc/tce.h
include/asm-sparc64/pgtable.h
include/linux/cpu.h
include/linux/memory.h
include/linux/mm.h
include/linux/rmap.h
include/linux/sched.h
include/linux/swap.h
kernel/cpu.c
kernel/fork.c
kernel/posix-cpu-timers.c
kernel/workqueue.c
lib/genalloc.c
mm/fremap.c
mm/madvise.c
mm/memory.c
mm/mempolicy.c
mm/msync.c
mm/nommu.c
mm/page_alloc.c
mm/rmap.c
mm/thrash.c
mm/vmscan.c
net/sunrpc/rpc_pipe.c

index 5cba9c1f2b3dcf2c01579528f878f44ce88fbc90..7971d680ae298bbe6ef5cacf09de735527633109 100644 (file)
@@ -20,7 +20,7 @@ struct sem_waiter {
        struct task_struct      *task;
 };
 
-#if SEM_DEBUG
+#if SEMAPHORE_DEBUG
 void semtrace(struct semaphore *sem, const char *str)
 {
        if (sem->debug)
index af981bda015cb719db418a71410236c45871f42d..24622d89b1ca4d01c6257943eea7e9a877c22708 100644 (file)
@@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void)
        }
 }
 
-void __init pcibios_penalize_isa_irq(int irq, int active)
+void __init pcibios_penalize_isa_irq(int irq)
 {
 }
 
index 79433159b5f05a7bbb3022c5a89b6555247f3090..765088ea8a505844649258d9f2dd7cb60904e047 100644 (file)
@@ -108,7 +108,7 @@ void __init paging_init(void)
 
        memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
        if (num_physpages - num_mappedpages) {
                pgd_t *pge;
                pud_t *pue;
index 2c67dfe5a6b366d6e16e4569d86028593c17ff24..f76dd03ddd99a3505ba250b2b5d55c15b24c0372 100644 (file)
@@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *pgd)
        struct page *page = virt_to_page(pgd);
        page->index = (unsigned long) pgd_list;
        if (pgd_list)
-               pgd_list->private = (unsigned long) &page->index;
+               set_page_private(pgd_list, (unsigned long) &page->index);
        pgd_list = page;
        set_page_private(page, (unsigned long)&pgd_list);
 }
@@ -94,10 +94,10 @@ static inline void pgd_list_del(pgd_t *pgd)
 {
        struct page *next, **pprev, *page = virt_to_page(pgd);
        next = (struct page *) page->index;
-       pprev = (struct page **)page_private(page);
+       pprev = (struct page **) page_private(page);
        *pprev = next;
        if (next)
-               next->private = (unsigned long) pprev;
+               set_page_private(next, (unsigned long) pprev);
 }
 
 void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
index 6716ffea769a17b9d4423acfd79ccbea81c060ca..f80321a58764c71b882c50e5f509259314bdacdf 100644 (file)
@@ -36,12 +36,13 @@ static inline void *_port2addr(unsigned long port)
        return (void *)(port + NONCACHE_OFFSET);
 }
 
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+#if defined(CONFIG_IDE)
 static inline void *__port2addr_ata(unsigned long port)
 {
        static int      dummy_reg;
 
        switch (port) {
+         /* IDE0 CF */
        case 0x1f0:     return (void *)0xb4002000;
        case 0x1f1:     return (void *)0xb4012800;
        case 0x1f2:     return (void *)0xb4012002;
@@ -51,6 +52,17 @@ static inline void *__port2addr_ata(unsigned long port)
        case 0x1f6:     return (void *)0xb4012006;
        case 0x1f7:     return (void *)0xb4012806;
        case 0x3f6:     return (void *)0xb401200e;
+         /* IDE1 IDE */
+       case 0x170:     return (void *)0xb4810000;  /* Data 16bit */
+       case 0x171:     return (void *)0xb4810002;  /* Features / Error */
+       case 0x172:     return (void *)0xb4810004;  /* Sector count */
+       case 0x173:     return (void *)0xb4810006;  /* Sector number */
+       case 0x174:     return (void *)0xb4810008;  /* Cylinder low */
+       case 0x175:     return (void *)0xb481000a;  /* Cylinder high */
+       case 0x176:     return (void *)0xb481000c;  /* Device head */
+       case 0x177:     return (void *)0xb481000e;  /* Command     */
+       case 0x376:     return (void *)0xb480800c;  /* Device control / Alt status */
+
        default:        return (void *)&dummy_reg;
        }
 }
@@ -108,8 +120,9 @@ unsigned char _inb(unsigned long port)
 {
        if (port >= LAN_IOSTART && port < LAN_IOEND)
                return _ne_inb(PORT2ADDR_NE(port));
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                return *(volatile unsigned char *)__port2addr_ata(port);
        }
 #endif
@@ -127,8 +140,9 @@ unsigned short _inw(unsigned long port)
 {
        if (port >= LAN_IOSTART && port < LAN_IOEND)
                return _ne_inw(PORT2ADDR_NE(port));
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                return *(volatile unsigned short *)__port2addr_ata(port);
        }
 #endif
@@ -185,8 +199,9 @@ void _outb(unsigned char b, unsigned long port)
        if (port >= LAN_IOSTART && port < LAN_IOEND)
                _ne_outb(b, PORT2ADDR_NE(port));
        else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                *(volatile unsigned char *)__port2addr_ata(port) = b;
        } else
 #endif
@@ -203,8 +218,9 @@ void _outw(unsigned short w, unsigned long port)
        if (port >= LAN_IOSTART && port < LAN_IOEND)
                _ne_outw(w, PORT2ADDR_NE(port));
        else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                *(volatile unsigned short *)__port2addr_ata(port) = w;
        } else
 #endif
@@ -253,8 +269,9 @@ void _insb(unsigned int port, void * addr, unsigned long count)
 {
        if (port >= LAN_IOSTART && port < LAN_IOEND)
                _ne_insb(PORT2ADDR_NE(port), addr, count);
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                unsigned char *buf = addr;
                unsigned char *portp = __port2addr_ata(port);
                while (count--)
@@ -289,8 +306,9 @@ void _insw(unsigned int port, void * addr, unsigned long count)
                pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
                                count, 1);
 #endif
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                portp = __port2addr_ata(port);
                while (count--)
                        *buf++ = *(volatile unsigned short *)portp;
@@ -321,8 +339,9 @@ void _outsb(unsigned int port, const void * addr, unsigned long count)
                portp = PORT2ADDR_NE(port);
                while (count--)
                        _ne_outb(*buf++, portp);
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                portp = __port2addr_ata(port);
                while (count--)
                        *(volatile unsigned char *)portp = *buf++;
@@ -348,8 +367,9 @@ void _outsw(unsigned int port, const void * addr, unsigned long count)
                portp = PORT2ADDR_NE(port);
                while (count--)
                        *(volatile unsigned short *)portp = *buf++;
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-       } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+       } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+                 ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
                portp = __port2addr_ata(port);
                while (count--)
                        *(volatile unsigned short *)portp = *buf++;
index 9c79341a7b455711c165da735893f61cad8cef37..f6ecdf7f555ceb4ba2e04805398db3cb0e5e67a5 100644 (file)
@@ -151,7 +151,7 @@ void __init init_IRQ(void)
        disable_mappi3_irq(M32R_IRQ_INT1);
 #endif /* CONFIG_USB */
 
-       /* ICUCR40: CFC IREQ */
+       /* CFC IREQ */
        irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED;
        irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type;
        irq_desc[PLD_IRQ_CFIREQ].action = 0;
@@ -160,7 +160,7 @@ void __init init_IRQ(void)
        disable_mappi3_irq(PLD_IRQ_CFIREQ);
 
 #if defined(CONFIG_M32R_CFC)
-       /* ICUCR41: CFC Insert */
+       /* ICUCR41: CFC Insert & eject */
        irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
        irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type;
        irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
@@ -168,14 +168,16 @@ void __init init_IRQ(void)
        icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00;
        disable_mappi3_irq(PLD_IRQ_CFC_INSERT);
 
-       /* ICUCR42: CFC Eject */
-       irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
-       irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi3_irq_type;
-       irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
-       irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;  /* disable nested irq */
-       icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
-       disable_mappi3_irq(PLD_IRQ_CFC_EJECT);
 #endif /* CONFIG_M32R_CFC */
+
+       /* IDE IREQ */
+       irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED;
+       irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type;
+       irq_desc[PLD_IRQ_IDEIREQ].action = 0;
+       irq_desc[PLD_IRQ_IDEIREQ].depth = 1;    /* disable nested irq */
+       icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
+       disable_mappi3_irq(PLD_IRQ_IDEIREQ);
+
 }
 
 #if defined(CONFIG_SMC91X)
index e0500e12c5fbbb934c7debc9dc84dd1d7d1300dc..fe55b28d3725b48ed48e5fcdab52902592aa2d4e 100644 (file)
@@ -41,7 +41,8 @@ asmlinkage int sys_tas(int *addr)
                return -EFAULT;
        local_irq_save(flags);
        oldval = *addr;
-       *addr = 1;
+       if (!oldval)
+               *addr = 1;
        local_irq_restore(flags);
        return oldval;
 }
@@ -59,7 +60,8 @@ asmlinkage int sys_tas(int *addr)
 
        _raw_spin_lock(&tas_lock);
        oldval = *addr;
-       *addr = 1;
+       if (!oldval)
+               *addr = 1;
        _raw_spin_unlock(&tas_lock);
 
        return oldval;
index 98f67c78d1bd9ad191b6fe9a97849e0f0bf68b70..a13eb575f834c2520d30276aba3e5545ac66f310 100644 (file)
@@ -61,15 +61,17 @@ endif
 LDFLAGS_vmlinux        := -Bstatic
 
 # The -Iarch/$(ARCH)/include is temporary while we are merging
-CPPFLAGS       += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
-AFLAGS         += -Iarch/$(ARCH)
-CFLAGS         += -Iarch/$(ARCH) -msoft-float -pipe
+CPPFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH) -Iarch/$(ARCH)/include
+AFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH)
 CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none  -mcall-aixdesc
-CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
-CFLAGS         += $(CFLAGS-y)
+CFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH) -ffixed-r2 -mmultiple
+CPPFLAGS       += $(CPPFLAGS-y)
+AFLAGS         += $(AFLAGS-y)
+CFLAGS         += -msoft-float -pipe $(CFLAGS-y)
 CPP            = $(CC) -E $(CFLAGS)
 # Temporary hack until we have migrated to asm-powerpc
-LINUXINCLUDE    += -Iarch/$(ARCH)/include
+LINUXINCLUDE-$(CONFIG_PPC32)   := -Iarch/$(ARCH)/include
+LINUXINCLUDE    += $(LINUXINCLUDE-y)
 
 CHECKFLAGS     += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
 
@@ -173,11 +175,13 @@ archclean:
 
 archprepare: checkbin
 
+ifeq ($(CONFIG_PPC32),y)
 # Temporary hack until we have migrated to asm-powerpc
 include/asm: arch/$(ARCH)/include/asm
 arch/$(ARCH)/include/asm: FORCE
        $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
        $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
+endif
 
 # Use the file '.tmp_gas_check' for binutils tests, as gas won't output
 # to stdout and these checks are run even on install targets.
index b44b36e0c29325281daa939d7eeacf8df8d3eb84..f0c47dab09030266d799bbf2544e94a6a2c0e872 100644 (file)
@@ -145,8 +145,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma)
                        struct page *pg = virt_to_page(vdso32_kbase +
                                                       i*PAGE_SIZE);
                        struct page *upg = (vma && vma->vm_mm) ?
-                               follow_page(vma->vm_mm, vma->vm_start +
-                                           i*PAGE_SIZE, 0)
+                               follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
                                : NULL;
                        dump_one_vdso_page(pg, upg);
                }
@@ -157,8 +156,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma)
                        struct page *pg = virt_to_page(vdso64_kbase +
                                                       i*PAGE_SIZE);
                        struct page *upg = (vma && vma->vm_mm) ?
-                               follow_page(vma->vm_mm, vma->vm_start +
-                                           i*PAGE_SIZE, 0)
+                               follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
                                : NULL;
                        dump_one_vdso_page(pg, upg);
                }
index f867bba893caf86a8fdaa48019b1d86782f06c66..6bc9dbad7dea20cd744d10f682f74562533f614f 100644 (file)
@@ -295,7 +295,7 @@ int prepare_hugepage_range(unsigned long addr, unsigned long len)
        if (addr < 0x100000000UL)
                err = open_low_hpage_areas(current->mm,
                                          LOW_ESID_MASK(addr, len));
-       if ((addr + len) >= 0x100000000UL)
+       if ((addr + len) > 0x100000000UL)
                err = open_high_hpage_areas(current->mm,
                                            HTLB_AREA_MASK(addr, len));
        if (err) {
index bf081b3458201deef96b0b9bd59216cd666ee985..2b54eeb2c8997c5f6c540c137824aea64513aec7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Rewrite, cleanup:
  *
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * Dynamic DMA mapping support, iSeries-specific parts.
  *
index 97ba5214417f856a7371652e0df54a6863ab5085..c78f2b290a73a52b90356f32f54af51569227796 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Rewrite, cleanup: 
  *
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
  *
index ea8f0d9eed8a14b752d6eb6eac7089f0fbf35ac3..33ed9ed7fc1e35f693d41d0369d47c8658d613af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f32baf7f4693eb0980c3a42ba366492fb9c0517e..5c1a26a6d00c3cd28e4ec1937e3824d62da4c0f5 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * arch/powerpc/sysdev/u3_iommu.c
  *
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * Based on pSeries_iommu.c:
  * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * Dynamic DMA mapping support, Apple U3 & IBM CPC925 "DART" iommu.
  *
index 0410bae681f869c6335ab3f8bffd45c14f204920..2cb0728cee052012c7856b017f7499fa5638ce82 100644 (file)
@@ -32,9 +32,7 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigne
        if (end > PMD_SIZE)
                end = PMD_SIZE;
        do {
-               pte_t oldpage = *pte;
-               pte_clear(mm, address, pte);
-               set_pte(pte, mk_pte_io(offset, prot, space));
+               set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space));
                address += PAGE_SIZE;
                offset += PAGE_SIZE;
                pte++;
@@ -63,7 +61,7 @@ static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned
 }
 
 int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                       unsigned long pfn, unsigned long size, pgprot_t prot)
+                      unsigned long pfn, unsigned long size, pgprot_t prot)
 {
        int error = 0;
        pgd_t * dir;
@@ -74,7 +72,9 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
        unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
 
        /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       vma->vm_pgoff = (offset >> PAGE_SHIFT) |
+               ((unsigned long)space << 28UL);
 
        prot = __pgprot(pg_iobits);
        offset -= from;
index 8fd4cb1f050a19e394068abce75e8ff08fbd57e7..d9396c1721cdd3d67e11ab2ec9b5c5174a096a4b 100644 (file)
 #include <asm/page.h>
 #include <asm/tlbflush.h>
 
+static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
+{
+       pte_t pte;
+       pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) &
+                       ~(unsigned long)_PAGE_CACHE);
+       pte_val(pte) |= (((unsigned long)space) << 32);
+       return pte;
+}
+
 /* Remap IO memory, the same way as remap_pfn_range(), but use
  * the obio memory space.
  *
@@ -126,9 +135,13 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
        struct mm_struct *mm = vma->vm_mm;
        int space = GET_IOSPACE(pfn);
        unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+       unsigned long phys_base;
+
+       phys_base = offset | (((unsigned long) space) << 32UL);
 
        /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       vma->vm_pgoff = phys_base >> PAGE_SHIFT;
 
        prot = __pgprot(pg_iobits);
        offset -= from;
index b276ae8a6633bb836cd96ed3cd927ca3504efce0..b48a595d54eca0e9c13b0cb269b88fba6dc49f56 100644 (file)
@@ -104,6 +104,10 @@ int drm_lock(struct inode *inode, struct file *filp,
        __set_current_state(TASK_RUNNING);
        remove_wait_queue(&dev->lock.lock_queue, &entry);
 
+       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+       if (ret)
+               return ret;
+
        sigemptyset(&dev->sigmask);
        sigaddset(&dev->sigmask, SIGSTOP);
        sigaddset(&dev->sigmask, SIGTSTP);
@@ -116,8 +120,12 @@ int drm_lock(struct inode *inode, struct file *filp,
        if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
                dev->driver->dma_ready(dev);
 
-       if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
-               return dev->driver->dma_quiescent(dev);
+       if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) {
+               if (dev->driver->dma_quiescent(dev)) {
+                       DRM_DEBUG("%d waiting for DMA quiescent\n", lock.context);
+                       return DRM_ERR(EBUSY);
+               }
+       }
 
        /* dev->driver->kernel_context_switch isn't used by any of the x86
         *  drivers but is used by the Sparc driver.
@@ -128,9 +136,7 @@ int drm_lock(struct inode *inode, struct file *filp,
                dev->driver->kernel_context_switch(dev, dev->last_context,
                                                   lock.context);
        }
-       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-       return ret;
+       return 0;
 }
 
 /**
index 29c3b631445af851e9e90c93f7a25dbdef08ad7a..91dd669273e0018aeeb95b02e18b4549e074a661 100644 (file)
@@ -591,7 +591,7 @@ static inline size_t read_zero_pagealigned(char __user * buf, size_t size)
 
                if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
                        goto out_up;
-               if (vma->vm_flags & (VM_SHARED | VM_HUGETLB | VM_UNPAGED))
+               if (vma->vm_flags & (VM_SHARED | VM_HUGETLB))
                        break;
                count = vma->vm_end - addr;
                if (count > size)
index 1c0f62d0f938af7568312ea0f6649c5d5d80a36d..815902c2c856bd08df4da65daaf996f78f07e419 100644 (file)
@@ -1113,21 +1113,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
 {
        int retval = -EINVAL;
 
-       /*
-        * If we are already in context of hotplug thread, we dont need to
-        * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
-        * hotplug from removing this cpu that we are working on.
-        */
-       if (!current_in_cpu_hotplug())
-               lock_cpu_hotplug();
-
+       lock_cpu_hotplug();
        dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
                target_freq, relation);
        if (cpu_online(policy->cpu) && cpufreq_driver->target)
                retval = cpufreq_driver->target(policy, target_freq, relation);
 
-       if (!current_in_cpu_hotplug())
-               unlock_cpu_hotplug();
+       unlock_cpu_hotplug();
 
        return retval;
 }
index 41d6b4017acb9d24aebdd5aed278b079bf382d85..d393b504bf26b23ffafc069e92a07bf485ffd3f4 100644 (file)
@@ -355,9 +355,9 @@ error4:
        spin_unlock_irqrestore(&port_priv->reg_lock, flags);
        kfree(reg_req);
 error3:
-       kfree(mad_agent_priv);
-error2:
        ib_dereg_mr(mad_agent_priv->agent.mr);
+error2:
+       kfree(mad_agent_priv);
 error1:
        return ret;
 }
index 78c7418478d63e86f55127026d227bfae18e94a3..cd12fca73b0d89fa0ee83e711f97c7d08e9cf63d 100644 (file)
@@ -1028,7 +1028,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
                mddev->size = le64_to_cpu(sb->size)/2;
                mddev->events = le64_to_cpu(sb->events);
                mddev->bitmap_offset = 0;
-               mddev->default_bitmap_offset = 0;
                mddev->default_bitmap_offset = 1024;
                
                mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
@@ -2932,6 +2931,9 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
 
        mddev->sb_dirty      = 1;
 
+       mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
+       mddev->bitmap_offset = 0;
+
        /*
         * Generate a 128 bit UUID
         */
index 2da9d3ba902dd1337ff2d724e46838f9d604f148..3066c587b5391202dda91f8e4a9bdc977a4b335a 100644 (file)
@@ -953,9 +953,6 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        int mirror = 0;
        mirror_info_t *p;
 
-       if (rdev->saved_raid_disk >= 0 &&
-           conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
-               mirror = rdev->saved_raid_disk;
        for (mirror=0; mirror < mddev->raid_disks; mirror++)
                if ( !(p=conf->mirrors+mirror)->rdev) {
 
@@ -972,7 +969,10 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
                        found = 1;
-                       if (rdev->saved_raid_disk != mirror)
+                       /* As all devices are equivalent, we don't need a full recovery
+                        * if this was recently any drive of the array
+                        */
+                       if (rdev->saved_raid_disk < 0)
                                conf->fullsync = 1;
                        rcu_assign_pointer(p->rdev, rdev);
                        break;
index 867f06ae33d944e8ef7178d28fc3fa8905d963b3..713dc9c2c73093a67348e473f2bfc47f888d6e3c 100644 (file)
@@ -552,7 +552,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
                    !test_bit(In_sync, &rdev->flags))
                        continue;
 
-               if (!atomic_read(&rdev->nr_pending)) {
+               /* This optimisation is debatable, and completely destroys
+                * sequential read speed for 'far copies' arrays.  So only
+                * keep it for 'near' arrays, and review those later.
+                */
+               if (conf->near_copies > 1 && !atomic_read(&rdev->nr_pending)) {
                        disk = ndisk;
                        slot = nslot;
                        break;
index e2a40283e323b46335beedb18face0aad67eae00..36d5f8ac82650bfb4eda7ddce550b44af2f80ac1 100644 (file)
@@ -1704,7 +1704,9 @@ static void raid5d (mddev_t *mddev)
 
                if (conf->seq_flush - conf->seq_write > 0) {
                        int seq = conf->seq_flush;
+                       spin_unlock_irq(&conf->device_lock);
                        bitmap_unplug(mddev->bitmap);
+                       spin_lock_irq(&conf->device_lock);
                        conf->seq_write = seq;
                        activate_bit_delay(conf);
                }
index eae5a35629c59101372d31518ecba9daa4e77814..0000d162d198a60d558ab4be3f54f608ff8b7473 100644 (file)
@@ -1702,6 +1702,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        int data_disks = raid_disks - 2;
        sector_t max_sector = mddev->size << 1;
        int sync_blocks;
+       int still_degraded = 0;
+       int i;
 
        if (sector_nr >= max_sector) {
                /* just being told to finish up .. nothing much to do */
@@ -1710,7 +1712,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                if (mddev->curr_resync < max_sector) /* aborted */
                        bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
                                        &sync_blocks, 1);
-               else /* compelted sync */
+               else /* completed sync */
                        conf->fullsync = 0;
                bitmap_close_sync(mddev->bitmap);
 
@@ -1748,7 +1750,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                 */
                schedule_timeout_uninterruptible(1);
        }
-       bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
+       /* Need to check if array will still be degraded after recovery/resync
+        * We don't need to check the 'failed' flag as when that gets set,
+        * recovery aborts.
+        */
+       for (i=0; i<mddev->raid_disks; i++)
+               if (conf->disks[i].rdev == NULL)
+                       still_degraded = 1;
+
+       bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);
+
        spin_lock(&sh->lock);
        set_bit(STRIPE_SYNCING, &sh->state);
        clear_bit(STRIPE_INSYNC, &sh->state);
@@ -1784,7 +1795,9 @@ static void raid6d (mddev_t *mddev)
 
                if (conf->seq_flush - conf->seq_write > 0) {
                        int seq = conf->seq_flush;
+                       spin_unlock_irq(&conf->device_lock);
                        bitmap_unplug(mddev->bitmap);
+                       spin_lock_irq(&conf->device_lock);
                        conf->seq_write = seq;
                        activate_bit_delay(conf);
                }
@@ -2145,9 +2158,15 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                /* no point adding a device */
                return 0;
        /*
-        * find the disk ...
+        * find the disk ... but prefer rdev->saved_raid_disk
+        * if possible.
         */
-       for (disk=0; disk < mddev->raid_disks; disk++)
+       if (rdev->saved_raid_disk >= 0 &&
+           conf->disks[rdev->saved_raid_disk].rdev == NULL)
+               disk = rdev->saved_raid_disk;
+       else
+               disk = 0;
+       for ( ; disk < mddev->raid_disks; disk++)
                if ((p=conf->disks + disk)->rdev == NULL) {
                        clear_bit(In_sync, &rdev->flags);
                        rdev->raid_disk = disk;
index 1a3b3c7e5e99699815245de164016959b549c6ed..ecb9a31dd003cb125fbe3a5a7a9520d7ff0b292f 100644 (file)
@@ -26,7 +26,7 @@ config VIDEO_BT848
          module will be called bttv.
 
 config VIDEO_BT848_DVB
-       tristate "DVB/ATSC Support for bt878 based TV cards"
+       bool "DVB/ATSC Support for bt878 based TV cards"
        depends on VIDEO_BT848 && DVB_CORE
        select DVB_BT8XX
        ---help---
index 41818b6205b3b9cc02efafab549426307570d29f..85ba4106dc79456621e090da7aba453808b9f0d5 100644 (file)
@@ -46,8 +46,8 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
          If you are unsure, choose Y.
 
 config VIDEO_CX88_DVB_MT352
-       tristate "Zarlink MT352 DVB-T Support"
-       default m
+       bool "Zarlink MT352 DVB-T Support"
+       default y
        depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
        select DVB_MT352
        ---help---
@@ -55,8 +55,8 @@ config VIDEO_CX88_DVB_MT352
          Connexant 2388x chip and the MT352 demodulator.
 
 config VIDEO_CX88_DVB_OR51132
-       tristate "OR51132 ATSC Support"
-       default m
+       bool "OR51132 ATSC Support"
+       default y
        depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
        select DVB_OR51132
        ---help---
@@ -64,8 +64,8 @@ config VIDEO_CX88_DVB_OR51132
          Connexant 2388x chip and the OR51132 demodulator.
 
 config VIDEO_CX88_DVB_CX22702
-       tristate "Conexant CX22702 DVB-T Support"
-       default m
+       bool "Conexant CX22702 DVB-T Support"
+       default y
        depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
        select DVB_CX22702
        ---help---
@@ -73,8 +73,8 @@ config VIDEO_CX88_DVB_CX22702
          Connexant 2388x chip and the CX22702 demodulator.
 
 config VIDEO_CX88_DVB_LGDT330X
-       tristate "LG Electronics DT3302/DT3303 ATSC Support"
-       default m
+       bool "LG Electronics DT3302/DT3303 ATSC Support"
+       default y
        depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
        select DVB_LGDT330X
        ---help---
@@ -82,8 +82,8 @@ config VIDEO_CX88_DVB_LGDT330X
          Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
 
 config VIDEO_CX88_DVB_NXT200X
-       tristate "NXT2002/NXT2004 ATSC Support"
-       default m
+       bool "NXT2002/NXT2004 ATSC Support"
+       default y
        depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
        select DVB_NXT200X
        ---help---
index 0df40b7734548e99fccf79454bba870868a23680..54401b02b7ce75c13dfc24df48c3b85c8d9196a7 100644 (file)
@@ -9,21 +9,12 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
-ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
- EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
-endif
-ifneq ($(CONFIG_DVB_CX22702),n)
- EXTRA_CFLAGS += -DHAVE_CX22702=1
-endif
-ifneq ($(CONFIG_DVB_OR51132),n)
- EXTRA_CFLAGS += -DHAVE_OR51132=1
-endif
-ifneq ($(CONFIG_DVB_LGDT330X),n)
- EXTRA_CFLAGS += -DHAVE_LGDT330X=1
-endif
-ifneq ($(CONFIG_DVB_MT352),n)
- EXTRA_CFLAGS += -DHAVE_MT352=1
-endif
-ifneq ($(CONFIG_DVB_NXT200X),n)
- EXTRA_CFLAGS += -DHAVE_NXT200X=1
-endif
+
+extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
+extra-cflags-$(CONFIG_DVB_CX22702)   += -DHAVE_CX22702=1
+extra-cflags-$(CONFIG_DVB_OR51132)   += -DHAVE_OR51132=1
+extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
+extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
+extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
index 7bdeabe638cacef344f30fc933fbb9b1fe6c95c7..c512c4411b38319b513b9bc9bfb7ac80bfda2c59 100644 (file)
@@ -42,8 +42,8 @@ config VIDEO_SAA7134_DVB_ALL_FRONTENDS
          If you are unsure, choose Y.
 
 config VIDEO_SAA7134_DVB_MT352
-       tristate "Zarlink MT352 DVB-T Support"
-       default m
+       bool "Zarlink MT352 DVB-T Support"
+       default y
        depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
        select DVB_MT352
        ---help---
@@ -51,8 +51,8 @@ config VIDEO_SAA7134_DVB_MT352
          Philips saa7134 chip and the MT352 demodulator.
 
 config VIDEO_SAA7134_DVB_TDA1004X
-       tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
-       default m
+       bool "Phillips TDA10045H/TDA10046H DVB-T Support"
+       default y
        depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
        select DVB_TDA1004X
        ---help---
@@ -60,8 +60,8 @@ config VIDEO_SAA7134_DVB_TDA1004X
          Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
 
 config VIDEO_SAA7134_DVB_NXT200X
-       tristate "NXT2002/NXT2004 ATSC Support"
-       default m
+       bool "NXT2002/NXT2004 ATSC Support"
+       default y
        depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
        select DVB_NXT200X
        ---help---
index 4226b61cc613a60d5a67ebdb5851aac26ee06619..134f83a962188f7d8da5b0d45db4c5cb380455a3 100644 (file)
@@ -11,15 +11,10 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
-ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
- EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
-endif
-ifneq ($(CONFIG_DVB_MT352),n)
- EXTRA_CFLAGS += -DHAVE_MT352=1
-endif
-ifneq ($(CONFIG_DVB_TDA1004X),n)
- EXTRA_CFLAGS += -DHAVE_TDA1004X=1
-endif
-ifneq ($(CONFIG_DVB_NXT200X),n)
- EXTRA_CFLAGS += -DHAVE_NXT200X=1
-endif
+
+extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
+extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
+extra-cflags-$(CONFIG_DVB_TDA1004X)  += -DHAVE_TDA1004X=1
+extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
index 66c03e8825703a408b21c239ff5e4781fab71ffc..81ef306cb1247c40ac2dbb6d1458f71f7b36453c 100644 (file)
@@ -421,8 +421,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
        i2o_pci_free(c);
 
       free_controller:
-       i2o_iop_free(c);
        put_device(c->device.parent);
+       i2o_iop_free(c);
 
       disable:
        pci_disable_device(pdev);
index 2c22b4b3619d58f6c1c1a5c107597eb724b2a7e5..078579ae635905477212d8894414b6e0be86c204 100644 (file)
@@ -355,9 +355,10 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr
 #ifndef CONFIG_PLAT_USRV
        /* insert interrupt */
        request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
+#ifndef CONFIG_PLAT_MAPPI3
        /* eject interrupt */
        request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
-
+#endif
        debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
        pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
 #endif /* CONFIG_PLAT_USRV */
index c28e3aea1c3cef83f28e3b3bccb00dac2e8ada27..418fc7b896ace82d050c477fe67738173b148443 100644 (file)
@@ -816,7 +816,7 @@ static int adpt_hba_reset(adpt_hba* pHba)
 static void adpt_i2o_sys_shutdown(void)
 {
        adpt_hba *pHba, *pNext;
-       struct adpt_i2o_post_wait_data *p1, *p2;
+       struct adpt_i2o_post_wait_data *p1, *old;
 
         printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
         printk(KERN_INFO"   This could take a few minutes if there are many devices attached\n");
@@ -830,13 +830,14 @@ static void adpt_i2o_sys_shutdown(void)
        }
 
        /* Remove any timedout entries from the wait queue.  */
-       p2 = NULL;
 //     spin_lock_irqsave(&adpt_post_wait_lock, flags);
        /* Nothing should be outstanding at this point so just
         * free them 
         */
-       for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {
-               kfree(p1);
+       for(p1 = adpt_post_wait_queue; p1;) {
+               old = p1;
+               p1 = p1->next;
+               kfree(old);
        }
 //     spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
        adpt_post_wait_queue = NULL;
index 3afd1eeb1adebc38b5432a36ecaca220a88eba88..4952b66ae2062996d13ce6efcbb0b7df29c68470 100644 (file)
@@ -34,7 +34,7 @@ static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
                msk <<= (8 - mod);
 
        if (offset > mod)
-               set_bit(FBCON_BIT(7), (void *)&msk1);
+               msk1 |= 0x01;
 
        for (i = 0; i < vc->vc_font.width; i++) {
                for (j = 0; j < width; j++) {
index e504fbf5c6045bedb1319d76f968b0c4e425007f..1b8f92fdc6a82f3c02b8c02096832d053ba6e1d9 100644 (file)
         (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
         (i)->var.xres : (i)->var.xres_virtual; })
 
-/*
- * The bitmap is always big endian
- */
-#if defined(__LITTLE_ENDIAN)
-#define FBCON_BIT(b) (7 - (b))
-#else
-#define FBCON_BIT(b) (b)
-#endif
 
 static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
 {
        u32 tmp = (y * pitch) + x, index = tmp / 8,  bit = tmp % 8;
 
        pat +=index;
-       return (test_bit(FBCON_BIT(bit), (void *)pat));
+       return (*pat) & (0x80 >> bit);
 }
 
 static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
@@ -43,7 +35,8 @@ static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
        u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
 
        pat += index;
-       set_bit(FBCON_BIT(bit), (void *)pat);
+
+       (*pat) |= 0x80 >> bit;
 }
 
 static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
index be7288184fa9de0a580f7ec64d86f29fec5d3ce3..0ea965c3bb7d0d7233e320a8957be96aaefb33ad 100644 (file)
@@ -427,6 +427,8 @@ v9fs_create(struct inode *dir,
 
        v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb);
        kfree(fcall);
+       fcall = NULL;
+       file_dentry->d_op = &v9fs_dentry_operations;
        d_instantiate(file_dentry, file_inode);
 
        if (perm & V9FS_DMDIR) {
index 05b60283c9c2710d65fa96ccfe20d47f1da13f64..2a62b3dc20ec00a76c665a8f1e9dda9808e715b6 100644 (file)
@@ -1513,10 +1513,16 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
 
+       if (!dentry->d_inode) {
+               error = -ENOENT;
+               goto out;
+       }
+
        error = security_quota_on(dentry);
        if (!error)
                error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
 
+out:
        dput(dentry);
        return error;
 }
index 1be78b4b4de956f7bb9e831a7f3e1c1c489b997b..6104ad3105077ec7a14e5da4f24a261d116035a0 100644 (file)
@@ -767,6 +767,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
        if (input->group != EXT3_SB(sb)->s_groups_count) {
                ext3_warning(sb, __FUNCTION__,
                             "multiple resizers run on filesystem!\n");
+               err = -EBUSY;
                goto exit_journal;
        }
 
index c045cc70c74931864e01763c3573eeae19c2d1e8..51f5da6527719c31ab3a7316c0ba99812e85809b 100644 (file)
@@ -74,6 +74,24 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
        return 1;
 }
 
+static int dir_alias(struct inode *inode)
+{
+       if (S_ISDIR(inode->i_mode)) {
+               /* Don't allow creating an alias to a directory  */
+               struct dentry *alias = d_find_alias(inode);
+               if (alias) {
+                       dput(alias);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static inline int invalid_nodeid(u64 nodeid)
+{
+       return !nodeid || nodeid == FUSE_ROOT_ID;
+}
+
 static struct dentry_operations fuse_dentry_operations = {
        .d_revalidate   = fuse_dentry_revalidate,
 };
@@ -97,7 +115,7 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
        fuse_lookup_init(req, dir, entry, &outarg);
        request_send(fc, req);
        err = req->out.h.error;
-       if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
+       if (!err && invalid_nodeid(outarg.nodeid))
                err = -EIO;
        if (!err) {
                inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
@@ -193,7 +211,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        }
 
        err = -EIO;
-       if (!S_ISREG(outentry.attr.mode))
+       if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
                goto out_free_ff;
 
        inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
@@ -250,7 +268,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                fuse_put_request(fc, req);
                return err;
        }
-       if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
+       if (invalid_nodeid(outarg.nodeid)) {
                fuse_put_request(fc, req);
                return -EIO;
        }
@@ -263,7 +281,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        fuse_put_request(fc, req);
 
        /* Don't allow userspace to do really stupid things... */
-       if ((inode->i_mode ^ mode) & S_IFMT) {
+       if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
                iput(inode);
                return -EIO;
        }
@@ -874,14 +892,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        err = fuse_lookup_iget(dir, entry, &inode);
        if (err)
                return ERR_PTR(err);
-       if (inode && S_ISDIR(inode->i_mode)) {
-               /* Don't allow creating an alias to a directory  */
-               struct dentry *alias = d_find_alias(inode);
-               if (alias) {
-                       dput(alias);
-                       iput(inode);
-                       return ERR_PTR(-EIO);
-               }
+       if (inode && dir_alias(inode)) {
+               iput(inode);
+               return ERR_PTR(-EIO);
        }
        d_add(entry, inode);
        return NULL;
index 6391d89642144366591df7e7c0e6733b12916899..aaab1a5ac4616e1e0d2242c405494382d429a2b4 100644 (file)
@@ -643,14 +643,11 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
 /*
  * Invalidate the local caches
  */
-void
-nfs_zap_caches(struct inode *inode)
+static void nfs_zap_caches_locked(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
        int mode = inode->i_mode;
 
-       spin_lock(&inode->i_lock);
-
        NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
        NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
 
@@ -659,7 +656,12 @@ nfs_zap_caches(struct inode *inode)
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
        else
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
+}
 
+void nfs_zap_caches(struct inode *inode)
+{
+       spin_lock(&inode->i_lock);
+       nfs_zap_caches_locked(inode);
        spin_unlock(&inode->i_lock);
 }
 
@@ -676,16 +678,13 @@ static void nfs_zap_acl_cache(struct inode *inode)
 }
 
 /*
- * Invalidate, but do not unhash, the inode
+ * Invalidate, but do not unhash, the inode.
+ * NB: must be called with inode->i_lock held!
  */
-static void
-nfs_invalidate_inode(struct inode *inode)
+static void nfs_invalidate_inode(struct inode *inode)
 {
-       umode_t save_mode = inode->i_mode;
-
-       make_bad_inode(inode);
-       inode->i_mode = save_mode;
-       nfs_zap_caches(inode);
+       set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
+       nfs_zap_caches_locked(inode);
 }
 
 struct nfs_find_desc {
@@ -1528,14 +1527,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
        printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
                        __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
 #endif
+ out_err:
        /*
         * No need to worry about unhashing the dentry, as the
         * lookup validation will know that the inode is bad.
         * (But we fall through to invalidate the caches.)
         */
        nfs_invalidate_inode(inode);
- out_err:
-       set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
        return -ESTALE;
 }
 
index 21482b2518f61799a53b85ecba768b0de2ef056c..60e0dd800cc37e8a80168957391dbcc7113a4754 100644 (file)
@@ -3071,15 +3071,15 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
        struct nfs4_client *clp = state->owner->so_client;
        int status;
 
-       down_read(&clp->cl_sem);
        /* Is this a delegated open? */
-       if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+       if (NFS_I(state->inode)->delegation_state != 0) {
                /* Yes: cache locks! */
                status = do_vfs_lock(request->fl_file, request);
                /* ...but avoid races with delegation recall... */
                if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
-                       goto out;
+                       return status;
        }
+       down_read(&clp->cl_sem);
        status = nfs4_set_lock_state(state, request);
        if (status != 0)
                goto out;
index 0675f3215e0a4fb7512f4950b007dfcb98420489..5ef4c57618fe8507da03dd4dbbd3d9de3aa84dca 100644 (file)
@@ -644,12 +644,15 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
 
 struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
 {
+       struct rpc_sequence *sequence = counter->sequence;
        struct nfs_seqid *new;
 
        new = kmalloc(sizeof(*new), GFP_KERNEL);
        if (new != NULL) {
                new->sequence = counter;
-               INIT_LIST_HEAD(&new->list);
+               spin_lock(&sequence->lock);
+               list_add_tail(&new->list, &sequence->list);
+               spin_unlock(&sequence->lock);
        }
        return new;
 }
@@ -658,12 +661,10 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
 {
        struct rpc_sequence *sequence = seqid->sequence->sequence;
 
-       if (!list_empty(&seqid->list)) {
-               spin_lock(&sequence->lock);
-               list_del(&seqid->list);
-               spin_unlock(&sequence->lock);
-       }
-       rpc_wake_up_next(&sequence->wait);
+       spin_lock(&sequence->lock);
+       list_del(&seqid->list);
+       spin_unlock(&sequence->lock);
+       rpc_wake_up(&sequence->wait);
        kfree(seqid);
 }
 
@@ -722,11 +723,10 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
        if (sequence->list.next == &seqid->list)
                goto out;
        spin_lock(&sequence->lock);
-       if (!list_empty(&sequence->list)) {
+       if (sequence->list.next != &seqid->list) {
                rpc_sleep_on(&sequence->wait, task, NULL, NULL);
                status = -EAGAIN;
-       } else
-               list_add(&seqid->list, &sequence->list);
+       }
        spin_unlock(&sequence->lock);
 out:
        return status;
index 9ab97cef0daa001dded3c6d667e95ea4134fc0a7..50bd5a8f0446d902cc6161032fde8ac5fcadd7a6 100644 (file)
@@ -402,12 +402,11 @@ struct numa_maps {
 /*
  * Calculate numa node maps for a vma
  */
-static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
+static struct numa_maps *get_numa_maps(struct vm_area_struct *vma)
 {
+       int i;
        struct page *page;
        unsigned long vaddr;
-       struct mm_struct *mm = vma->vm_mm;
-       int i;
        struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL);
 
        if (!md)
@@ -420,7 +419,7 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
                md->node[i] =0;
 
        for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
-               page = follow_page(mm, vaddr, 0);
+               page = follow_page(vma, vaddr, 0);
                if (page) {
                        int count = page_mapcount(page);
 
index 5f82352b97e179c263366e550ab8f7564ebf1d16..0a044ad98885e1af810d1ba3907d6338a2321b00 100644 (file)
@@ -2194,7 +2194,7 @@ static int map_block_for_writepage(struct inode *inode,
        INITIALIZE_PATH(path);
        int pos_in_item;
        int jbegin_count = JOURNAL_PER_BALANCE_CNT;
-       loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1;
+       loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1;
        int retval;
        int use_get_block = 0;
        int bytes_copied = 0;
index c6108971b4e6a4febd84be420c6da7b832acf768..94d3cdfbf9b8054a502b976fb8c7825837bbf85c 100644 (file)
@@ -941,13 +941,12 @@ __linvfs_get_block(
        int                     retpbbm = 1;
        int                     error;
 
-       if (blocks) {
-               offset = blocks << inode->i_blkbits;    /* 64 bit goodness */
-               size = (ssize_t) min_t(xfs_off_t, offset, LONG_MAX);
-       } else {
-               size = 1 << inode->i_blkbits;
-       }
        offset = (xfs_off_t)iblock << inode->i_blkbits;
+       if (blocks)
+               size = (ssize_t) min_t(xfs_off_t, LONG_MAX,
+                                       (xfs_off_t)blocks << inode->i_blkbits);
+       else
+               size = 1 << inode->i_blkbits;
 
        VOP_BMAP(vp, offset, size,
                create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
@@ -1007,7 +1006,7 @@ __linvfs_get_block(
                ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
                offset = min_t(xfs_off_t,
                                iomap.iomap_bsize - iomap.iomap_delta,
-                               blocks << inode->i_blkbits);
+                               (xfs_off_t)blocks << inode->i_blkbits);
                bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
        }
 
index 35e557b00db2175cdbda7a48ce4f4a2e93b0b0ad..1c7421840c1802441b5345ec766727a0f874b9eb 100644 (file)
@@ -310,7 +310,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
         * Fix up the start offset of the attribute fork
         */
        totsize -= size;
-       if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname) {
+       if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
+           !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
                /*
                 * Last attribute now removed, revert to original
                 * inode format making all literal area available
@@ -328,7 +329,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
                xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
                dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
                ASSERT(dp->i_d.di_forkoff);
-               ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname);
+               ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||
+                       (mp->m_flags & XFS_MOUNT_COMPAT_ATTR));
                dp->i_afp->if_ext_max =
                        XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
                dp->i_df.if_ext_max =
@@ -737,7 +739,8 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
                                + name_loc->namelen
                                + INT_GET(name_loc->valuelen, ARCH_CONVERT);
        }
-       if (bytes == sizeof(struct xfs_attr_sf_hdr))
+       if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
+           (bytes == sizeof(struct xfs_attr_sf_hdr)))
                return(-1);
        return(xfs_attr_shortform_bytesfit(dp, bytes));
 }
@@ -775,6 +778,8 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
                goto out;
 
        if (forkoff == -1) {
+               ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR));
+
                /*
                 * Last attribute was removed, revert to original
                 * inode format making all literal area available
index 7ceabd0e2d9d93c0abd771855efa245e86454e91..d1236d6f40455c96d188463c188dee42502447db 100644 (file)
@@ -550,7 +550,7 @@ xfs_fs_goingdown(
                struct vfs *vfsp = XFS_MTOVFS(mp);
                struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
 
-               if (sb) {
+               if (sb && !IS_ERR(sb)) {
                        xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
                        thaw_bdev(sb->s_bdev, sb);
                }
index fcd6d63bb68ba4c4db7da17d15d8dfcb0572d8e4..3ce204a524b0665df59272cdc4425d0772f95619 100644 (file)
@@ -69,7 +69,7 @@ typedef struct xfs_iomap {
        xfs_buftarg_t           *iomap_target;
        xfs_off_t               iomap_offset;   /* offset of mapping, bytes */
        xfs_off_t               iomap_bsize;    /* size of mapping, bytes */
-       size_t                  iomap_delta;    /* offset into mapping, bytes */
+       xfs_off_t               iomap_delta;    /* offset into mapping, bytes */
        iomap_flags_t           iomap_flags;
 } xfs_iomap_t;
 
index 8f285149681fcb6c03f05685502c1d036adb24be..4518b188ade69d5e1ff44f850f2a2a5e0e9fd768 100644 (file)
@@ -494,10 +494,8 @@ typedef struct log {
 
 #define XLOG_FORCED_SHUTDOWN(log)      ((log)->l_flags & XLOG_IO_ERROR)
 
-#define XLOG_GRANT_SUB_SPACE(log,bytes,type)   \
-       xlog_grant_sub_space(log,bytes,type)
-static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
-{
+#define XLOG_GRANT_SUB_SPACE(log,bytes,type)                           \
+    {                                                                  \
        if (type == 'w') {                                              \
                (log)->l_grant_write_bytes -= (bytes);                  \
                if ((log)->l_grant_write_bytes < 0) {                   \
@@ -511,13 +509,9 @@ static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
                        (log)->l_grant_reserve_cycle--;                 \
                }                                                       \
         }                                                              \
-}
-
-#define XLOG_GRANT_ADD_SPACE(log,bytes,type)   \
-       xlog_grant_add_space(log,bytes,type)
-static inline void
-xlog_grant_add_space(struct log *log, int bytes, int type)
-{
+    }
+#define XLOG_GRANT_ADD_SPACE(log,bytes,type)                           \
+    {                                                                  \
        if (type == 'w') {                                              \
                (log)->l_grant_write_bytes += (bytes);                  \
                if ((log)->l_grant_write_bytes > (log)->l_logsize) {    \
@@ -531,12 +525,9 @@ xlog_grant_add_space(struct log *log, int bytes, int type)
                        (log)->l_grant_reserve_cycle++;                 \
                }                                                       \
         }                                                              \
-}
-
-#define XLOG_INS_TICKETQ(q, tic)       xlog_ins_ticketq(q, tic)
-static inline void
-xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
-{                                                      \
+    }
+#define XLOG_INS_TICKETQ(q, tic)                       \
+    {                                                  \
        if (q) {                                        \
                (tic)->t_next       = (q);              \
                (tic)->t_prev       = (q)->t_prev;      \
@@ -547,12 +538,9 @@ xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
                (q) = (tic);                            \
        }                                               \
        (tic)->t_flags |= XLOG_TIC_IN_Q;                \
-}
-
-#define XLOG_DEL_TICKETQ(q, tic)       xlog_del_ticketq(q, tic)
-static inline void
-xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
-{                                                      \
+    }
+#define XLOG_DEL_TICKETQ(q, tic)                       \
+    {                                                  \
        if ((tic) == (tic)->t_next) {                   \
                (q) = NULL;                             \
        } else {                                        \
@@ -562,7 +550,7 @@ xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
        }                                               \
        (tic)->t_next = (tic)->t_prev = NULL;           \
        (tic)->t_flags &= ~XLOG_TIC_IN_Q;               \
-}
+    }
 
 /* common routines */
 extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
index 7c1f74531463bb11cac411322a6366420c822921..e03fa2a3d5ed4bb2af022b31c4bf0309c481d702 100644 (file)
@@ -3958,8 +3958,9 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
                                }
                        }
                        XFS_MOUNT_IUNLOCK(mp);
-                       xfs_finish_reclaim(ip, noblock,
-                               XFS_IFLUSH_DELWRI_ELSE_ASYNC);
+                       if (xfs_finish_reclaim(ip, noblock,
+                                       XFS_IFLUSH_DELWRI_ELSE_ASYNC))
+                               delay(1);
                        purged = 1;
                        break;
                }
index 5248ca054909e4c8a1314077b6303f0f7f021d48..685123981e8b291d9ab1865220ba221722e14bb0 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/config.h>
 #include <linux/threads.h>
+#include <linux/irq.h>
 
 typedef struct {
        unsigned int __softirq_pending;
index f9caecf7e3c0dd7f5b821336d2101a7647d841ed..ae031eaa3dd2a05705fca170524ec3cedad996c5 100644 (file)
 /*
  * some bits needed for parts of the IDE subsystem to compile
  */
-#define __ide_mm_insw(port, addr, n)   insw(port, addr, n)
-#define __ide_mm_insl(port, addr, n)   insl(port, addr, n)
-#define __ide_mm_outsw(port, addr, n)  outsw(port, addr, n)
-#define __ide_mm_outsl(port, addr, n)  outsl(port, addr, n)
+#define __ide_mm_insw(port, addr, n)   insw((unsigned long) (port), addr, n)
+#define __ide_mm_insl(port, addr, n)   insl((unsigned long) (port), addr, n)
+#define __ide_mm_outsw(port, addr, n)  outsw((unsigned long) (port), addr, n)
+#define __ide_mm_outsl(port, addr, n)  outsl((unsigned long) (port), addr, n)
 
 
 #endif /* __KERNEL__ */
index 4feba567e7fd7bd47601f3199285ba15e7ed9815..b8221b611b5c3cad5c1f54d004d410f1e4dc2e90 100644 (file)
@@ -47,8 +47,8 @@ typedef struct { unsigned long        pgprot; } pgprot_t;
 
 #define devmem_is_allowed(pfn) 1
 
-#define __pa(vaddr)            virt_to_phys((void *) vaddr)
-#define __va(paddr)            phys_to_virt((unsigned long) paddr)
+#define __pa(vaddr)            virt_to_phys((void *) (unsigned long) (vaddr))
+#define __va(paddr)            phys_to_virt((unsigned long) (paddr))
 
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
index b18396288df1a0475fe7d28d09189076e2fcf7e4..907c5c3643cced5eb8e3ecef3b33dd8a6607a213 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 
-#define SEMAPHORE_DEBUG                WAITQUEUE_DEBUG
+#define SEMAPHORE_DEBUG                0
 
 /*
  * the semaphore definition
index c8cba7836f0d2d2b79171235fd522cf7b21ae588..60f6b2aee76d7dc94666b4fc6e5bd24ef6a0e6e7 100644 (file)
@@ -58,7 +58,7 @@ struct thread_info {
 
 #endif
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
index bfff69a49936abdaae3b3d07dea3a8843cf6e39f..ef1fb8ea4726b0c7b3aea02db8d0fc40d4ee6cdf 100644 (file)
@@ -242,6 +242,27 @@ static __inline__ int atomic_dec_return(atomic_t *v)
  */
 #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)                             \
+({                                                             \
+       int c, old;                                             \
+       c = atomic_read(v);                                     \
+       while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+               c = old;                                        \
+       c != (u);                                               \
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static __inline__ void atomic_clear_mask(unsigned long  mask, atomic_t *addr)
 {
        unsigned long flags;
index 194393bd8beb8f07eee63a375211c34350efc603..f7aa96970d180c7389a272ea0b8b583ca1ca8325 100644 (file)
 # endif
 #endif
 
-#if defined(CONFIG_PLAT_M32700UT)
-#include <asm/irq.h>
-#include <asm/m32700ut/m32700ut_pld.h>
-#endif
+#include <asm/m32r.h>
+
 
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
 static __inline__ int ide_default_irq(unsigned long base)
 {
        switch (base) {
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2)
+               case 0x1f0: return PLD_IRQ_CFIREQ;
+               default:
+                       return 0;
+#elif defined(CONFIG_PLAT_MAPPI3)
                case 0x1f0: return PLD_IRQ_CFIREQ;
+               case 0x170: return PLD_IRQ_IDEIREQ;
                default:
                        return 0;
 #else
index 3f1551f7f01f16835d82f7cd85dca06dcdb154ac..1d3c25d61bcb2399e6f4def20b7ac16b2a911fd0 100644 (file)
@@ -59,7 +59,7 @@
 #define  M32R_IRQ_I2C          (28)  /* I2C-BUS     */
 #define  PLD_IRQ_CFIREQ       (6)  /* INT5 CFC Card Interrupt */
 #define  PLD_IRQ_CFC_INSERT   (7)  /* INT6 CFC Card Insert */
-#define  PLD_IRQ_CFC_EJECT    (8)  /* INT7 CFC Card Eject */
+#define  PLD_IRQ_IDEIREQ      (8)  /* INT7 IDE Interrupt   */
 #define  PLD_IRQ_MMCCARD      (43)  /* MMC Card Insert */
 #define  PLD_IRQ_MMCIRQ       (44)  /* MMC Transfer Done */
 
index 73348c3f858b673b73513e97d913cb4e265e38c6..5eee832b73a03e56beb8ce574c75f1ca74499eb4 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/assembler.h>
 
 #ifdef __KERNEL__
 
@@ -132,8 +133,6 @@ static inline void local_irq_disable(void)
                !(flags & 0x40);                        \
        })
 
-#endif  /* __KERNEL__ */
-
 #define nop()  __asm__ __volatile__ ("nop" : : )
 
 #define xchg(ptr,x) \
@@ -213,6 +212,67 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr,
        return (tmp);
 }
 
+#define __HAVE_ARCH_CMPXCHG    1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
+{
+       unsigned long flags;
+       unsigned int retval;
+
+       local_irq_save(flags);
+       __asm__ __volatile__ (
+                       DCACHE_CLEAR("%0", "r4", "%1")
+                       M32R_LOCK" %0, @%1;     \n"
+               "       bne     %0, %2, 1f;     \n"
+                       M32R_UNLOCK" %3, @%1;   \n"
+               "       bra     2f;             \n"
+                "       .fillinsn              \n"
+               "1:"
+                       M32R_UNLOCK" %2, @%1;   \n"
+                "       .fillinsn              \n"
+               "2:"
+                       : "=&r" (retval)
+                       : "r" (p), "r" (old), "r" (new)
+                       : "cbit", "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+                       , "r4"
+#endif  /* CONFIG_CHIP_M32700_TS1 */
+               );
+       local_irq_restore(flags);
+
+       return retval;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+       switch (size) {
+       case 4:
+               return __cmpxchg_u32(ptr, old, new);
+#if 0  /* we don't have __cmpxchg_u64 */
+       case 8:
+               return __cmpxchg_u64(ptr, old, new);
+#endif /* 0 */
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#define cmpxchg(ptr,o,n)                                                \
+  ({                                                                    \
+     __typeof__(*(ptr)) _o_ = (o);                                      \
+     __typeof__(*(ptr)) _n_ = (n);                                      \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
+                                   (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
+#endif  /* __KERNEL__ */
+
 /*
  * Memory barrier.
  *
index 6a35e6570ccd4ad9dd3691078609a1a1daadc585..f89f0605089378e6579f6b3710044fa70813a017 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
  * Rewrite, cleanup:
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 58a3dd9a79ec3f957f46ed5e84b768c65d44ecef..6642c012500177fc5e6f90a6ddf84e0cfa2e5ec5 100644 (file)
@@ -103,8 +103,9 @@ extern unsigned int HPAGE_SHIFT;
 #define HTLB_AREA_SIZE         (1UL << HTLB_AREA_SHIFT)
 #define GET_HTLB_AREA(x)       ((x) >> HTLB_AREA_SHIFT)
 
-#define LOW_ESID_MASK(addr, len)    (((1U << (GET_ESID(addr+len-1)+1)) \
-                                     - (1U << GET_ESID(addr))) & 0xffff)
+#define LOW_ESID_MASK(addr, len)    \
+       (((1U << (GET_ESID(min((addr)+(len)-1, 0x100000000UL))+1)) \
+         - (1U << GET_ESID(min((addr), 0x100000000UL)))) & 0xffff)
 #define HTLB_AREA_MASK(addr, len)   (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \
                                      - (1U << GET_HTLB_AREA(addr))) & 0xffff)
 
@@ -113,17 +114,21 @@ extern unsigned int HPAGE_SHIFT;
 #define ARCH_HAS_SETCLEAR_HUGE_PTE
 
 #define touches_hugepage_low_range(mm, addr, len) \
-       (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas)
+       (((addr) < 0x100000000UL) \
+        && (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas))
 #define touches_hugepage_high_range(mm, addr, len) \
-       (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas)
+       ((((addr) + (len)) > 0x100000000UL) \
+         && (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas))
 
 #define __within_hugepage_low_range(addr, len, segmask) \
-       ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask))
+       ( (((addr)+(len)) <= 0x100000000UL) \
+         && ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask)))
 #define within_hugepage_low_range(addr, len) \
        __within_hugepage_low_range((addr), (len), \
                                    current->mm->context.low_htlb_areas)
 #define __within_hugepage_high_range(addr, len, zonemask) \
-       ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask))
+       ( ((addr) >= 0x100000000UL) \
+         && ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask)))
 #define within_hugepage_high_range(addr, len) \
        __within_hugepage_high_range((addr), (len), \
                                    current->mm->context.high_htlb_areas)
index d099d5200f9bbb7ffea65a29535300289c7d84b9..980a094fd5a7201c488b26d577efa49f31e33dac 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
  * Rewrite, cleanup:
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9a02879b235db410cb6d3e465b080eee1daaba5d..f0a9b44d3eb5068c1c70b14520d25c4f5226974b 100644 (file)
@@ -348,16 +348,6 @@ extern unsigned long find_ecache_flush_span(unsigned long size);
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
-/* Make a non-present pseudo-TTE. */
-static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
-{
-       pte_t pte;
-       pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) &
-                       ~(unsigned long)_PAGE_CACHE);
-       pte_val(pte) |= (((unsigned long)space) << 32);
-       return pte;
-}
-
 /* Encode and de-code a swap entry */
 #define __swp_type(entry)      (((entry).val >> PAGE_SHIFT) & 0xffUL)
 #define __swp_offset(entry)    ((entry).val >> (PAGE_SHIFT + 8UL))
index 43c44530ef9dc02297c6a27e8478c80e7cbf5c79..0ed1d4853c69814530920c14b9c2bb6cee445b92 100644 (file)
@@ -65,10 +65,9 @@ extern struct sysdev_class cpu_sysdev_class;
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* Stop CPUs going up and down. */
-extern struct semaphore cpucontrol;
-#define lock_cpu_hotplug()     down(&cpucontrol)
-#define unlock_cpu_hotplug()   up(&cpucontrol)
-#define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol)
+extern void lock_cpu_hotplug(void);
+extern void unlock_cpu_hotplug(void);
+extern int lock_cpu_hotplug_interruptible(void);
 #define hotcpu_notifier(fn, pri) {                             \
        static struct notifier_block fn##_nb =                  \
                { .notifier_call = fn, .priority = pri };       \
index 9a424383e6c60064fdb76ae8b0c7895351da69a0..dc4081b6f161e3f697c3280bbf9547aed9bfbea1 100644 (file)
@@ -85,7 +85,6 @@ struct notifier_block;
 extern int register_memory_notifier(struct notifier_block *nb);
 extern void unregister_memory_notifier(struct notifier_block *nb);
 
-extern struct sysdev_class memory_sysdev_class;
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 #define hotplug_memory_notifier(fn, pri) {                     \
index f0cdfd18db55b7edfe3af313dbf4cd9bcca22f70..6a75a7a78bf1b6ee5ec87f95a0b6fa8addaca1f1 100644 (file)
@@ -145,7 +145,7 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_GROWSDOWN   0x00000100      /* general info on the segment */
 #define VM_GROWSUP     0x00000200
 #define VM_SHM         0x00000000      /* Means nothing: delete it later */
-#define VM_UNPAGED     0x00000400      /* Pages managed without map count */
+#define VM_PFNMAP      0x00000400      /* Page-ranges managed without "struct page", just pure PFN */
 #define VM_DENYWRITE   0x00000800      /* ETXTBSY on write attempts.. */
 
 #define VM_EXECUTABLE  0x00001000
@@ -664,6 +664,7 @@ struct zap_details {
        unsigned long truncate_count;           /* Compare vm_truncate_count */
 };
 
+struct page *vm_normal_page(struct vm_area_struct *, unsigned long, pte_t);
 unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
                unsigned long size, struct zap_details *);
 unsigned long unmap_vmas(struct mmu_gather **tlb,
@@ -953,7 +954,7 @@ unsigned long vmalloc_to_pfn(void *addr);
 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
                        unsigned long pfn, unsigned long size, pgprot_t);
 
-struct page *follow_page(struct mm_struct *, unsigned long address,
+struct page *follow_page(struct vm_area_struct *, unsigned long address,
                        unsigned int foll_flags);
 #define FOLL_WRITE     0x01    /* check pte is writable */
 #define FOLL_TOUCH     0x02    /* mark page accessed */
index 35b30e6c8cf8c7b0b4fb4bd09c11b154a45c6ba6..33261f1d22395fba7d9a54a45efcaff12493336d 100644 (file)
@@ -89,7 +89,7 @@ static inline void page_dup_rmap(struct page *page)
 /*
  * Called from mm/vmscan.c to handle paging out
  */
-int page_referenced(struct page *, int is_locked, int ignore_token);
+int page_referenced(struct page *, int is_locked);
 int try_to_unmap(struct page *);
 
 /*
@@ -109,7 +109,7 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *);
 #define anon_vma_prepare(vma)  (0)
 #define anon_vma_link(vma)     do {} while (0)
 
-#define page_referenced(page,l,i) TestClearPageReferenced(page)
+#define page_referenced(page,l) TestClearPageReferenced(page)
 #define try_to_unmap(page)     SWAP_FAIL
 
 #endif /* CONFIG_MMU */
index 2038bd27b0413c74bcb66290adc3cfe33b5c0fd3..b0ad6f30679eac4cd128f924bd8b1010b4c75be1 100644 (file)
@@ -908,7 +908,6 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
 #define PF_SYNCWRITE   0x00200000      /* I am doing a sync write */
 #define PF_BORROWED_MM 0x00400000      /* I am a kthread doing use_mm */
 #define PF_RANDOMIZE   0x00800000      /* randomize virtual address space */
-#define PF_HOTPLUG_CPU 0x01000000      /* Currently performing CPU hotplug */
 
 /*
  * Only the _current_ task can read/write to tsk->flags, but other
index 20c975642cab4c7f17e1cd9c8b2a6b9a2938aa03..508668f840b6a072998ce931bfc492a68c83f473 100644 (file)
@@ -239,6 +239,11 @@ static inline void put_swap_token(struct mm_struct *mm)
                __put_swap_token(mm);
 }
 
+static inline void disable_swap_token(void)
+{
+       put_swap_token(swap_token_mm);
+}
+
 #else /* CONFIG_SWAP */
 
 #define total_swap_pages                       0
@@ -283,6 +288,7 @@ static inline swp_entry_t get_swap_page(void)
 #define put_swap_token(x) do { } while(0)
 #define grab_swap_token()  do { } while(0)
 #define has_swap_token(x) 0
+#define disable_swap_token() do { } while(0)
 
 #endif /* CONFIG_SWAP */
 #endif /* __KERNEL__*/
index d61ba88f34e57b90edae90342ed1db59ebfbb59c..e882c6babf414854a53b615229e49005d3cc4d75 100644 (file)
 #include <asm/semaphore.h>
 
 /* This protects CPUs going up and down... */
-DECLARE_MUTEX(cpucontrol);
-EXPORT_SYMBOL_GPL(cpucontrol);
+static DECLARE_MUTEX(cpucontrol);
 
 static struct notifier_block *cpu_chain;
 
-/*
- * Used to check by callers if they need to acquire the cpucontrol
- * or not to protect a cpu from being removed. Its sometimes required to
- * call these functions both for normal operations, and in response to
- * a cpu being added/removed. If the context of the call is in the same
- * thread context as a CPU hotplug thread, we dont need to take the lock
- * since its already protected
- * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj
- */
+#ifdef CONFIG_HOTPLUG_CPU
+static struct task_struct *lock_cpu_hotplug_owner;
+static int lock_cpu_hotplug_depth;
 
-int current_in_cpu_hotplug(void)
+static int __lock_cpu_hotplug(int interruptible)
 {
-       return (current->flags & PF_HOTPLUG_CPU);
+       int ret = 0;
+
+       if (lock_cpu_hotplug_owner != current) {
+               if (interruptible)
+                       ret = down_interruptible(&cpucontrol);
+               else
+                       down(&cpucontrol);
+       }
+
+       /*
+        * Set only if we succeed in locking
+        */
+       if (!ret) {
+               lock_cpu_hotplug_depth++;
+               lock_cpu_hotplug_owner = current;
+       }
+
+       return ret;
 }
 
-EXPORT_SYMBOL_GPL(current_in_cpu_hotplug);
+void lock_cpu_hotplug(void)
+{
+       __lock_cpu_hotplug(0);
+}
+EXPORT_SYMBOL_GPL(lock_cpu_hotplug);
 
+void unlock_cpu_hotplug(void)
+{
+       if (--lock_cpu_hotplug_depth == 0) {
+               lock_cpu_hotplug_owner = NULL;
+               up(&cpucontrol);
+       }
+}
+EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
+
+int lock_cpu_hotplug_interruptible(void)
+{
+       return __lock_cpu_hotplug(1);
+}
+EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible);
+#endif /* CONFIG_HOTPLUG_CPU */
 
 /* Need to know about CPUs going up/down? */
 int register_cpu_notifier(struct notifier_block *nb)
 {
        int ret;
 
-       if ((ret = down_interruptible(&cpucontrol)) != 0)
+       if ((ret = lock_cpu_hotplug_interruptible()) != 0)
                return ret;
        ret = notifier_chain_register(&cpu_chain, nb);
-       up(&cpucontrol);
+       unlock_cpu_hotplug();
        return ret;
 }
 EXPORT_SYMBOL(register_cpu_notifier);
 
 void unregister_cpu_notifier(struct notifier_block *nb)
 {
-       down(&cpucontrol);
+       lock_cpu_hotplug();
        notifier_chain_unregister(&cpu_chain, nb);
-       up(&cpucontrol);
+       unlock_cpu_hotplug();
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
@@ -112,13 +141,6 @@ int cpu_down(unsigned int cpu)
                goto out;
        }
 
-       /*
-        * Leave a trace in current->flags indicating we are already in
-        * process of performing CPU hotplug. Callers can check if cpucontrol
-        * is already acquired by current thread, and if so not cause
-        * a dead lock by not acquiring the lock
-        */
-       current->flags |= PF_HOTPLUG_CPU;
        err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
                                                (void *)(long)cpu);
        if (err == NOTIFY_BAD) {
@@ -171,7 +193,6 @@ out_thread:
 out_allowed:
        set_cpus_allowed(current, old_allowed);
 out:
-       current->flags &= ~PF_HOTPLUG_CPU;
        unlock_cpu_hotplug();
        return err;
 }
@@ -182,7 +203,7 @@ int __devinit cpu_up(unsigned int cpu)
        int ret;
        void *hcpu = (void *)(long)cpu;
 
-       if ((ret = down_interruptible(&cpucontrol)) != 0)
+       if ((ret = lock_cpu_hotplug_interruptible()) != 0)
                return ret;
 
        if (cpu_online(cpu) || !cpu_present(cpu)) {
@@ -190,11 +211,6 @@ int __devinit cpu_up(unsigned int cpu)
                goto out;
        }
 
-       /*
-        * Leave a trace in current->flags indicating we are already in
-        * process of performing CPU hotplug.
-        */
-       current->flags |= PF_HOTPLUG_CPU;
        ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
        if (ret == NOTIFY_BAD) {
                printk("%s: attempt to bring up CPU %u failed\n",
@@ -217,7 +233,6 @@ out_notify:
        if (ret != 0)
                notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
 out:
-       current->flags &= ~PF_HOTPLUG_CPU;
-       up(&cpucontrol);
+       unlock_cpu_hotplug();
        return ret;
 }
index 1c1cf8dc396be6ddebca4c663a9eb234d56cb0cc..fb8572a4229743baef22241dbab6ae8356f633c7 100644 (file)
@@ -1124,8 +1124,6 @@ static task_t *copy_process(unsigned long clone_flags,
        if (unlikely(p->ptrace & PT_PTRACED))
                __ptrace_link(p, current->parent);
 
-       cpuset_fork(p);
-
        attach_pid(p, PIDTYPE_PID, p->pid);
        attach_pid(p, PIDTYPE_TGID, p->tgid);
        if (thread_group_leader(p)) {
@@ -1135,13 +1133,14 @@ static task_t *copy_process(unsigned long clone_flags,
                        __get_cpu_var(process_counts)++;
        }
 
-       proc_fork_connector(p);
        if (!current->signal->tty && p->signal->tty)
                p->signal->tty = NULL;
 
        nr_threads++;
        total_forks++;
        write_unlock_irq(&tasklist_lock);
+       proc_fork_connector(p);
+       cpuset_fork(p);
        retval = 0;
 
 fork_out:
index 84af54c39e1b0c31ff32854b45cbb15a512a4ba5..cae4f572899714369bcd8d5d18dad16f84d690a4 100644 (file)
@@ -36,7 +36,7 @@ timespec_to_sample(clockid_t which_clock, const struct timespec *tp)
        union cpu_time_count ret;
        ret.sched = 0;          /* high half always zero when .cpu used */
        if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
-               ret.sched = tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
+               ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
        } else {
                ret.cpu = timespec_to_cputime(tp);
        }
index 42df83d7fad21d7176efdfef13282ef693f3c6ba..2bd5aee1c7369af14c8f8ba71a9715ad6f03346b 100644 (file)
@@ -102,7 +102,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
 
        if (!test_and_set_bit(0, &work->pending)) {
                if (unlikely(is_single_threaded(wq)))
-                       cpu = 0;
+                       cpu = any_online_cpu(cpu_online_map);
                BUG_ON(!list_empty(&work->entry));
                __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
                ret = 1;
@@ -118,7 +118,7 @@ static void delayed_work_timer_fn(unsigned long __data)
        int cpu = smp_processor_id();
 
        if (unlikely(is_single_threaded(wq)))
-               cpu = 0;
+               cpu = any_online_cpu(cpu_online_map);
 
        __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
 }
@@ -266,8 +266,8 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
        might_sleep();
 
        if (is_single_threaded(wq)) {
-               /* Always use cpu 0's area. */
-               flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
+               /* Always use first cpu's area. */
+               flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, any_online_cpu(cpu_online_map)));
        } else {
                int cpu;
 
@@ -320,7 +320,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
        lock_cpu_hotplug();
        if (singlethread) {
                INIT_LIST_HEAD(&wq->list);
-               p = create_workqueue_thread(wq, 0);
+               p = create_workqueue_thread(wq, any_online_cpu(cpu_online_map));
                if (!p)
                        destroy = 1;
                else
@@ -374,7 +374,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
        /* We don't need the distraction of CPUs appearing and vanishing. */
        lock_cpu_hotplug();
        if (is_single_threaded(wq))
-               cleanup_workqueue_thread(wq, 0);
+               cleanup_workqueue_thread(wq, any_online_cpu(cpu_online_map));
        else {
                for_each_online_cpu(cpu)
                        cleanup_workqueue_thread(wq, cpu);
index d6d30d2e71664629304bc4795b533fbb89914e11..9ce0a6a3b85ac49d2f160dda9c732ec65698f078 100644 (file)
@@ -95,12 +95,10 @@ unsigned long gen_pool_alloc(struct gen_pool *poolp, int size)
        if (size > max_chunk_size)
                return 0;
 
-       i = 0;
-
        size = max(size, 1 << ALLOC_MIN_SHIFT);
-       s = roundup_pow_of_two(size);
-
-       j = i;
+       i = fls(size - 1);
+       s = 1 << i;
+       j = i -= ALLOC_MIN_SHIFT;
 
        spin_lock_irqsave(&poolp->lock, flags);
        while (!h[j].next) {
@@ -153,10 +151,10 @@ void gen_pool_free(struct gen_pool *poolp, unsigned long ptr, int size)
        if (size > max_chunk_size)
                return;
 
-       i = 0;
-
        size = max(size, 1 << ALLOC_MIN_SHIFT);
-       s = roundup_pow_of_two(size);
+       i = fls(size - 1);
+       s = 1 << i;
+       i -= ALLOC_MIN_SHIFT;
 
        a = ptr;
 
index 007cbad9331e208f37713148707843aeae105079..f851775e09c2a27f66763ef9e239c025f2ae8c6a 100644 (file)
@@ -27,24 +27,20 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
        struct page *page = NULL;
 
        if (pte_present(pte)) {
-               unsigned long pfn = pte_pfn(pte);
-               flush_cache_page(vma, addr, pfn);
+               flush_cache_page(vma, addr, pte_pfn(pte));
                pte = ptep_clear_flush(vma, addr, ptep);
-               if (unlikely(!pfn_valid(pfn))) {
-                       print_bad_pte(vma, pte, addr);
-                       goto out;
+               page = vm_normal_page(vma, addr, pte);
+               if (page) {
+                       if (pte_dirty(pte))
+                               set_page_dirty(page);
+                       page_remove_rmap(page);
+                       page_cache_release(page);
                }
-               page = pfn_to_page(pfn);
-               if (pte_dirty(pte))
-                       set_page_dirty(page);
-               page_remove_rmap(page);
-               page_cache_release(page);
        } else {
                if (!pte_file(pte))
                        free_swap_and_cache(pte_to_swp_entry(pte));
                pte_clear(mm, addr, ptep);
        }
-out:
        return !!page;
 }
 
@@ -65,8 +61,6 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
        pte_t pte_val;
        spinlock_t *ptl;
 
-       BUG_ON(vma->vm_flags & VM_UNPAGED);
-
        pgd = pgd_offset(mm, addr);
        pud = pud_alloc(mm, pgd, addr);
        if (!pud)
@@ -122,8 +116,6 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
        pte_t pte_val;
        spinlock_t *ptl;
 
-       BUG_ON(vma->vm_flags & VM_UNPAGED);
-
        pgd = pgd_offset(mm, addr);
        pud = pud_alloc(mm, pgd, addr);
        if (!pud)
index 328a3bcce5271ee969e231962354159227da9eba..2b7cf0400a217cd453641eaf097d1291125e1431 100644 (file)
@@ -126,7 +126,7 @@ static long madvise_dontneed(struct vm_area_struct * vma,
                             unsigned long start, unsigned long end)
 {
        *prev = vma;
-       if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_UNPAGED))
+       if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
                return -EINVAL;
 
        if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
index d1f46f4e4c8a8594ffa649f15dd03d6cd6eda944..9ab206b829a2f4a55a3be143ba5e4440dc30cb1e 100644 (file)
@@ -333,9 +333,9 @@ static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
 }
 
 /*
- * This function is called to print an error when a pte in a
- * !VM_UNPAGED region is found pointing to an invalid pfn (which
- * is an error.
+ * This function is called to print an error when a bad pte
+ * is found. For example, we might have a PFN-mapped pte in
+ * a region that doesn't allow it.
  *
  * The calling function must still handle the error.
  */
@@ -350,19 +350,56 @@ void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr)
 }
 
 /*
- * page_is_anon applies strict checks for an anonymous page belonging to
- * this vma at this address.  It is used on VM_UNPAGED vmas, which are
- * usually populated with shared originals (which must not be counted),
- * but occasionally contain private COWed copies (when !VM_SHARED, or
- * perhaps via ptrace when VM_SHARED).  An mmap of /dev/mem might window
- * free pages, pages from other processes, or from other parts of this:
- * it's tricky, but try not to be deceived by foreign anonymous pages.
+ * This function gets the "struct page" associated with a pte.
+ *
+ * NOTE! Some mappings do not have "struct pages". A raw PFN mapping
+ * will have each page table entry just pointing to a raw page frame
+ * number, and as far as the VM layer is concerned, those do not have
+ * pages associated with them - even if the PFN might point to memory
+ * that otherwise is perfectly fine and has a "struct page".
+ *
+ * The way we recognize those mappings is through the rules set up
+ * by "remap_pfn_range()": the vma will have the VM_PFNMAP bit set,
+ * and the vm_pgoff will point to the first PFN mapped: thus every
+ * page that is a raw mapping will always honor the rule
+ *
+ *     pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT)
+ *
+ * and if that isn't true, the page has been COW'ed (in which case it
+ * _does_ have a "struct page" associated with it even if it is in a
+ * VM_PFNMAP range).
  */
-static inline int page_is_anon(struct page *page,
-                       struct vm_area_struct *vma, unsigned long addr)
+struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
-       return page && PageAnon(page) && page_mapped(page) &&
-               page_address_in_vma(page, vma) == addr;
+       unsigned long pfn = pte_pfn(pte);
+
+       if (vma->vm_flags & VM_PFNMAP) {
+               unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
+               if (pfn == vma->vm_pgoff + off)
+                       return NULL;
+       }
+
+       /*
+        * Add some anal sanity checks for now. Eventually,
+        * we should just do "return pfn_to_page(pfn)", but
+        * in the meantime we check that we get a valid pfn,
+        * and that the resulting page looks ok.
+        *
+        * Remove this test eventually!
+        */
+       if (unlikely(!pfn_valid(pfn))) {
+               print_bad_pte(vma, pte, addr);
+               return NULL;
+       }
+
+       /*
+        * NOTE! We still have PageReserved() pages in the page 
+        * tables. 
+        *
+        * The PAGE_ZERO() pages and various VDSO mappings can
+        * cause them to exist.
+        */
+       return pfn_to_page(pfn);
 }
 
 /*
@@ -379,7 +416,6 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
        unsigned long vm_flags = vma->vm_flags;
        pte_t pte = *src_pte;
        struct page *page;
-       unsigned long pfn;
 
        /* pte contains position in swap or file, so copy. */
        if (unlikely(!pte_present(pte))) {
@@ -397,22 +433,6 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
                goto out_set_pte;
        }
 
-       pfn = pte_pfn(pte);
-       page = pfn_valid(pfn)? pfn_to_page(pfn): NULL;
-
-       if (unlikely(vm_flags & VM_UNPAGED))
-               if (!page_is_anon(page, vma, addr))
-                       goto out_set_pte;
-
-       /*
-        * If the pte points outside of valid memory but
-        * the region is not VM_UNPAGED, we have a problem.
-        */
-       if (unlikely(!page)) {
-               print_bad_pte(vma, pte, addr);
-               goto out_set_pte; /* try to do something sane */
-       }
-
        /*
         * If it's a COW mapping, write protect it both
         * in the parent and the child
@@ -429,9 +449,13 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
        if (vm_flags & VM_SHARED)
                pte = pte_mkclean(pte);
        pte = pte_mkold(pte);
-       get_page(page);
-       page_dup_rmap(page);
-       rss[!!PageAnon(page)]++;
+
+       page = vm_normal_page(vma, addr, pte);
+       if (page) {
+               get_page(page);
+               page_dup_rmap(page);
+               rss[!!PageAnon(page)]++;
+       }
 
 out_set_pte:
        set_pte_at(dst_mm, addr, dst_pte, pte);
@@ -543,7 +567,7 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
         * readonly mappings. The tradeoff is that copy_page_range is more
         * efficient than faulting.
         */
-       if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_UNPAGED))) {
+       if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP))) {
                if (!vma->anon_vma)
                        return 0;
        }
@@ -584,19 +608,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
                }
                if (pte_present(ptent)) {
                        struct page *page;
-                       unsigned long pfn;
 
                        (*zap_work) -= PAGE_SIZE;
 
-                       pfn = pte_pfn(ptent);
-                       page = pfn_valid(pfn)? pfn_to_page(pfn): NULL;
-
-                       if (unlikely(vma->vm_flags & VM_UNPAGED)) {
-                               if (!page_is_anon(page, vma, addr))
-                                       page = NULL;
-                       } else if (unlikely(!page))
-                               print_bad_pte(vma, ptent, addr);
-
+                       page = vm_normal_page(vma, addr, ptent);
                        if (unlikely(details) && page) {
                                /*
                                 * unmap_shared_mapping_pages() wants to
@@ -852,7 +867,7 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
 /*
  * Do a quick page-table lookup for a single page.
  */
-struct page *follow_page(struct mm_struct *mm, unsigned long address,
+struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                        unsigned int flags)
 {
        pgd_t *pgd;
@@ -860,8 +875,8 @@ struct page *follow_page(struct mm_struct *mm, unsigned long address,
        pmd_t *pmd;
        pte_t *ptep, pte;
        spinlock_t *ptl;
-       unsigned long pfn;
        struct page *page;
+       struct mm_struct *mm = vma->vm_mm;
 
        page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
        if (!IS_ERR(page)) {
@@ -897,11 +912,10 @@ struct page *follow_page(struct mm_struct *mm, unsigned long address,
                goto unlock;
        if ((flags & FOLL_WRITE) && !pte_write(pte))
                goto unlock;
-       pfn = pte_pfn(pte);
-       if (!pfn_valid(pfn))
+       page = vm_normal_page(vma, address, pte);
+       if (unlikely(!page))
                goto unlock;
 
-       page = pfn_to_page(pfn);
        if (flags & FOLL_GET)
                get_page(page);
        if (flags & FOLL_TOUCH) {
@@ -974,8 +988,10 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                return i ? : -EFAULT;
                        }
                        if (pages) {
-                               pages[i] = pte_page(*pte);
-                               get_page(pages[i]);
+                               struct page *page = vm_normal_page(vma, start, *pte);
+                               pages[i] = page;
+                               if (page)
+                                       get_page(page);
                        }
                        pte_unmap(pte);
                        if (vmas)
@@ -1010,7 +1026,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                foll_flags |= FOLL_WRITE;
 
                        cond_resched();
-                       while (!(page = follow_page(mm, start, foll_flags))) {
+                       while (!(page = follow_page(vma, start, foll_flags))) {
                                int ret;
                                ret = __handle_mm_fault(mm, vma, start,
                                                foll_flags & FOLL_WRITE);
@@ -1214,11 +1230,12 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
         *      in 2.6 the LRU scan won't even find its pages, so this
         *      flag means no more than count its pages in reserved_vm,
         *      and omit it from core dump, even when VM_IO turned off.
-        *   VM_UNPAGED tells the core MM not to "manage" these pages
-         *     (e.g. refcount, mapcount, try to swap them out): in
-        *      particular, zap_pte_range does not try to free them.
+        *   VM_PFNMAP tells the core MM that the base pages are just
+        *      raw PFN mappings, and do not have a "struct page" associated
+        *      with them.
         */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       vma->vm_pgoff = pfn;
 
        BUG_ON(addr >= end);
        pfn -= addr >> PAGE_SHIFT;
@@ -1273,6 +1290,26 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
        return pte;
 }
 
+static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va)
+{
+       /*
+        * If the source page was a PFN mapping, we don't have
+        * a "struct page" for it. We do a best-effort copy by
+        * just copying from the original user address. If that
+        * fails, we just zero-fill it. Live with it.
+        */
+       if (unlikely(!src)) {
+               void *kaddr = kmap_atomic(dst, KM_USER0);
+               unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE);
+               if (left)
+                       memset(kaddr, 0, PAGE_SIZE);
+               kunmap_atomic(kaddr, KM_USER0);
+               return;
+               
+       }
+       copy_user_highpage(dst, src, va);
+}
+
 /*
  * This routine handles present pages, when users try to write
  * to a shared page. It is done by copying the page to a new address
@@ -1296,28 +1333,13 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                spinlock_t *ptl, pte_t orig_pte)
 {
        struct page *old_page, *src_page, *new_page;
-       unsigned long pfn = pte_pfn(orig_pte);
        pte_t entry;
        int ret = VM_FAULT_MINOR;
 
-       if (unlikely(!pfn_valid(pfn))) {
-               /*
-                * Page table corrupted: show pte and kill process.
-                * Or it's an attempt to COW an out-of-map VM_UNPAGED
-                * entry, which copy_user_highpage does not support.
-                */
-               print_bad_pte(vma, orig_pte, address);
-               ret = VM_FAULT_OOM;
-               goto unlock;
-       }
-       old_page = pfn_to_page(pfn);
+       old_page = vm_normal_page(vma, address, orig_pte);
        src_page = old_page;
-
-       if (unlikely(vma->vm_flags & VM_UNPAGED))
-               if (!page_is_anon(old_page, vma, address)) {
-                       old_page = NULL;
-                       goto gotten;
-               }
+       if (!old_page)
+               goto gotten;
 
        if (PageAnon(old_page) && !TestSetPageLocked(old_page)) {
                int reuse = can_share_swap_page(old_page);
@@ -1351,7 +1373,7 @@ gotten:
                new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
                if (!new_page)
                        goto oom;
-               copy_user_highpage(new_page, src_page, address);
+               cow_user_page(new_page, src_page, address);
        }
 
        /*
@@ -1812,16 +1834,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
        spinlock_t *ptl;
        pte_t entry;
 
-       /*
-        * A VM_UNPAGED vma will normally be filled with present ptes
-        * by remap_pfn_range, and never arrive here; but it might have
-        * holes, or if !VM_DONTEXPAND, mremap might have expanded it.
-        * It's weird enough handling anon pages in unpaged vmas, we do
-        * not want to worry about ZERO_PAGEs too (it may or may not
-        * matter if their counts wrap): just give them anon pages.
-        */
-
-       if (write_access || (vma->vm_flags & VM_UNPAGED)) {
+       if (write_access) {
                /* Allocate our own private page. */
                pte_unmap(page_table);
 
@@ -1896,8 +1909,6 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
        int anon = 0;
 
        pte_unmap(page_table);
-       BUG_ON(vma->vm_flags & VM_UNPAGED);
-
        if (vma->vm_file) {
                mapping = vma->vm_file->f_mapping;
                sequence = mapping->truncate_count;
@@ -1930,7 +1941,7 @@ retry:
                page = alloc_page_vma(GFP_HIGHUSER, vma, address);
                if (!page)
                        goto oom;
-               copy_user_highpage(page, new_page, address);
+               cow_user_page(page, new_page, address);
                page_cache_release(new_page);
                new_page = page;
                anon = 1;
@@ -2149,6 +2160,12 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
        spin_unlock(&mm->page_table_lock);
        return 0;
 }
+#else
+/* Workaround for gcc 2.96 */
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+{
+       return 0;
+}
 #endif /* __PAGETABLE_PUD_FOLDED */
 
 #ifndef __PAGETABLE_PMD_FOLDED
@@ -2177,6 +2194,12 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
        spin_unlock(&mm->page_table_lock);
        return 0;
 }
+#else
+/* Workaround for gcc 2.96 */
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+{
+       return 0;
+}
 #endif /* __PAGETABLE_PMD_FOLDED */
 
 int make_pages_present(unsigned long addr, unsigned long end)
index 5609a31bdf229e51300474764c320d0404767fe5..bec88c81244e0d4f9541f4098f5f8c8409ba455b 100644 (file)
@@ -189,17 +189,15 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 
        orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
        do {
-               unsigned long pfn;
+               struct page *page;
                unsigned int nid;
 
                if (!pte_present(*pte))
                        continue;
-               pfn = pte_pfn(*pte);
-               if (!pfn_valid(pfn)) {
-                       print_bad_pte(vma, *pte, addr);
+               page = vm_normal_page(vma, addr, *pte);
+               if (!page)
                        continue;
-               }
-               nid = pfn_to_nid(pfn);
+               nid = page_to_nid(page);
                if (!node_isset(nid, *nodes))
                        break;
        } while (pte++, addr += PAGE_SIZE, addr != end);
@@ -269,8 +267,6 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
        first = find_vma(mm, start);
        if (!first)
                return ERR_PTR(-EFAULT);
-       if (first->vm_flags & VM_UNPAGED)
-               return ERR_PTR(-EACCES);
        prev = NULL;
        for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
                if (!vma->vm_next && vma->vm_end < end)
index b3f4caf3010b3ae998e456ba99faeff335623e07..1b5b6f662dcfd40e3c27122a58c2c1a17e93e295 100644 (file)
@@ -27,7 +27,6 @@ static void msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 again:
        pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
        do {
-               unsigned long pfn;
                struct page *page;
 
                if (progress >= 64) {
@@ -40,13 +39,9 @@ again:
                        continue;
                if (!pte_maybe_dirty(*pte))
                        continue;
-               pfn = pte_pfn(*pte);
-               if (unlikely(!pfn_valid(pfn))) {
-                       print_bad_pte(vma, *pte, addr);
+               page = vm_normal_page(vma, addr, *pte);
+               if (!page)
                        continue;
-               }
-               page = pfn_to_page(pfn);
-
                if (ptep_clear_flush_dirty(vma, addr, pte) ||
                    page_test_and_clear_dirty(page))
                        set_page_dirty(page);
@@ -97,9 +92,8 @@ static void msync_page_range(struct vm_area_struct *vma,
        /* For hugepages we can't go walking the page table normally,
         * but that's ok, hugetlbfs is memory based, so we don't need
         * to do anything more on an msync().
-        * Can't do anything with VM_UNPAGED regions either.
         */
-       if (vma->vm_flags & (VM_HUGETLB|VM_UNPAGED))
+       if (vma->vm_flags & VM_HUGETLB)
                return;
 
        BUG_ON(addr >= end);
index 6deb6ab3d6ada1a27cfcbc65303fa1403d498ac0..c1196812876be984920118078fd817dccbf771f8 100644 (file)
@@ -1045,7 +1045,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
 
 EXPORT_SYMBOL(find_vma);
 
-struct page *follow_page(struct mm_struct *mm, unsigned long address,
+struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                        unsigned int foll_flags)
 {
        return NULL;
index 1731236dec352ffd9dc3e21e11cc9ce27bd9bde2..b257720edfc83ce4d025159d05c82354b9dd220b 100644 (file)
@@ -773,9 +773,12 @@ again:
 }
 
 #define ALLOC_NO_WATERMARKS    0x01 /* don't check watermarks at all */
-#define ALLOC_HARDER           0x02 /* try to alloc harder */
-#define ALLOC_HIGH             0x04 /* __GFP_HIGH set */
-#define ALLOC_CPUSET           0x08 /* check for correct cpuset */
+#define ALLOC_WMARK_MIN                0x02 /* use pages_min watermark */
+#define ALLOC_WMARK_LOW                0x04 /* use pages_low watermark */
+#define ALLOC_WMARK_HIGH       0x08 /* use pages_high watermark */
+#define ALLOC_HARDER           0x10 /* try to alloc harder */
+#define ALLOC_HIGH             0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET           0x40 /* check for correct cpuset */
 
 /*
  * Return 1 if free pages are above 'mark'. This takes into account the order
@@ -830,7 +833,14 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order,
                        continue;
 
                if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
-                       if (!zone_watermark_ok(*z, order, (*z)->pages_low,
+                       unsigned long mark;
+                       if (alloc_flags & ALLOC_WMARK_MIN)
+                               mark = (*z)->pages_min;
+                       else if (alloc_flags & ALLOC_WMARK_LOW)
+                               mark = (*z)->pages_low;
+                       else
+                               mark = (*z)->pages_high;
+                       if (!zone_watermark_ok(*z, order, mark,
                                    classzone_idx, alloc_flags))
                                continue;
                }
@@ -871,7 +881,7 @@ restart:
        }
 
        page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
-                               zonelist, ALLOC_CPUSET);
+                               zonelist, ALLOC_WMARK_LOW|ALLOC_CPUSET);
        if (page)
                goto got_pg;
 
@@ -888,7 +898,7 @@ restart:
         * cannot run direct reclaim, or if the caller has realtime scheduling
         * policy.
         */
-       alloc_flags = 0;
+       alloc_flags = ALLOC_WMARK_MIN;
        if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait)
                alloc_flags |= ALLOC_HARDER;
        if (gfp_mask & __GFP_HIGH)
@@ -959,7 +969,7 @@ rebalance:
                 * under heavy pressure.
                 */
                page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
-                                               zonelist, ALLOC_CPUSET);
+                               zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
                if (page)
                        goto got_pg;
 
index 2e034a0b89abff5ccc2bc310255f18c6e5ac165c..491ac350048f2546c8aa5c09a2f7356a46e22993 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -226,8 +226,6 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 /*
  * At what user virtual address is page expected in vma? checking that the
  * page matches the vma: currently only used on anon pages, by unuse_vma;
- * and by extraordinary checks on anon pages in VM_UNPAGED vmas, taking
- * care that an mmap of /dev/mem might window free and foreign pages.
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
@@ -292,7 +290,7 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm,
  * repeatedly from either page_referenced_anon or page_referenced_file.
  */
 static int page_referenced_one(struct page *page,
-       struct vm_area_struct *vma, unsigned int *mapcount, int ignore_token)
+       struct vm_area_struct *vma, unsigned int *mapcount)
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long address;
@@ -313,7 +311,7 @@ static int page_referenced_one(struct page *page,
 
        /* Pretend the page is referenced if the task has the
           swap token and is in the middle of a page fault. */
-       if (mm != current->mm && !ignore_token && has_swap_token(mm) &&
+       if (mm != current->mm && has_swap_token(mm) &&
                        rwsem_is_locked(&mm->mmap_sem))
                referenced++;
 
@@ -323,7 +321,7 @@ out:
        return referenced;
 }
 
-static int page_referenced_anon(struct page *page, int ignore_token)
+static int page_referenced_anon(struct page *page)
 {
        unsigned int mapcount;
        struct anon_vma *anon_vma;
@@ -336,8 +334,7 @@ static int page_referenced_anon(struct page *page, int ignore_token)
 
        mapcount = page_mapcount(page);
        list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
-               referenced += page_referenced_one(page, vma, &mapcount,
-                                                       ignore_token);
+               referenced += page_referenced_one(page, vma, &mapcount);
                if (!mapcount)
                        break;
        }
@@ -356,7 +353,7 @@ static int page_referenced_anon(struct page *page, int ignore_token)
  *
  * This function is only called from page_referenced for object-based pages.
  */
-static int page_referenced_file(struct page *page, int ignore_token)
+static int page_referenced_file(struct page *page)
 {
        unsigned int mapcount;
        struct address_space *mapping = page->mapping;
@@ -394,8 +391,7 @@ static int page_referenced_file(struct page *page, int ignore_token)
                        referenced++;
                        break;
                }
-               referenced += page_referenced_one(page, vma, &mapcount,
-                                                       ignore_token);
+               referenced += page_referenced_one(page, vma, &mapcount);
                if (!mapcount)
                        break;
        }
@@ -412,13 +408,10 @@ static int page_referenced_file(struct page *page, int ignore_token)
  * Quick test_and_clear_referenced for all mappings to a page,
  * returns the number of ptes which referenced the page.
  */
-int page_referenced(struct page *page, int is_locked, int ignore_token)
+int page_referenced(struct page *page, int is_locked)
 {
        int referenced = 0;
 
-       if (!swap_token_default_timeout)
-               ignore_token = 1;
-
        if (page_test_and_clear_young(page))
                referenced++;
 
@@ -427,15 +420,14 @@ int page_referenced(struct page *page, int is_locked, int ignore_token)
 
        if (page_mapped(page) && page->mapping) {
                if (PageAnon(page))
-                       referenced += page_referenced_anon(page, ignore_token);
+                       referenced += page_referenced_anon(page);
                else if (is_locked)
-                       referenced += page_referenced_file(page, ignore_token);
+                       referenced += page_referenced_file(page);
                else if (TestSetPageLocked(page))
                        referenced++;
                else {
                        if (page->mapping)
-                               referenced += page_referenced_file(page,
-                                                               ignore_token);
+                               referenced += page_referenced_file(page);
                        unlock_page(page);
                }
        }
@@ -614,7 +606,6 @@ static void try_to_unmap_cluster(unsigned long cursor,
        struct page *page;
        unsigned long address;
        unsigned long end;
-       unsigned long pfn;
 
        address = (vma->vm_start + cursor) & CLUSTER_MASK;
        end = address + CLUSTER_SIZE;
@@ -643,15 +634,8 @@ static void try_to_unmap_cluster(unsigned long cursor,
        for (; address < end; pte++, address += PAGE_SIZE) {
                if (!pte_present(*pte))
                        continue;
-
-               pfn = pte_pfn(*pte);
-               if (unlikely(!pfn_valid(pfn))) {
-                       print_bad_pte(vma, *pte, address);
-                       continue;
-               }
-
-               page = pfn_to_page(pfn);
-               BUG_ON(PageAnon(page));
+               page = vm_normal_page(vma, address, *pte);
+               BUG_ON(!page || PageAnon(page));
 
                if (ptep_clear_flush_young(vma, address, pte))
                        continue;
index eff3c18c33a10ba802b9743c514a83ccd04aaa09..f4c560b4a2b79862340fe7457af001f8e6141715 100644 (file)
@@ -57,14 +57,17 @@ void grab_swap_token(void)
        /* We have the token. Let others know we still need it. */
        if (has_swap_token(current->mm)) {
                current->mm->recent_pagein = 1;
+               if (unlikely(!swap_token_default_timeout))
+                       disable_swap_token();
                return;
        }
 
        if (time_after(jiffies, swap_token_check)) {
 
-               /* Can't get swapout protection if we exceed our RSS limit. */
-               // if (current->mm->rss > current->mm->rlimit_rss)
-               //      return;
+               if (!swap_token_default_timeout) {
+                       swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL;
+                       return;
+               }
 
                /* ... or if we recently held the token. */
                if (time_before(jiffies, current->mm->swap_token_time))
@@ -95,6 +98,7 @@ void __put_swap_token(struct mm_struct *mm)
 {
        spin_lock(&swap_token_lock);
        if (likely(mm == swap_token_mm)) {
+               mm->swap_token_time = jiffies + SWAP_TOKEN_CHECK_INTERVAL;
                swap_token_mm = &init_mm;
                swap_token_check = jiffies;
        }
index 28130541270f5ad35b3e18ac878b349c61c6e01f..b0cd81c32de6ca0f601bb1be3c12764beb37a8af 100644 (file)
@@ -201,13 +201,25 @@ static int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
        list_for_each_entry(shrinker, &shrinker_list, list) {
                unsigned long long delta;
                unsigned long total_scan;
+               unsigned long max_pass = (*shrinker->shrinker)(0, gfp_mask);
 
                delta = (4 * scanned) / shrinker->seeks;
-               delta *= (*shrinker->shrinker)(0, gfp_mask);
+               delta *= max_pass;
                do_div(delta, lru_pages + 1);
                shrinker->nr += delta;
-               if (shrinker->nr < 0)
-                       shrinker->nr = LONG_MAX;        /* It wrapped! */
+               if (shrinker->nr < 0) {
+                       printk(KERN_ERR "%s: nr=%ld\n",
+                                       __FUNCTION__, shrinker->nr);
+                       shrinker->nr = max_pass;
+               }
+
+               /*
+                * Avoid risking looping forever due to too large nr value:
+                * never try to free more than twice the estimate number of
+                * freeable entries.
+                */
+               if (shrinker->nr > max_pass * 2)
+                       shrinker->nr = max_pass * 2;
 
                total_scan = shrinker->nr;
                shrinker->nr = 0;
@@ -407,7 +419,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
                if (PageWriteback(page))
                        goto keep_locked;
 
-               referenced = page_referenced(page, 1, sc->priority <= 0);
+               referenced = page_referenced(page, 1);
                /* In active use or really unfreeable?  Activate it. */
                if (referenced && page_mapping_inuse(page))
                        goto activate_locked;
@@ -756,7 +768,7 @@ refill_inactive_zone(struct zone *zone, struct scan_control *sc)
                if (page_mapped(page)) {
                        if (!reclaim_mapped ||
                            (total_swap_pages == 0 && PageAnon(page)) ||
-                           page_referenced(page, 0, sc->priority <= 0)) {
+                           page_referenced(page, 0)) {
                                list_add(&page->lru, &l_active);
                                continue;
                        }
@@ -960,6 +972,8 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
                sc.nr_reclaimed = 0;
                sc.priority = priority;
                sc.swap_cluster_max = SWAP_CLUSTER_MAX;
+               if (!priority)
+                       disable_swap_token();
                shrink_caches(zones, &sc);
                shrink_slab(sc.nr_scanned, gfp_mask, lru_pages);
                if (reclaim_state) {
@@ -1056,6 +1070,10 @@ loop_again:
                int end_zone = 0;       /* Inclusive.  0 = ZONE_DMA */
                unsigned long lru_pages = 0;
 
+               /* The swap token gets in the way of swapout... */
+               if (!priority)
+                       disable_swap_token();
+
                all_zones_ok = 1;
 
                if (nr_pages == 0) {
@@ -1360,6 +1378,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
        sc.nr_reclaimed = 0;
        /* scan at the highest priority */
        sc.priority = 0;
+       disable_swap_token();
 
        if (nr_pages > SWAP_CLUSTER_MAX)
                sc.swap_cluster_max = nr_pages;
index 81e00a6c19def97230e09f0302029c5ef04f82e9..e3b242daf53c64506f9ba77937a94bb544bcefe6 100644 (file)
@@ -39,23 +39,27 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly;
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
 static void
-__rpc_purge_upcall(struct inode *inode, int err)
+__rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err)
 {
-       struct rpc_inode *rpci = RPC_I(inode);
        struct rpc_pipe_msg *msg;
+       void (*destroy_msg)(struct rpc_pipe_msg *);
 
-       while (!list_empty(&rpci->pipe)) {
-               msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, list);
+       destroy_msg = rpci->ops->destroy_msg;
+       while (!list_empty(head)) {
+               msg = list_entry(head->next, struct rpc_pipe_msg, list);
                list_del_init(&msg->list);
                msg->errno = err;
-               rpci->ops->destroy_msg(msg);
-       }
-       while (!list_empty(&rpci->in_upcall)) {
-               msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, list);
-               list_del_init(&msg->list);
-               msg->errno = err;
-               rpci->ops->destroy_msg(msg);
+               destroy_msg(msg);
        }
+}
+
+static void
+__rpc_purge_upcall(struct inode *inode, int err)
+{
+       struct rpc_inode *rpci = RPC_I(inode);
+
+       __rpc_purge_list(rpci, &rpci->pipe, err);
+       __rpc_purge_list(rpci, &rpci->in_upcall, err);
        rpci->pipelen = 0;
        wake_up(&rpci->waitq);
 }