From: Linus Torvalds Date: Fri, 23 Nov 2007 20:15:55 +0000 (-0500) Subject: Import 2.1.110pre1 X-Git-Tag: 2.1.110pre1 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=42b1d0716fdc7f9aec32d043c779bcb357b1ca06;p=history.git Import 2.1.110pre1 --- diff --git a/Makefile b/Makefile index 88c0d76014c3..069d4abdd108 100644 --- 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/) diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index b92607a58970..bc7611bb0234 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -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(); diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 2f0667f48562..9625e5e6e5f2 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -61,7 +61,11 @@ atomic_t nmi_counter; * * (0x0000ffff for NR_IRQS==16, 0x00ffffff for NR_IRQS=24) */ -unsigned int cached_irq_mask = (1<> 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 diff --git a/arch/i386/kernel/irq.h b/arch/i386/kernel/irq.h index b2a6e4128d48..99a4d20e1f31 100644 --- a/arch/i386/kernel/irq.h +++ b/arch/i386/kernel/irq.h @@ -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 diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 959376e17e0d..4e63c0546828 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -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, diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 5172f2ffe5de..5bce97e9b490 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -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); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 6a876123ecbe..6d680d146ee4 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -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 { /* diff --git a/fs/ntfs/attr.c b/fs/ntfs/attr.c index f94dd9dd7e89..7c6a64e0da8b 100644 --- a/fs/ntfs/attr.c +++ b/fs/ntfs/attr.c @@ -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; diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index 8a8fc563f406..bf5b8505e06f 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -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"); diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index 37e2465166c6..def8f1cb6950 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -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; diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index c7df9cc5a23d..3d9a7c46c4de 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h @@ -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) { diff --git a/include/linux/mm.h b/include/linux/mm.h index f5cb5d79bd81..8ff946430ce0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -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); diff --git a/mm/filemap.c b/mm/filemap.c index 29cc74d50e6a..9b046dd00e42 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -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; } diff --git a/mm/page_io.c b/mm/page_io.c index fa404b1b32e4..7e5a3518637f 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -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", diff --git a/mm/vmscan.c b/mm/vmscan.c index 7936cb4e6968..d4bb5367c8b7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -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); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 094c5e4ab69f..d161344da7a6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -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;