]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.1.91 2.1.91
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:01 +0000 (15:15 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:01 +0000 (15:15 -0500)
I just made a real 91 on ftp.kernel.org, let's hope that this has all the
sillies gone. As usual, it is prefectly smooth on my machine, but this
time we also have a better chance of it being smooth on machines with less
memory too, as Rik has done some good work in testing the algorithms out.
So throw some problems at it to see just how good it is..

                Linus

24 files changed:
Documentation/sysctl/vm.txt
arch/alpha/kernel/bios32.c
arch/i386/lib/locks.S
arch/ppc/kernel/misc.S
include/asm-alpha/init.h
include/asm-alpha/unistd.h
include/asm-arm/unistd.h
include/asm-i386/string.h
include/asm-i386/unistd.h
include/asm-m68k/unistd.h
include/asm-mips/unistd.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/linux/skbuff.h
include/linux/swap.h
include/linux/swapctl.h
include/linux/sysctl.h
kernel/kmod.c
kernel/sysctl.c
mm/filemap.c
mm/page_alloc.c
mm/swap.c
mm/vmscan.c
net/core/skbuff.c

index 818d00f40643cb5d2886c772b02cd7ed1b3feb30..f2ef26fff7897b59679f466cf059037bc5c380fb 100644 (file)
@@ -19,6 +19,7 @@ Currently, these files are in /proc/sys/vm:
 - buffermem
 - freepages
 - overcommit_memory
+- pagecache
 - swapctl
 - swapout_interval
 
@@ -93,17 +94,16 @@ buffermem:
 
 The three values in this file correspond to the values in
 the struct buffer_mem. It controls how much memory should
-be used for buffer and cache memory. Note that memorymapped
-files are also counted as cache memory...
+be used for buffer memory.
 
 The values are:
 min_percent    -- this is the minumum percentage of memory
-                  that should be spent on buffer + page cache
-borrow_percent  -- when Linux is short on memory, and buffer
-                   and cache use more than this percentage of
-                   memory, free pages are stolen from them
+                  that should be spent on buffer memory
+borrow_percent  -- when Linux is short on memory, and the
+                   buffer cache uses more memory, free pages
+                   are stolen from it
 max_percent     -- this is the maximum amount of memory that
-                   can be used for buffer and cache memory 
+                   can be used for buffer memory 
 
 ==============================================================
 freepages:
@@ -176,6 +176,18 @@ static inline int vm_enough_memory(long pages)
 
 ==============================================================
 
+pagecache:
+
+This file does exactly the same as buffermem, only this
+file controls the struct page_cache, and thus controls
+the amount of memory allowed for memory mapping of files.
+
+You don't want the minimum level to be too low, otherwise
+your system might thrash when memory is tight or fragmentation
+is high...
+
+==============================================================
+
 swapctl:
 
 This file contains no less than 8 variables.
index 9fbc46fd83dea8f3618e8addbb029fa5d1958259..af89718344f781311bf5168bd9be4dfc58c2f1ec 100644 (file)
@@ -813,7 +813,7 @@ common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
  */
 static inline void eb66p_fixup(void)
 {
-       static char irq_tab[5][5] __initdata = {
+       static char irq_tab[5][5] __initlocaldata = {
                {16+0, 16+0, 16+5,  16+9, 16+13},  /* IdSel 6,  slot 0, J25 */
                {16+1, 16+1, 16+6, 16+10, 16+14},  /* IdSel 7,  slot 1, J26 */
                {  -1,   -1,   -1,    -1,    -1},  /* IdSel 8,  SIO         */
@@ -869,7 +869,7 @@ static inline void eb66p_fixup(void)
 #if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
 static inline void alphapc164_fixup(void)
 {
-       static char irq_tab[7][5] __initdata = {
+       static char irq_tab[7][5] __initlocaldata = {
                /*INT   INTA  INTB   INTC   INTD */
                { 16+2, 16+2, 16+9,  16+13, 16+17}, /* IdSel  5, slot 2, J20 */
                { 16+0, 16+0, 16+7,  16+11, 16+15}, /* IdSel  6, slot 0, J29 */
@@ -900,7 +900,7 @@ static inline void alphapc164_fixup(void)
  */
 static inline void cabriolet_fixup(void)
 {
-       static char irq_tab[5][5] __initdata = {
+       static char irq_tab[5][5] __initlocaldata = {
                { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5,  slot 2, J21 */
                { 16+0, 16+0, 16+5,  16+9, 16+13}, /* IdSel 6,  slot 0, J19 */
                { 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7,  slot 1, J20 */
@@ -956,7 +956,7 @@ static inline void cabriolet_fixup(void)
  */
 static inline void eb66_and_eb64p_fixup(void)
 {
-       static char irq_tab[5][5] __initdata = {
+       static char irq_tab[5][5] __initlocaldata = {
                {16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
                {16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
                {16+1, 16+1, 16+3, 16+8, 16+10},  /* IdSel 7,  slot ?, ?? */
@@ -1005,7 +1005,7 @@ static inline void eb66_and_eb64p_fixup(void)
  */
 static inline void mikasa_fixup(void)
 {
-       static char irq_tab[8][5] __initdata = {
+       static char irq_tab[8][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                {16+12, 16+12, 16+12, 16+12, 16+12},    /* IdSel 17,  SCSI */
                {   -1,    -1,    -1,    -1,    -1},    /* IdSel 18,  PCEB */
@@ -1076,7 +1076,7 @@ static inline void mikasa_fixup(void)
  */
 static inline void noritake_fixup(void)
 {
-       static char irq_tab[13][5] __initdata = {
+       static char irq_tab[13][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCEB */
                {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PPB  */
@@ -1140,7 +1140,7 @@ static inline void noritake_fixup(void)
  */
 static inline void alcor_fixup(void)
 {
-       static char irq_tab[6][5] __initdata = {
+       static char irq_tab[6][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 18,  slot 0 */
                {16+16, 16+16, 16+17, 16+18, 16+19},    /* IdSel 19,  slot 3 */
@@ -1195,7 +1195,7 @@ static inline void alcor_fixup(void)
  */
 static inline void xlt_fixup(void)
 {
-       static char irq_tab[7][5] __initdata = {
+       static char irq_tab[7][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                {16+13, 16+13, 16+13, 16+13, 16+13},    /* IdSel 17,  TULIP  */
                { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 18,  slot 0 */
@@ -1266,7 +1266,7 @@ static inline void xlt_fixup(void)
 #ifdef CONFIG_ALPHA_SABLE
 static inline void sable_fixup(void)
 {
-        static char irq_tab[9][5] __initdata = {
+        static char irq_tab[9][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                { 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
                { 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
@@ -1349,7 +1349,7 @@ static inline void sable_fixup(void)
 #ifdef CONFIG_ALPHA_MIATA
 static inline void miata_fixup(void)
 {
-        static char irq_tab[18][5] __initdata = {
+        static char irq_tab[18][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142  */
                {   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE   */
@@ -1420,7 +1420,7 @@ static inline void miata_fixup(void)
 #ifdef CONFIG_ALPHA_SX164
 static inline void sx164_fixup(void)
 {
-       static char irq_tab[5][5] __initdata = {
+       static char irq_tab[5][5] __initlocaldata = {
                /*INT    INTA   INTB   INTC   INTD */
                { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
                { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
@@ -1461,7 +1461,7 @@ static inline void sio_fixup(void)
         * that they use the default INTA line, if they are interrupt
         * driven at all).
         */
-       static const char pirq_tab[][5] __initdata = {
+       static const char pirq_tab[][5] __initlocaldata = {
 #ifdef CONFIG_ALPHA_P2K
                { 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
                {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
index 30a5bc43255997246265de69609674eff8dce022..67f1caa518fcbac3ac00ad5c522da2849b98f3ab 100644 (file)
@@ -16,10 +16,10 @@ ENTRY(__lock_kernel)
        jnc     3f
        sti
 2:
-       btl     %dl, SYMBOL_NAME(smp_invalidate_needed)
+       btl     %edx, SYMBOL_NAME(smp_invalidate_needed)
        jnc     0f
        lock
-       btrl    %dl, SYMBOL_NAME(smp_invalidate_needed)
+       btrl    %edx, SYMBOL_NAME(smp_invalidate_needed)
        jnc     0f
        pushl   %eax
        movl    %cr3, %eax
index 9e3c6165d8cf9815876379f2b08ec836b1c46148..2c866eed86982becd83a91365b62c27e4d654f22 100644 (file)
@@ -413,6 +413,7 @@ SYSCALL(execve)
 SYSCALL(open)
 SYSCALL(close)
 SYSCALL(waitpid)
+SYSCALL(delete_module)
 
 
 /* Why isn't this a) automatic, b) written in 'C'? */  
index 7d769dfcd0fc20f93a1c889ed0ba097c9c18536e..9ce618965c70d54af0db9c63537e355c38a0ac21 100644 (file)
@@ -7,6 +7,12 @@
        __arginit __init; \
        __arginit
 
+#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 8
+#define __initlocaldata  __initdata
+#else
+#define __initlocaldata
+#endif
+
 /* For assembly routines */
 #define __INIT         .section        .text.init,"ax"
 #define __FINIT                .previous
index cef856f24729c893602d48bbf5f2599ca725c134..64361c234df68c7f2d7c758c640b64d47745108c 100644 (file)
@@ -421,6 +421,12 @@ static inline int read(int fd, char * buf, int nr)
        return sys_read(fd, buf, nr);
 }
 
+extern int sys_fork(void);
+static inline int fork(void)
+{
+       return sys_fork();
+}
+
 extern int __kernel_execve(char *, char **, char **, struct pt_regs *);
 static inline int execve(char * file, char ** argvp, char ** envp)
 {
@@ -452,6 +458,12 @@ static inline pid_t wait(int * wait_stat)
        return waitpid(-1,wait_stat,0);
 }
 
+extern int sys_delete_module(const char *name);
+static inline int delete_module(const char *name)
+{
+       return sys_delete_module(name);
+}
+
 #endif
 
 #endif /* _ALPHA_UNISTD_H */
index 31b407dbbc13ec36675044bb30606a6cf190704a..9bcf627939cbeb63e4bb02f2b87328f7da676d09 100644 (file)
@@ -325,6 +325,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode);
 static inline _syscall1(int,close,int,fd);
 static inline _syscall1(int,_exit,int,exitcode);
 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options);
+static inline _syscall1(int,delete_module,const char *,name)
 
 static inline pid_t wait(int * wait_stat)
 {
index a2947ce3e1363e70dc830082d02dd3ffbe5ee8e1..5370dbb6a7866010967284fb6f0517726635e03f 100644 (file)
@@ -114,7 +114,7 @@ __asm__ __volatile__(
        "xorl %%eax,%%eax\n\t"
        "jmp 3f\n"
        "2:\tsbbl %%eax,%%eax\n\t"
-       "orb $1,%%eax\n"
+       "orb $1,%%al\n"
        "3:"
        :"=a" (__res):"S" (cs),"D" (ct):"si","di");
 return __res;
index 53766f701544782231a4ea028f62bfbfcb767f90..068be0f2954762d23ef0fae612a836c846125022 100644 (file)
@@ -296,6 +296,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
 static inline _syscall1(int,_exit,int,exitcode)
 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
 
 static inline pid_t wait(int * wait_stat)
 {
index 7c5226b95e57f9e42a8c3d681f01a02466e77c38..f82743219b8108afcd443ceb297786a1e1bf80ee 100644 (file)
@@ -316,6 +316,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
 static inline _syscall1(int,_exit,int,exitcode)
 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
 
 /*
  * This is the mechanism for creating a new kernel thread.
index f0511957c0c093049ef499e180a29618016500d4..0aac2ed4278533d890687c866f43abdeaab230cf 100644 (file)
@@ -1410,6 +1410,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
 static inline _syscall1(int,_exit,int,exitcode)
 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
 
 static inline pid_t wait(int * wait_stat)
 {
index df519f28f3ef5af9da6c90fa74a52af8a3f69751..f5425f51bd82fafdf38a9df5ecce4f2974cf1ad7 100644 (file)
@@ -438,6 +438,7 @@ static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
 static __inline__ _syscall1(int,close,int,fd)
 static __inline__ _syscall1(int,_exit,int,exitcode)
 static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static __inline__ _syscall1(int,delete_module,const char *,name)
 
 static __inline__ pid_t wait(int * wait_stat)
 {
index 1983c79d9ca2eabc50882a1cd8b392ec96fffc4b..67a3c4108c7177b2c0b3b49a1101de8c3a126a5d 100644 (file)
@@ -426,6 +426,7 @@ static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
 static __inline__ _syscall1(int,close,int,fd)
 static __inline__ _syscall1(int,_exit,int,exitcode)
 static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static __inline__ _syscall1(int,delete_module,const char *,name)
 
 static __inline__ pid_t wait(int * wait_stat)
 {
index 9662bf3b7c5804cbc6bda9505df12d5e3bac7813..d94b40bcc9cba3fd813d86b9cb577bb5140adbcd 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <asm/atomic.h>
 #include <asm/types.h>
+#include <asm/spinlock.h>
 
 #define HAVE_ALLOC_SKB         /* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB     /* Ditto 8)                */
@@ -275,14 +276,15 @@ extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buf
        prev->next = newsk;
 }
 
+extern spinlock_t skb_queue_lock;
+
 extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        __skb_queue_head(list, newsk);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
 }
 
 /*
@@ -307,10 +309,9 @@ extern __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        __skb_queue_tail(list, newsk);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
 }
 
 /*
@@ -342,10 +343,9 @@ extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list)
        long flags;
        struct sk_buff *result;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        result = __skb_dequeue(list);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
        return result;
 }
 
@@ -372,10 +372,9 @@ extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        __skb_insert(newsk, old->prev, old, old->list);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
 }
 
 /*
@@ -386,10 +385,9 @@ extern __inline__ void skb_append(struct sk_buff *old, struct sk_buff *newsk)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        __skb_insert(newsk, old, old->next, old->list);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
 }
 
 /*
@@ -421,11 +419,10 @@ extern __inline__ void skb_unlink(struct sk_buff *skb)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        if(skb->list)
                __skb_unlink(skb, skb->list);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
 }
 
 /* XXX: more streamlined implementation */
@@ -442,10 +439,9 @@ extern __inline__ struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
        long flags;
        struct sk_buff *result;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&skb_queue_lock, flags);
        result = __skb_dequeue_tail(list);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&skb_queue_lock, flags);
        return result;
 }
 
index f4822bc8f1a82405735c62a4a17ed3adc8757f31..48a0ca02c757890ac9175bb7454fc2de1b24f65f 100644 (file)
@@ -121,6 +121,21 @@ static inline int is_page_shared(struct page *page)
        return (count > 1);
 }
 
+/*
+ * When we're freeing pages from a user application, we want
+ * to cluster swapouts too.    -- Rik.
+ * linux/mm/page_alloc.c
+ */
+static inline int try_to_free_pages(int gfp_mask, int count)
+{
+       int retval = 0;
+       while (count--) {
+               if (try_to_free_page(gfp_mask))
+                       retval = 1;
+       }
+       return retval;
+}
+
 /*
  * Make these inline later once they are working properly.
  */
index cc169d2dab85e4e5871913da9842721a83a2fa62..bf787614b546bd83a7ba18efff2e06eade1530fb 100644 (file)
@@ -39,6 +39,7 @@ typedef struct buffer_mem_v1
 } buffer_mem_v1;
 typedef buffer_mem_v1 buffer_mem_t;
 extern buffer_mem_t buffer_mem;
+extern buffer_mem_t page_cache;
 
 typedef struct freepages_v1
 {
index 22aab22a5028da0ee87cbfed4c59e9916cb7d074..3a8f31e777700437f8d5f841aeddc6e8278a8bd2 100644 (file)
@@ -84,7 +84,8 @@ enum
        VM_FREEPG,              /* struct: Set free page thresholds */
        VM_BDFLUSH,             /* struct: Control buffer cache flushing */
        VM_OVERCOMMIT_MEMORY,   /* Turn off the virtual memory safety limit */
-       VM_BUFFERMEM            /* struct: Set cache memory thresholds */
+       VM_BUFFERMEM,           /* struct: Set buffer memory thresholds */
+       VM_PAGECACHE            /* struct: Set cache memory thresholds */
 };
 
 
index a0f58d48538f56f0300ac361b6591d59a996adad..379c276955789cb3e71fab2c4d08e065eb91f11a 100644 (file)
@@ -9,24 +9,22 @@
 #include <linux/types.h>
 #include <linux/unistd.h>
 
-static inline _syscall1(int,delete_module,const char *,name_user)
-
 /*
        kmod_unload_delay and modprobe_path are set via /proc/sys.
 */
 int kmod_unload_delay = 60;
 char modprobe_path[256] = "/sbin/modprobe";
-char module_name[64] = "";
-char * argv[] = { "modprobe", "-k", NULL, NULL, };
-char * envp[] = { "HOME=/", "TERM=linux", NULL, };
+static char module_name[64] = "";
+static char * argv[] = { "modprobe", "-k", module_name, NULL, };
+static char * envp[] = { "HOME=/", "TERM=linux", NULL, };
 
 /*
        kmod_queue synchronizes the kmod thread and the rest of the system
        kmod_unload_timer is what we use to unload modules
        after kmod_unload_delay seconds
 */
-struct wait_queue * kmod_queue = NULL;
-struct timer_list kmod_unload_timer;
+static struct wait_queue * kmod_queue = NULL;
+static struct timer_list kmod_unload_timer;
 
 /*
        kmod_thread is the thread that does most of the work.  kmod_unload and
@@ -74,7 +72,6 @@ int kmod_thread(void * data)
                                        Call modprobe with module_name.  If execve returns,
                                        print out an error.
                                */
-                               argv[2] = module_name;
                                execve(modprobe_path, argv, envp);
 
                                printk("kmod: failed to load module %s\n", module_name);
@@ -136,7 +133,8 @@ int request_module(const char * name)
                the module into module_name.  Once that is done, wake up
                kmod_thread.
        */
-       strcpy(module_name, name);
+       strncpy(module_name, name, sizeof(module_name));
+       module_name[sizeof(module_name)-1] = '\0';
        wake_up(&kmod_queue);
 
        /*
index ea3b98c9401fc70457b39c435abb2881edd836d2..47bb361715b0181392b6241c8c8e017baed1170c 100644 (file)
@@ -201,6 +201,8 @@ static ctl_table vm_table[] = {
         sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec},
        {VM_BUFFERMEM, "buffermem",
         &buffer_mem, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
+       {VM_PAGECACHE, "pagecache",
+        &page_cache, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
        {0}
 };
 
index cb76c5592dbd0d55bd98a07d7d4ac1f9fbb294c8..0971c63b77c0f7f76f749839361ed6125a533c19 100644 (file)
@@ -152,7 +152,7 @@ int shrink_mmap(int priority, int gfp_mask)
                        } while (tmp != bh);
 
                        /* Refuse to swap out all buffer pages */
-                       if ((buffermem >> PAGE_SHIFT) * 100 > (buffer_mem.min_percent * num_physpages))
+                       if ((buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.min_percent * num_physpages))
                                goto next;
                }
 
@@ -171,7 +171,7 @@ int shrink_mmap(int priority, int gfp_mask)
                                                break;
                                        }
                                        age_page(page);
-                                       if (page->age)
+                                       if (page->age || page_cache_size * 100 < (page_cache.min_percent * num_physpages))
                                                break;
                                        if (PageSwapCache(page)) {
                                                delete_from_swap_cache(page);
index 5138eb0481cbe251fff92dd4b02c9ab590ab1465..35a5e982d793650fef05c82a9e821d33a1078676 100644 (file)
@@ -282,7 +282,7 @@ repeat:
        spin_lock_irqsave(&page_alloc_lock, flags);
        RMQUEUE(order, maxorder, (gfp_mask & GFP_DMA));
        spin_unlock_irqrestore(&page_alloc_lock, flags);
-       if ((gfp_mask & __GFP_WAIT) && try_to_free_page(gfp_mask))
+       if ((gfp_mask & __GFP_WAIT) && try_to_free_pages(gfp_mask,SWAP_CLUSTER_MAX))
                goto repeat;
 nopage:
        return 0;
index d607db93b88ca52793e429a72c8f7aff9fd953c3..957ad0a95bbd63bcf8182318ee8ce8c218bbbe1d 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -72,3 +72,8 @@ buffer_mem_t buffer_mem = {
        30      /* maximum percent buffer */
 };
 
+buffer_mem_t page_cache = {
+       10,     /* minimum percent page cache */
+       30,     /* borrow percent page cache */
+       75      /* maximum */
+};
index e6d325509b519df9be792bb4f9eb456e0e573bf4..0ad129a6b7144bbaa8c9fc3faa255df4b8862ff2 100644 (file)
@@ -451,7 +451,8 @@ static inline int do_try_to_free_page(int gfp_mask)
        stop = 3;
        if (gfp_mask & __GFP_WAIT)
                stop = 0;
-       if ((buffermem >> PAGE_SHIFT) * 100 > buffer_mem.borrow_percent * num_physpages)
+       if (((buffermem >> PAGE_SHIFT) * 100 > buffer_mem.borrow_percent * num_physpages)
+                  || (page_cache_size * 100 > page_cache.borrow_percent * num_physpages))
                state = 0;
 
        switch (state) {
@@ -568,7 +569,7 @@ int kswapd(void *unused)
                 * per second (1.6MB/s). This should be a /proc
                 * thing.
                 */
-               tries = 50;
+               tries = (50 << 2) >> free_memory_available(3);
        
                while (tries--) {
                        int gfp_mask;
@@ -620,7 +621,8 @@ void swap_tick(void)
        }
  
        if ((long) (now - want) >= 0) {
-               if (want_wakeup || (num_physpages * buffer_mem.max_percent) < (buffermem >> PAGE_SHIFT) * 100) {
+               if (want_wakeup || (num_physpages * buffer_mem.max_percent) < (buffermem >> PAGE_SHIFT) * 100
+                               || (num_physpages * page_cache.max_percent < page_cache_size)) {
                        /* Set the next wake-up time */
                        next_swap_jiffies = now + swapout_interval;
                        wake_up(&kswapd_wait);
index 80e3ba4a63bf5389186721a05291a3e95607806f..57e58f85a40b064c1bb56a47f9eeb189d8f7f27b 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+/*
+ * Skb list spinlock
+ */
+spinlock_t skb_queue_lock = SPIN_LOCK_UNLOCKED;
+
 /*
  *     Resource tracking variables
  */
@@ -300,7 +305,7 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom)
         *      Allocate the copy buffer
         */
         
-       n=alloc_skb(skb->truesize+newheadroom-headroom-sizeof(struct sk_buff), GFP_ATOMIC);
+       n=alloc_skb(skb->truesize+newheadroom-headroom, GFP_ATOMIC);
        if(n==NULL)
                return NULL;