]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.110pre1 2.1.110pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:55 +0000 (15:15 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:55 +0000 (15:15 -0500)
16 files changed:
Makefile
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/irq.h
arch/i386/kernel/setup.c
arch/i386/kernel/smp.c
arch/i386/mm/init.c
fs/ntfs/attr.c
fs/ntfs/fs.c
include/asm-i386/bugs.h
include/asm-i386/irq.h
include/linux/mm.h
mm/filemap.c
mm/page_io.c
mm/vmscan.c
net/ipv4/tcp.c

index 88c0d76014c360802e01a500ba6f763dc3361aab..069d4abdd10827ad236a9661834cd6b9667c300c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 109
+SUBLEVEL = 110
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index b92607a589709ffaa5d54905e60949e0e78add90..bc7611bb02342993d7083843449a5fc26bc7baa2 100644 (file)
@@ -525,6 +525,22 @@ int IO_APIC_irq_trigger (int irq)
        return 0;
 }
 
+__initfunc(static int assign_irq_vector(int irq))
+{
+       static int current_vector = IRQ0_TRAP_VECTOR, offset = 0;
+       if (IO_APIC_VECTOR(irq) > 0)
+               return IO_APIC_VECTOR(irq);
+       current_vector += 8;
+       if (current_vector > 0xFE) {
+               offset++;
+               current_vector = IRQ0_TRAP_VECTOR + offset;
+               printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n",
+                      current_vector);
+       }
+       IO_APIC_VECTOR(irq) = current_vector;
+       return current_vector;
+}
+
 __initfunc(void setup_IO_APIC_irqs (void))
 {
        struct IO_APIC_route_entry entry;
@@ -563,7 +579,7 @@ __initfunc(void setup_IO_APIC_irqs (void))
                if (!IO_APIC_IRQ(irq))
                        continue;
 
-               entry.vector = IO_APIC_VECTOR(irq);
+               entry.vector = assign_irq_vector(irq);
 
                bus = mp_irqs[idx].mpc_srcbus;
 
@@ -592,7 +608,7 @@ __initfunc(void setup_IO_APIC_irq_ISA_default (unsigned int irq))
        entry.mask = 0;                                 /* unmask IRQ now */
        entry.dest.logical.logical_dest = 0xff;         /* all CPUs */
 
-       entry.vector = IO_APIC_VECTOR(irq);
+       entry.vector = assign_irq_vector(irq);
 
        entry.polarity=0;
        entry.trigger=0;
@@ -618,7 +634,7 @@ __initfunc(void setup_ExtINT_pin (unsigned int pin))
        entry.mask = 0;                                 /* unmask IRQ now */
        entry.dest.logical.logical_dest = 0x01;         /* all CPUs */
 
-       entry.vector = IO_APIC_VECTOR(pin);             /* it's ignored */
+       entry.vector = 0;                               /* it's ignored */
 
        entry.polarity=0;
        entry.trigger=0;
@@ -1109,8 +1125,7 @@ void init_IO_APIC_traps(void)
         * 0x80, because int 0x80 is hm, kind of importantish. ;)
         */
        for (i = 0; i < NR_IRQS ; i++) {
-               if ((IO_APIC_VECTOR(i) <= 0xfe)  /* HACK */ &&
-                   (IO_APIC_IRQ(i))) {
+               if (IO_APIC_IRQ(i)) {
                        if (IO_APIC_irq_trigger(i))
                                irq_desc[i].handler = &ioapic_level_irq_type;
                        else
@@ -1217,6 +1232,7 @@ __initfunc(void setup_IO_APIC (void))
         * mptable:
         */
        setup_IO_APIC_irqs ();
+       init_IRQ_SMP();
        check_timer();
  
        print_IO_APIC();
index 2f0667f48562dbe0f2a5cb639a5b4293ee90bced..9625e5e6e5f282ade4c83d6f604e45311d5421d1 100644 (file)
@@ -61,7 +61,11 @@ atomic_t nmi_counter;
  *
  * (0x0000ffff for NR_IRQS==16, 0x00ffffff for NR_IRQS=24)
  */
-unsigned int cached_irq_mask = (1<<NR_IRQS)-1;
+#if NR_IRQS == 64
+unsigned long long cached_irq_mask = -1;
+#else
+unsigned long long cached_irq_mask = (((unsigned long long) 1)<<NR_IRQS)-1;
+#endif
 
 #define cached_21      ((cached_irq_mask | io_apic_irqs) & 0xff)
 #define cached_A1      (((cached_irq_mask | io_apic_irqs) >> 8) & 0xff)
@@ -84,7 +88,7 @@ spinlock_t irq_controller_lock;
  * To get IO-APIC interrupts we turn some of them into IO-APIC
  * interrupts during boot.
  */
-unsigned int io_apic_irqs = 0;
+unsigned long long io_apic_irqs = 0;
 
 static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
 static void enable_8259A_irq (unsigned int irq);
@@ -113,9 +117,11 @@ static struct hw_interrupt_type i8259A_irq_type = {
 
 irq_desc_t irq_desc[NR_IRQS] = {
        [0 ... 15] = { 0, 0, 0, &i8259A_irq_type, },    /* default to standard ISA IRQs */
-       [16 ... 23] = { 0, 0, 0, &no_irq_type, },       /* 'high' PCI IRQs filled in on demand */
+       [16 ... 63] = { 0, 0, 0, &no_irq_type, },       /* 'high' PCI IRQs filled in on demand */
 };
 
+int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 };
+
 
 /*
  * These have to be protected by the irq controller spinlock
@@ -207,6 +213,16 @@ BUILD_IRQ(22)
  */
 BUILD_IRQ(23)
 
+BUILD_IRQ(24)
+BUILD_IRQ(25) BUILD_IRQ(26) BUILD_IRQ(27) BUILD_IRQ(28) BUILD_IRQ(29)
+BUILD_IRQ(30) BUILD_IRQ(31) BUILD_IRQ(32) BUILD_IRQ(33) BUILD_IRQ(34)
+BUILD_IRQ(35) BUILD_IRQ(36) BUILD_IRQ(37) BUILD_IRQ(38) BUILD_IRQ(39)
+BUILD_IRQ(40) BUILD_IRQ(41) BUILD_IRQ(42) BUILD_IRQ(43) BUILD_IRQ(44)
+BUILD_IRQ(45) BUILD_IRQ(46) BUILD_IRQ(47) BUILD_IRQ(48) BUILD_IRQ(49)
+BUILD_IRQ(50) BUILD_IRQ(51) BUILD_IRQ(52) BUILD_IRQ(53) BUILD_IRQ(54)
+BUILD_IRQ(55) BUILD_IRQ(56) BUILD_IRQ(57) BUILD_IRQ(58) BUILD_IRQ(59)
+BUILD_IRQ(60) BUILD_IRQ(61) BUILD_IRQ(62) BUILD_IRQ(63)
+
 /*
  * The following vectors are part of the Linux architecture, there
  * is no hardware IRQ pin equivalent for them, they are triggered
@@ -236,7 +252,19 @@ static void (*interrupt[NR_IRQS])(void) = {
        IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
 #ifdef __SMP__
        ,IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
-       IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt
+       IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
+       IRQ24_interrupt, IRQ25_interrupt, IRQ26_interrupt, IRQ27_interrupt,
+       IRQ28_interrupt, IRQ29_interrupt,
+       IRQ30_interrupt, IRQ31_interrupt, IRQ32_interrupt, IRQ33_interrupt,
+       IRQ34_interrupt, IRQ35_interrupt, IRQ36_interrupt, IRQ37_interrupt,
+       IRQ38_interrupt, IRQ39_interrupt,
+       IRQ40_interrupt, IRQ41_interrupt, IRQ42_interrupt, IRQ43_interrupt,
+       IRQ44_interrupt, IRQ45_interrupt, IRQ46_interrupt, IRQ47_interrupt,
+       IRQ48_interrupt, IRQ49_interrupt,
+       IRQ50_interrupt, IRQ51_interrupt, IRQ52_interrupt, IRQ53_interrupt,
+       IRQ54_interrupt, IRQ55_interrupt, IRQ56_interrupt, IRQ57_interrupt,
+       IRQ58_interrupt, IRQ59_interrupt,
+       IRQ60_interrupt, IRQ61_interrupt, IRQ62_interrupt, IRQ63_interrupt
 #endif
 };
 
@@ -817,12 +845,6 @@ int setup_x86_irq(unsigned int irq, struct irqaction * new)
        if (!shared) {
 #ifdef __SMP__
                if (IO_APIC_IRQ(irq)) {
-                       if (IO_APIC_VECTOR(irq) > 0xfe)
-                               /*
-                                * break visibly for now, FIXME
-                                */
-                               panic("ayiee, tell mingo");
-
                        /*
                         * First disable it in the 8259A:
                         */
@@ -991,9 +1013,11 @@ __initfunc(void init_IRQ(void))
 
 #ifdef __SMP__ 
 
-       for (i = 0; i < NR_IRQS ; i++)
-               if (IO_APIC_VECTOR(i) <= 0xfe)  /* hack -- mingo */
-                       set_intr_gate(IO_APIC_VECTOR(i),interrupt[i]);
+       /*
+         IRQ0 must be given a fixed assignment and initialized
+         before init_IRQ_SMP.
+       */
+       set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]);
 
        /*
         * The reschedule interrupt slowly changes it's functionality,
@@ -1029,3 +1053,14 @@ __initfunc(void init_IRQ(void))
        setup_x86_irq(13, &irq13);
 } 
 
+#ifdef __SMP__ 
+
+__initfunc(void init_IRQ_SMP(void))
+{
+       int i;
+       for (i = 0; i < NR_IRQS ; i++)
+               if (IO_APIC_VECTOR(i) > 0)
+                       set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]);
+}
+
+#endif
index b2a6e4128d480c30d04064eba84449467898a9d5..99a4d20e1f31090ff2626ec10940284810a2dbae 100644 (file)
@@ -39,8 +39,12 @@ typedef struct {
        unsigned int unused[3];
 } irq_desc_t;
 
+#define IRQ0_TRAP_VECTOR 0x51
+
 extern irq_desc_t irq_desc[NR_IRQS];
+extern int irq_vector[NR_IRQS];
 
+extern void init_IRQ_SMP(void);
 extern int handle_IRQ_event(unsigned int, struct pt_regs *);
 
 /*
@@ -68,10 +72,10 @@ void send_IPI (int dest, int vector);
 void init_pic_mode (void);
 void print_IO_APIC (void);
 
-extern unsigned int io_apic_irqs;
-extern unsigned int cached_irq_mask;
+extern unsigned long long io_apic_irqs;
+extern unsigned long long cached_irq_mask;
 
-#define IO_APIC_VECTOR(irq)    (0x51+((irq)<<3))
+#define IO_APIC_VECTOR(irq)    irq_vector[irq]
 
 #define MAX_IRQ_SOURCES 128
 #define MAX_MP_BUSSES 32
index 959376e17e0dc9ef9dc39b1a45d08938dafe1fdc..4e63c05468282b52cca306941d6f5c3864e75046 100644 (file)
@@ -147,6 +147,8 @@ __initfunc(void setup_arch(char **cmdline_p,
                        memory_end = memory_alt_end;
        }
 #endif
+       if (memory_end > (1024-64)*1024*1024)
+               memory_end = (1024-64)*1024*1024;
        memory_end &= PAGE_MASK;
 #ifdef CONFIG_BLK_DEV_RAM
        rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
@@ -436,8 +438,9 @@ static struct cpu_model_info cpu_models[] __initdata = {
            NULL, "Pentium II (Deschutes)", NULL, NULL, NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL }},
        { X86_VENDOR_AMD,       4,
-         { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4",
-           "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }},
+         { NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB",
+           "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT",
+           "Am5x86-WB" }},
        { X86_VENDOR_AMD,       5,
          { "K5/SSA5 (PR75, PR90, PR100)", "K5 (PR120, PR133)",
            "K5 (PR166)", "K5 (PR200)", NULL, NULL,
index 5172f2ffe5de53220ec5313c4cbd402a3d1d5285..5bce97e9b4909e5ac7430c7a06ad43c786d2a601 100644 (file)
@@ -126,7 +126,7 @@ volatile unsigned long smp_invalidate_needed;               /* Used for the invalidate map th
 volatile unsigned long kstack_ptr;                     /* Stack vector for booting CPUs                        */
 struct cpuinfo_x86 cpu_data[NR_CPUS];                  /* Per CPU bogomips and other parameters                */
 static unsigned int num_processors = 1;                        /* Internal processor count                             */
-static unsigned long io_apic_addr = 0xFEC00000;                /* Address of the I/O apic (not yet used)               */
+unsigned long mp_ioapic_addr = 0xFEC00000;             /* Address of the I/O apic (not yet used)               */
 unsigned char boot_cpu_id = 0;                         /* Processor that is doing the boot up                  */
 static int smp_activated = 0;                          /* Tripped once we need to start cross invalidating     */
 int apic_version[NR_CPUS];                             /* APIC version number                                  */
@@ -363,7 +363,7 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc))
                                        printk("I/O APIC #%d Version %d at 0x%lX.\n",
                                                m->mpc_apicid,m->mpc_apicver,
                                                m->mpc_apicaddr);
-                                       io_apic_addr = m->mpc_apicaddr;
+                                       mp_ioapic_addr = m->mpc_apicaddr;
                                }
                                mpt+=sizeof(*m);
                                count+=sizeof(*m);
index 6a876123ecbe4bc20b7b187a1c7bd6c0f65d95f8..6d680d146ee4e65a05e773aaeb7a45c2618ff4f4 100644 (file)
@@ -296,6 +296,7 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
 #ifdef __SMP__
 {
        extern unsigned long mp_lapic_addr;
+       extern unsigned long mp_ioapic_addr;
        pte_t pte;
        unsigned long apic_area = (unsigned long)APIC_BASE;
 
@@ -320,7 +321,7 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
                 */
                apic_area = 0xFEC00000; /*(unsigned long)IO_APIC_BASE;*/
                pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
-               pte = mk_pte_phys(apic_area, PAGE_KERNEL);
+               pte = mk_pte_phys(mp_ioapic_addr, PAGE_KERNEL);
                set_pte(pg_table, pte);
        } else {
                /*
index f94dd9dd7e8945201cce9f1ab233a2792a0adc87..7c6a64e0da8b5c96a30ff36a66e6487076918115 100644 (file)
@@ -56,7 +56,7 @@ new_attr(ntfs_inode *ino,int type,void *name,int namelen,int *pos, int *found)
                }
        }
        if(do_insert)
-               ntfs_memcpy(ino->attrs+i+1,ino->attrs+i,(ino->attr_count-i)*
+               ntfs_memmove(ino->attrs+i+1,ino->attrs+i,(ino->attr_count-i)*
                            sizeof(ntfs_attribute));
        ino->attr_count++;
        ino->attrs[i].type=type;
@@ -95,7 +95,7 @@ ntfs_insert_run(ntfs_attribute *attr,int cnum,int cluster,int len)
                }
        }
        if(attr->d.r.len>cnum)
-               ntfs_memcpy(attr->d.r.runlist+cnum+1,attr->d.r.runlist+cnum,
+               ntfs_memmove(attr->d.r.runlist+cnum+1,attr->d.r.runlist+cnum,
                            (attr->d.r.len-cnum)*sizeof(ntfs_runlist));
        attr->d.r.runlist[cnum].cluster=cluster;
        attr->d.r.runlist[cnum].len=len;
index 8a8fc563f40655272dab15a9adc573fd0919fb13..bf5b8505e06f702849c34c6fa34ace424546db5b 100644 (file)
@@ -827,7 +827,7 @@ struct super_block * ntfs_read_super(struct super_block *sb,
 
        /* Inform the kernel that a device block is a NTFS cluster */
        sb->s_blocksize=vol->clustersize;
-       for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i;i>>=1)
+       for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i != 1;i>>=1)
                sb->s_blocksize_bits++;
        set_blocksize(sb->s_dev,sb->s_blocksize);
        ntfs_debug(DEBUG_OTHER, "set_blocksize\n");
index 37e2465166c69279e47652c0cc7a7a1e09298f1f..def8f1cb6950fe7012a979408c2c1ca85ea4d8f7 100644 (file)
@@ -232,22 +232,24 @@ __initfunc(static void check_pentium_f00f(void))
 }
 
 /*
- * perform the Cyrix 5/2 test (!0 means it's a Cyrix)
+ * Perform the Cyrix 5/2 test. A Cyrix won't change
+ * the flags, while other 486 chips will.
  */
 
 static inline int test_cyrix_52div(void)
 {
-       int test;
-
-       __asm__ __volatile__("xor %%eax,%%eax\n\t"
-            "sahf\n\t"
-            "movb $5,%%al\n\t"
-            "movb $2,%%bl\n\t"
-            "div %%bl\n\t"
-            "lahf\n\t"
-            "andl $0x200,%%eax": "=a" (test) : : "bx", "cc");
-
-       return test;
+       unsigned int test;
+
+       __asm__ __volatile__(
+            "sahf\n\t"         /* clear flags (%eax = 0x0005) */
+            "div %b2\n\t"      /* divide 5 by 2 */
+            "lahf"             /* store flags into %ah */
+            : "=a" (test)
+            : "0" (5), "q" (2)
+            : "cc");
+
+       /* AH is 0x02 on Cyrix after the divide.. */
+       return (unsigned char) (test >> 8) == 0x02;
 }
 
 /*
@@ -258,10 +260,10 @@ static inline int test_cyrix_52div(void)
 
 __initfunc(static void check_cyrix_cpu(void))
 {
-       if (boot_cpu_data.cpuid_level == -1 && boot_cpu_data.x86 == 4
+       if ((boot_cpu_data.cpuid_level == -1) && (boot_cpu_data.x86 == 4)
            && test_cyrix_52div()) {
 
-               /* default to an unknown Cx486, (we will diferentiate later) */
+               /* default to an unknown Cx486, (we will differentiate later) */
                /* NOTE:  using 0xff since 0x00 is a valid DIR0 value */
                strcpy(boot_cpu_data.x86_vendor_id, "CyrixInstead");
                boot_cpu_data.x86_model = 0xff;
@@ -270,7 +272,7 @@ __initfunc(static void check_cyrix_cpu(void))
 }
 
 /*
- * Fix two problems with the Cyrix 686 and 686L:
+ * Fix two problems with the Cyrix 6x86 and 6x86L:
  *   -- the cpuid is disabled on power up, enable it, use it.
  *   -- the SLOP bit needs resetting on some motherboards due to old BIOS,
  *      so that the udelay loop calibration works well.  Recalibrate.
@@ -281,7 +283,7 @@ extern void calibrate_delay(void) __init;
 __initfunc(static void check_cx686_cpuid_slop(void))
 {
        if (boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX &&
-           (boot_cpu_data.x86_model & 0xf0) == 0x30) {  /* 686(L) */
+           (boot_cpu_data.x86_model & 0xf0) == 0x30) {  /* 6x86(L) */
                int dummy;
                unsigned char ccr3, ccr5;
 
index c7df9cc5a23d36799c6c49d6be6b690fb9a0e47a..3d9a7c46c4de4815e41631c44b0cf35c0b605903 100644 (file)
@@ -17,7 +17,7 @@
  * Right now the APIC is only used for SMP, but this
  * may change.
  */
-#define NR_IRQS 24
+#define NR_IRQS 64
 
 static __inline__ int irq_cannonicalize(int irq)
 {
index f5cb5d79bd81697b870f4de1356719293ba870e2..8ff946430ce0fef23b8c0094976f8af298a65fe4 100644 (file)
@@ -298,6 +298,7 @@ extern unsigned long do_mmap(struct file *, unsigned long, unsigned long,
 extern int do_munmap(unsigned long, size_t);
 
 /* filemap.c */
+extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
 extern int shrink_mmap(int, int);
 extern void truncate_inode_pages(struct inode *, unsigned long);
index 29cc74d50e6a8347c6b72ef02fb4c077cb7bbcd7..9b046dd00e426acaca0fe820575fd91095666957 100644 (file)
@@ -117,12 +117,98 @@ repeat:
        }
 }
 
+/*
+ * Remove a page from the page cache and free it.
+ */
+void remove_inode_page(struct page *page)
+{
+       remove_page_from_hash_queue(page);
+       remove_page_from_inode_queue(page);
+       __free_page(page);
+}
+
+/*
+ * Check whether we can free this page.
+ */
+static inline int shrink_one_page(struct page *page, int gfp_mask)
+{
+       struct buffer_head *tmp, *bh;
+
+       if (PageLocked(page))
+               goto next;
+       if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
+               goto next;
+       /* First of all, regenerate the page's referenced bit
+         * from any buffers in the page
+        */
+       bh = page->buffers;
+       if (bh) {
+               tmp = bh;
+               do {
+                       if (buffer_touched(tmp)) {
+                               clear_bit(BH_Touched, &tmp->b_state);
+                               set_bit(PG_referenced, &page->flags);
+                       }
+                       tmp = tmp->b_this_page;
+               } while (tmp != bh);
+
+               /* Refuse to swap out all buffer pages */
+               if ((buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.min_percent * num_physpages))
+                       goto next;
+       }
+
+       /* We can't throw away shared pages, but we do mark
+          them as referenced.  This relies on the fact that
+          no page is currently in both the page cache and the
+          buffer cache; we'd have to modify the following
+          test to allow for that case. */
+
+       switch (atomic_read(&page->count)) {
+       case 1:
+               /* is it a swap-cache or page-cache page? */
+               if (page->inode) {
+                       if (test_and_clear_bit(PG_referenced, &page->flags)) {
+                               touch_page(page);
+                               break;
+                       }
+                       age_page(page);
+                       if (page->age)
+                               break;
+                       if (page_cache_size * 100 < (page_cache.min_percent * num_physpages))
+                               break;
+                       if (PageSwapCache(page)) {
+                               delete_from_swap_cache(page);
+                               return 1;
+                       }
+                       remove_inode_page(page);
+                       return 1;
+               }
+               /* It's not a cache page, so we don't do aging.
+                * If it has been referenced recently, don't free it */
+               if (test_and_clear_bit(PG_referenced, &page->flags))
+                       break;
+
+               /* is it a buffer cache page? */
+               if ((gfp_mask & __GFP_IO) && bh && try_to_free_buffer(bh, &bh, 6))
+                       return 1;
+               break;
+
+       default:
+               /* more than one user: we can't throw it away */
+               set_bit(PG_referenced, &page->flags);
+               /* fall through */
+       case 0:
+               /* nothing */
+       }
+next:
+       return 0;
+}
+
 int shrink_mmap(int priority, int gfp_mask)
 {
        static unsigned long clock = 0;
-       struct page * page;
        unsigned long limit = num_physpages;
-       struct buffer_head *tmp, *bh;
+       struct page * page;
        int count_max, count_min;
 
        count_max = (limit<<2) >> (priority>>1);
@@ -130,76 +216,11 @@ int shrink_mmap(int priority, int gfp_mask)
 
        page = mem_map + clock;
        do {
+               if (shrink_one_page(page, gfp_mask))
+                       return 1;
                count_max--;
                if (page->inode || page->buffers)
                        count_min--;
-
-               if (PageLocked(page))
-                       goto next;
-               if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
-                       goto next;
-               /* First of all, regenerate the page's referenced bit
-                   from any buffers in the page */
-               bh = page->buffers;
-               if (bh) {
-                       tmp = bh;
-                       do {
-                               if (buffer_touched(tmp)) {
-                                       clear_bit(BH_Touched, &tmp->b_state);
-                                       set_bit(PG_referenced, &page->flags);
-                               }
-                               tmp = tmp->b_this_page;
-                       } while (tmp != bh);
-
-                       /* Refuse to swap out all buffer pages */
-                       if ((buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.min_percent * num_physpages))
-                               goto next;
-               }
-
-               /* We can't throw away shared pages, but we do mark
-                  them as referenced.  This relies on the fact that
-                  no page is currently in both the page cache and the
-                  buffer cache; we'd have to modify the following
-                  test to allow for that case. */
-
-               switch (atomic_read(&page->count)) {
-                       case 1:
-                               /* is it a swap-cache or page-cache page? */
-                               if (page->inode) {
-                                       if (test_and_clear_bit(PG_referenced, &page->flags)) {
-                                               touch_page(page);
-                                               break;
-                                       }
-                                       age_page(page);
-                                       if (page->age || page_cache_size * 100 < (page_cache.min_percent * num_physpages))
-                                               break;
-                                       if (PageSwapCache(page)) {
-                                               delete_from_swap_cache(page);
-                                               return 1;
-                                       }
-                                       remove_page_from_hash_queue(page);
-                                       remove_page_from_inode_queue(page);
-                                       __free_page(page);
-                                       return 1;
-                               }
-                               /* It's not a cache page, so we don't do aging.
-                                * If it has been referenced recently, don't free it */
-                               if (test_and_clear_bit(PG_referenced, &page->flags))
-                                       break;
-
-                               /* is it a buffer cache page? */
-                               if ((gfp_mask & __GFP_IO) && bh && try_to_free_buffer(bh, &bh, 6))
-                                       return 1;
-                               break;
-
-                       default:
-                               /* more than one users: we can't throw it away */
-                               set_bit(PG_referenced, &page->flags);
-                               /* fall through */
-                       case 0:
-                               /* nothing */
-               }
-next:
                page++;
                clock++;
                if (clock >= limit) {
@@ -226,9 +247,7 @@ unsigned long page_unuse(struct page * page)
                return count;
        if (PageSwapCache(page))
                panic ("Doing a normal page_unuse of a swap cache page");
-       remove_page_from_hash_queue(page);
-       remove_page_from_inode_queue(page);
-       __free_page(page);
+       remove_inode_page(page);
        return 1;
 }
 
index fa404b1b32e4ab1f0fff5926c66ddcfee636348c..7e5a3518637fc894e47c4b9c1dbdd98206e0e2f0 100644 (file)
@@ -74,18 +74,19 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                return;
        }
        if (p->swap_map && !p->swap_map[offset]) {
-               printk("Hmm.. Trying to %s unallocated swap (%08lx)\n", 
-                      (rw == READ) ? "read" : "write", 
-                      entry);
+               printk(KERN_ERR "rw_swap_page: "
+                       "Trying to %s unallocated swap (%08lx)\n", 
+                       (rw == READ) ? "read" : "write", entry);
                return;
        }
        if (!(p->flags & SWP_USED)) {
-               printk("Trying to swap to unused swap-device\n");
+               printk(KERN_ERR "rw_swap_page: "
+                       "Trying to swap to unused swap-device\n");
                return;
        }
 
        if (!PageLocked(page)) {
-               printk("VM: swap page is unlocked\n");
+               printk(KERN_ERR "VM: swap page is unlocked\n");
                return;
        }
        
@@ -111,11 +112,11 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
         * hashing for locked pages.
         */
        if (!PageSwapCache(page)) {
-               printk("VM: swap page is not in swap cache\n");
+               printk(KERN_ERR "VM: swap page is not in swap cache\n");
                return;
        }
        if (page->offset != entry) {
-               printk ("swap entry mismatch");
+               printk (KERN_ERR "VM: swap entry mismatch\n");
                return;
        }
 
@@ -179,11 +180,14 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                clear_bit(PG_locked, &page->flags);
                wake_up(&page->wait);
        } else
-               printk("rw_swap_page: no swap file or device\n");
+               printk(KERN_ERR "rw_swap_page: no swap file or device\n");
 
+       /* This shouldn't happen, but check to be sure. */
+       if (atomic_read(&page->count) == 1)
+               printk(KERN_ERR "rw_swap_page: page unused while waiting!\n");
        atomic_dec(&page->count);
        if (offset && !test_and_clear_bit(offset,p->swap_lockmap))
-               printk("rw_swap_page: lock already cleared\n");
+               printk(KERN_ERR "rw_swap_page: lock already cleared\n");
        wake_up(&lock_queue);
 #ifdef DEBUG_SWAP
        printk ("DebugVM: %s_swap_page finished on page %p (count %d)\n",
index 7936cb4e6968568877ebb532cc23de165c5b1245..d4bb5367c8b707cf4bd25a5af25252a167835e6d 100644 (file)
@@ -533,7 +533,6 @@ int kswapd(void *unused)
        add_wait_queue(&kswapd_wait, &wait);
        while (1) {
                int tries;
-               int tried = 0;
 
                current->state = TASK_INTERRUPTIBLE;
                flush_signals(current);
index 094c5e4ab69f35161c63395c4603ed62e9bbf0ca..d161344da7a69f0e403be93f079f79c9bfc0a919 100644 (file)
@@ -580,7 +580,7 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
                /* Always wake the user up when an error occurred */
                if (sock_wspace(sk) >= space || sk->err)
                        mask |= POLLOUT | POLLWRNORM;
-               if (tp->urg_data)
+               if (tp->urg_data & URG_VALID)
                        mask |= POLLPRI;
        }
        return mask;