Commit cad34273 authored by Linus Torvalds's avatar Linus Torvalds

Linux 2.1.91

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
parent b884a92a
...@@ -19,6 +19,7 @@ Currently, these files are in /proc/sys/vm: ...@@ -19,6 +19,7 @@ Currently, these files are in /proc/sys/vm:
- buffermem - buffermem
- freepages - freepages
- overcommit_memory - overcommit_memory
- pagecache
- swapctl - swapctl
- swapout_interval - swapout_interval
...@@ -93,17 +94,16 @@ buffermem: ...@@ -93,17 +94,16 @@ buffermem:
The three values in this file correspond to the values in The three values in this file correspond to the values in
the struct buffer_mem. It controls how much memory should the struct buffer_mem. It controls how much memory should
be used for buffer and cache memory. Note that memorymapped be used for buffer memory.
files are also counted as cache memory...
The values are: The values are:
min_percent -- this is the minumum percentage of memory min_percent -- this is the minumum percentage of memory
that should be spent on buffer + page cache that should be spent on buffer memory
borrow_percent -- when Linux is short on memory, and buffer borrow_percent -- when Linux is short on memory, and the
and cache use more than this percentage of buffer cache uses more memory, free pages
memory, free pages are stolen from them are stolen from it
max_percent -- this is the maximum amount of memory that 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: freepages:
...@@ -176,6 +176,18 @@ static inline int vm_enough_memory(long pages) ...@@ -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: swapctl:
This file contains no less than 8 variables. This file contains no less than 8 variables.
......
...@@ -813,7 +813,7 @@ common_fixup(long min_idsel, long max_idsel, long irqs_per_slot, ...@@ -813,7 +813,7 @@ common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
*/ */
static inline void eb66p_fixup(void) 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+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 */ {16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
{ -1, -1, -1, -1, -1}, /* IdSel 8, SIO */ { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
...@@ -869,7 +869,7 @@ static inline void eb66p_fixup(void) ...@@ -869,7 +869,7 @@ static inline void eb66p_fixup(void)
#if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164) #if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
static inline void alphapc164_fixup(void) 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 */ /*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */ { 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 */ { 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) ...@@ -900,7 +900,7 @@ static inline void alphapc164_fixup(void)
*/ */
static inline void cabriolet_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+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+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 */ { 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) ...@@ -956,7 +956,7 @@ static inline void cabriolet_fixup(void)
*/ */
static inline void eb66_and_eb64p_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+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+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 ?, ?? */ {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) ...@@ -1005,7 +1005,7 @@ static inline void eb66_and_eb64p_fixup(void)
*/ */
static inline void mikasa_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 */ /*INT INTA INTB INTC INTD */
{16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */ {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */
{ -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
...@@ -1076,7 +1076,7 @@ static inline void mikasa_fixup(void) ...@@ -1076,7 +1076,7 @@ static inline void mikasa_fixup(void)
*/ */
static inline void noritake_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 */ /*INT INTA INTB INTC INTD */
{ -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
{ -1, -1, -1, -1, -1}, /* IdSel 19, PPB */ { -1, -1, -1, -1, -1}, /* IdSel 19, PPB */
...@@ -1140,7 +1140,7 @@ static inline void noritake_fixup(void) ...@@ -1140,7 +1140,7 @@ static inline void noritake_fixup(void)
*/ */
static inline void alcor_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 */ /*INT INTA INTB INTC INTD */
{ 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */ { 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 */ {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 19, slot 3 */
...@@ -1195,7 +1195,7 @@ static inline void alcor_fixup(void) ...@@ -1195,7 +1195,7 @@ static inline void alcor_fixup(void)
*/ */
static inline void xlt_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 */ /*INT INTA INTB INTC INTD */
{16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */ {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 */ { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
...@@ -1266,7 +1266,7 @@ static inline void xlt_fixup(void) ...@@ -1266,7 +1266,7 @@ static inline void xlt_fixup(void)
#ifdef CONFIG_ALPHA_SABLE #ifdef CONFIG_ALPHA_SABLE
static inline void sable_fixup(void) 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 */ /*INT INTA INTB INTC INTD */
{ 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */ { 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 */ { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */
...@@ -1349,7 +1349,7 @@ static inline void sable_fixup(void) ...@@ -1349,7 +1349,7 @@ static inline void sable_fixup(void)
#ifdef CONFIG_ALPHA_MIATA #ifdef CONFIG_ALPHA_MIATA
static inline void miata_fixup(void) 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 */ /*INT INTA INTB INTC INTD */
{16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */ {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */
{ -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */ { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */
...@@ -1420,7 +1420,7 @@ static inline void miata_fixup(void) ...@@ -1420,7 +1420,7 @@ static inline void miata_fixup(void)
#ifdef CONFIG_ALPHA_SX164 #ifdef CONFIG_ALPHA_SX164
static inline void sx164_fixup(void) 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 */ /*INT INTA INTB INTC INTD */
{ 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */ { 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 */ { 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) ...@@ -1461,7 +1461,7 @@ static inline void sio_fixup(void)
* that they use the default INTA line, if they are interrupt * that they use the default INTA line, if they are interrupt
* driven at all). * driven at all).
*/ */
static const char pirq_tab[][5] __initdata = { static const char pirq_tab[][5] __initlocaldata = {
#ifdef CONFIG_ALPHA_P2K #ifdef CONFIG_ALPHA_P2K
{ 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */ { 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
......
...@@ -16,10 +16,10 @@ ENTRY(__lock_kernel) ...@@ -16,10 +16,10 @@ ENTRY(__lock_kernel)
jnc 3f jnc 3f
sti sti
2: 2:
btl %dl, SYMBOL_NAME(smp_invalidate_needed) btl %edx, SYMBOL_NAME(smp_invalidate_needed)
jnc 0f jnc 0f
lock lock
btrl %dl, SYMBOL_NAME(smp_invalidate_needed) btrl %edx, SYMBOL_NAME(smp_invalidate_needed)
jnc 0f jnc 0f
pushl %eax pushl %eax
movl %cr3, %eax movl %cr3, %eax
......
...@@ -413,6 +413,7 @@ SYSCALL(execve) ...@@ -413,6 +413,7 @@ SYSCALL(execve)
SYSCALL(open) SYSCALL(open)
SYSCALL(close) SYSCALL(close)
SYSCALL(waitpid) SYSCALL(waitpid)
SYSCALL(delete_module)
/* Why isn't this a) automatic, b) written in 'C'? */ /* Why isn't this a) automatic, b) written in 'C'? */
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
__arginit __init; \ __arginit __init; \
__arginit __arginit
#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 8
#define __initlocaldata __initdata
#else
#define __initlocaldata
#endif
/* For assembly routines */ /* For assembly routines */
#define __INIT .section .text.init,"ax" #define __INIT .section .text.init,"ax"
#define __FINIT .previous #define __FINIT .previous
......
...@@ -421,6 +421,12 @@ static inline int read(int fd, char * buf, int nr) ...@@ -421,6 +421,12 @@ static inline int read(int fd, char * buf, int nr)
return sys_read(fd, buf, 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 *); extern int __kernel_execve(char *, char **, char **, struct pt_regs *);
static inline int execve(char * file, char ** argvp, char ** envp) static inline int execve(char * file, char ** argvp, char ** envp)
{ {
...@@ -452,6 +458,12 @@ static inline pid_t wait(int * wait_stat) ...@@ -452,6 +458,12 @@ static inline pid_t wait(int * wait_stat)
return waitpid(-1,wait_stat,0); 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
#endif /* _ALPHA_UNISTD_H */ #endif /* _ALPHA_UNISTD_H */
...@@ -325,6 +325,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode); ...@@ -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,close,int,fd);
static inline _syscall1(int,_exit,int,exitcode); static inline _syscall1(int,_exit,int,exitcode);
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options); 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) static inline pid_t wait(int * wait_stat)
{ {
......
...@@ -114,7 +114,7 @@ __asm__ __volatile__( ...@@ -114,7 +114,7 @@ __asm__ __volatile__(
"xorl %%eax,%%eax\n\t" "xorl %%eax,%%eax\n\t"
"jmp 3f\n" "jmp 3f\n"
"2:\tsbbl %%eax,%%eax\n\t" "2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%eax\n" "orb $1,%%al\n"
"3:" "3:"
:"=a" (__res):"S" (cs),"D" (ct):"si","di"); :"=a" (__res):"S" (cs),"D" (ct):"si","di");
return __res; return __res;
......
...@@ -296,6 +296,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode) ...@@ -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,close,int,fd)
static inline _syscall1(int,_exit,int,exitcode) static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 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) static inline pid_t wait(int * wait_stat)
{ {
......
...@@ -316,6 +316,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode) ...@@ -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,close,int,fd)
static inline _syscall1(int,_exit,int,exitcode) static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 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. * This is the mechanism for creating a new kernel thread.
......
...@@ -1410,6 +1410,7 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode) ...@@ -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,close,int,fd)
static inline _syscall1(int,_exit,int,exitcode) static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 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) static inline pid_t wait(int * wait_stat)
{ {
......
...@@ -438,6 +438,7 @@ static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode) ...@@ -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,close,int,fd)
static __inline__ _syscall1(int,_exit,int,exitcode) static __inline__ _syscall1(int,_exit,int,exitcode)
static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 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) static __inline__ pid_t wait(int * wait_stat)
{ {
......
...@@ -426,6 +426,7 @@ static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode) ...@@ -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,close,int,fd)
static __inline__ _syscall1(int,_exit,int,exitcode) static __inline__ _syscall1(int,_exit,int,exitcode)
static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 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) static __inline__ pid_t wait(int * wait_stat)
{ {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/spinlock.h>
#define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALLOC_SKB /* For the drivers to know */
#define HAVE_ALIGNABLE_SKB /* Ditto 8) */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */
...@@ -275,14 +276,15 @@ extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buf ...@@ -275,14 +276,15 @@ extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buf
prev->next = newsk; prev->next = newsk;
} }
extern spinlock_t skb_queue_lock;
extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
__skb_queue_head(list, newsk); __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 ...@@ -307,10 +309,9 @@ extern __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
__skb_queue_tail(list, newsk); __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) ...@@ -342,10 +343,9 @@ extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list)
long flags; long flags;
struct sk_buff *result; struct sk_buff *result;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
result = __skb_dequeue(list); result = __skb_dequeue(list);
restore_flags(flags); spin_unlock_irqrestore(&skb_queue_lock, flags);
return result; return result;
} }
...@@ -372,10 +372,9 @@ extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk) ...@@ -372,10 +372,9 @@ extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
__skb_insert(newsk, old->prev, old, old->list); __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) ...@@ -386,10 +385,9 @@ extern __inline__ void skb_append(struct sk_buff *old, struct sk_buff *newsk)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
__skb_insert(newsk, old, old->next, old->list); __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) ...@@ -421,11 +419,10 @@ extern __inline__ void skb_unlink(struct sk_buff *skb)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
if(skb->list) if(skb->list)
__skb_unlink(skb, skb->list); __skb_unlink(skb, skb->list);
restore_flags(flags); spin_unlock_irqrestore(&skb_queue_lock, flags);
} }
/* XXX: more streamlined implementation */ /* XXX: more streamlined implementation */
...@@ -442,10 +439,9 @@ extern __inline__ struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) ...@@ -442,10 +439,9 @@ extern __inline__ struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
long flags; long flags;
struct sk_buff *result; struct sk_buff *result;
save_flags(flags); spin_lock_irqsave(&skb_queue_lock, flags);
cli();
result = __skb_dequeue_tail(list); result = __skb_dequeue_tail(list);
restore_flags(flags); spin_unlock_irqrestore(&skb_queue_lock, flags);
return result; return result;
} }
......
...@@ -121,6 +121,21 @@ static inline int is_page_shared(struct page *page) ...@@ -121,6 +121,21 @@ static inline int is_page_shared(struct page *page)
return (count > 1); 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. * Make these inline later once they are working properly.
*/ */
......
...@@ -39,6 +39,7 @@ typedef struct buffer_mem_v1 ...@@ -39,6 +39,7 @@ typedef struct buffer_mem_v1
} buffer_mem_v1; } buffer_mem_v1;
typedef buffer_mem_v1 buffer_mem_t; typedef buffer_mem_v1 buffer_mem_t;
extern buffer_mem_t buffer_mem; extern buffer_mem_t buffer_mem;
extern buffer_mem_t page_cache;
typedef struct freepages_v1 typedef struct freepages_v1
{ {
......
...@@ -84,7 +84,8 @@ enum ...@@ -84,7 +84,8 @@ enum
VM_FREEPG, /* struct: Set free page thresholds */ VM_FREEPG, /* struct: Set free page thresholds */
VM_BDFLUSH, /* struct: Control buffer cache flushing */ VM_BDFLUSH, /* struct: Control buffer cache flushing */
VM_OVERCOMMIT_MEMORY, /* Turn off the virtual memory safety limit */ 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 */
}; };
......
...@@ -9,24 +9,22 @@ ...@@ -9,24 +9,22 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/unistd.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. kmod_unload_delay and modprobe_path are set via /proc/sys.
*/ */
int kmod_unload_delay = 60; int kmod_unload_delay = 60;
char modprobe_path[256] = "/sbin/modprobe"; char modprobe_path[256] = "/sbin/modprobe";
char module_name[64] = ""; static char module_name[64] = "";
char * argv[] = { "modprobe", "-k", NULL, NULL, }; static char * argv[] = { "modprobe", "-k", module_name, NULL, };
char * envp[] = { "HOME=/", "TERM=linux", NULL, }; static char * envp[] = { "HOME=/", "TERM=linux", NULL, };
/* /*
kmod_queue synchronizes the kmod thread and the rest of the system kmod_queue synchronizes the kmod thread and the rest of the system
kmod_unload_timer is what we use to unload modules kmod_unload_timer is what we use to unload modules
after kmod_unload_delay seconds after kmod_unload_delay seconds
*/ */
struct wait_queue * kmod_queue = NULL; static struct wait_queue * kmod_queue = NULL;
struct timer_list kmod_unload_timer; static struct timer_list kmod_unload_timer;
/* /*
kmod_thread is the thread that does most of the work. kmod_unload and kmod_thread is the thread that does most of the work. kmod_unload and
...@@ -74,7 +72,6 @@ int kmod_thread(void * data) ...@@ -74,7 +72,6 @@ int kmod_thread(void * data)
Call modprobe with module_name. If execve returns, Call modprobe with module_name. If execve returns,
print out an error. print out an error.
*/ */
argv[2] = module_name;
execve(modprobe_path, argv, envp); execve(modprobe_path, argv, envp);
printk("kmod: failed to load module %s\n", module_name); printk("kmod: failed to load module %s\n", module_name);
...@@ -136,7 +133,8 @@ int request_module(const char * name) ...@@ -136,7 +133,8 @@ int request_module(const char * name)
the module into module_name. Once that is done, wake up the module into module_name. Once that is done, wake up
kmod_thread. kmod_thread.
*/ */
strcpy(module_name, name); strncpy(module_name, name, sizeof(module_name));
module_name[sizeof(module_name)-1] = '\0';
wake_up(&kmod_queue); wake_up(&kmod_queue);
/* /*
......
...@@ -201,6 +201,8 @@ static ctl_table vm_table[] = { ...@@ -201,6 +201,8 @@ static ctl_table vm_table[] = {
sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec}, sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec},
{VM_BUFFERMEM, "buffermem", {VM_BUFFERMEM, "buffermem",
&buffer_mem, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec}, &buffer_mem, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
{VM_PAGECACHE, "pagecache",
&page_cache, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
{0} {0}
}; };
......
...@@ -152,7 +152,7 @@ int shrink_mmap(int priority, int gfp_mask) ...@@ -152,7 +152,7 @@ int shrink_mmap(int priority, int gfp_mask)
} while (tmp != bh); } while (tmp != bh);
/* Refuse to swap out all buffer pages */ /* 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; goto next;
} }
...@@ -171,7 +171,7 @@ int shrink_mmap(int priority, int gfp_mask) ...@@ -171,7 +171,7 @@ int shrink_mmap(int priority, int gfp_mask)
break; break;
} }
age_page(page); age_page(page);
if (page->age) if (page->age || page_cache_size * 100 < (page_cache.min_percent * num_physpages))
break; break;
if (PageSwapCache(page)) { if (PageSwapCache(page)) {
delete_from_swap_cache(page); delete_from_swap_cache(page);
......
...@@ -282,7 +282,7 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order) ...@@ -282,7 +282,7 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
spin_lock_irqsave(&page_alloc_lock, flags); spin_lock_irqsave(&page_alloc_lock, flags);
RMQUEUE(order, maxorder, (gfp_mask & GFP_DMA)); RMQUEUE(order, maxorder, (gfp_mask & GFP_DMA));
spin_unlock_irqrestore(&page_alloc_lock, flags); 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; goto repeat;
nopage: nopage:
return 0; return 0;
......
...@@ -72,3 +72,8 @@ buffer_mem_t buffer_mem = { ...@@ -72,3 +72,8 @@ buffer_mem_t buffer_mem = {
30 /* maximum percent buffer */ 30 /* maximum percent buffer */
}; };
buffer_mem_t page_cache = {
10, /* minimum percent page cache */
30, /* borrow percent page cache */
75 /* maximum */
};
...@@ -451,7 +451,8 @@ static inline int do_try_to_free_page(int gfp_mask) ...@@ -451,7 +451,8 @@ static inline int do_try_to_free_page(int gfp_mask)
stop = 3; stop = 3;
if (gfp_mask & __GFP_WAIT) if (gfp_mask & __GFP_WAIT)
stop = 0; 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; state = 0;
switch (state) { switch (state) {
...@@ -568,7 +569,7 @@ int kswapd(void *unused) ...@@ -568,7 +569,7 @@ int kswapd(void *unused)
* per second (1.6MB/s). This should be a /proc * per second (1.6MB/s). This should be a /proc
* thing. * thing.
*/ */
tries = 50; tries = (50 << 2) >> free_memory_available(3);
while (tries--) { while (tries--) {
int gfp_mask; int gfp_mask;
...@@ -620,7 +621,8 @@ void swap_tick(void) ...@@ -620,7 +621,8 @@ void swap_tick(void)
} }
if ((long) (now - want) >= 0) { 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 */ /* Set the next wake-up time */
next_swap_jiffies = now + swapout_interval; next_swap_jiffies = now + swapout_interval;
wake_up(&kswapd_wait); wake_up(&kswapd_wait);
......
...@@ -59,6 +59,11 @@ ...@@ -59,6 +59,11 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
/*
* Skb list spinlock
*/
spinlock_t skb_queue_lock = SPIN_LOCK_UNLOCKED;
/* /*
* Resource tracking variables * Resource tracking variables
*/ */
...@@ -300,7 +305,7 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) ...@@ -300,7 +305,7 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom)
* Allocate the copy buffer * 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) if(n==NULL)
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment