Ingo wrote:
> On Wed, Jan 03, 2001 at 09:43:54AM -0200, Rik van Riel wrote:
> > On Fri, 28 Dec 2000, Mike Sklar wrote:
> > > If I wanted to adjust the rlim_cur value of a running
> > > processes, is there any sort of interface for that?
> > 
> > Hmmm, I don't think there is an interface to adjust the
> > per-process ulimit settings on-the-fly ...
> > 
> > Does anybody know if there's an interface for this ?

> If you don't mean "kill -TERM", no there isn't. It would be evil
> to the process anyway.

The RSS limits patch I sent to linux-kernel some time ago provided an
experimental /proc interface to allow exactly this.
The patch against 2.2.16 is still on our FTP server at 

ftp://ftp-au.aurema.com/private/aurpjc31/linux-2216-rsslimit.diff.bz2

Here's the patch against 2.4.0.  The main differences between this and 
Rik's patch are:
      -- you  choose soft or hard limits at kernel config time with my 
      patch; with Rik's you get both (rlim_cur is `soft' rlim_max is
      `hard') 
      -- Rik's patch does some extra stuff to the VM code as well as
         the RSS limits
      -- Rik's patch doesn't affect swap behaviour (except in so far
         as processes over their RSS limit will tend to swap, which reduces
         memory pressure on all other processes); my patch means that
         processes over RSS limit suffer somewhat
      -- My patch puts the limit into the struct mm for slightly more
         cache-friendly behaviour, and to allow later interfacing with
         per-user resource-management software (it should be possible
         to write a kernel module to adjust RSS limits to implement per-user 
         limits without affecting per-process RLIMIT values)
      -- My patch has a /proc interface to allow setting
         rlimit[RLIMIT_RSS]
      -- my patch implements the rss accounting fields so that time -v 
         gives reasonable output


Index: linux-2.4.0/CREDITS
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/CREDITS,v
retrieving revision 1.1.1.5
diff -u -b -u -r1.1.1.5 CREDITS
--- linux-2.4.0/CREDITS 2001/01/04 23:02:54     1.1.1.5
+++ linux-2.4.0/CREDITS 2001/01/08 04:41:41
@@ -491,6 +491,24 @@
 S: Stanford, California 94305
 S: USA
 
+N: Kingsley Cheung
+E: [EMAIL PROTECTED]
+D: Page fault calculation
+D: /proc/<pid>/rss support
+D: kswapd improvements regarding process RSS limits 
+S: Aurema Pty Limited
+S: PO Box 305, Strawberry Hills NSW 2012, 
+S: Australia 
+
+N: Peter Chubb
+E: [EMAIL PROTECTED]
+D: Page fault calculation
+D: /proc/<pid>/rss support
+D: kswapd improvements regarding process RSS limits 
+S: Aurema Pty Limited
+S: PO Box 305, Strawberry Hills NSW 2012, 
+S: Australia 
+
 N: Juan Jose Ciarlante
 W: http://juanjox.kernelnotes.org/
 E: [EMAIL PROTECTED]
Index: linux-2.4.0/Documentation/Configure.help
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/Documentation/Configure.help,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 Configure.help
--- linux-2.4.0/Documentation/Configure.help    2001/01/07 21:44:33     1.1.1.6
+++ linux-2.4.0/Documentation/Configure.help    2001/01/08 04:41:41
@@ -16955,6 +16955,50 @@
   another UltraSPARC-IIi-cEngine boardset with a 7-segment display,
   you should say N to this option. 
 
+RSS Softlimits (EXPERIMENTAL)
+CONFIG_RSS_SOFTLIMIT
+  If you want the setrlimit(RLIMIT_RSS, ...) system call to work, say
+  Y either here or for RSS Hardlimits.  If you don't understand this
+  you don't need it, so say N.
+
+  RSS Softlimits will make it more likely that pages will be stolen
+  from processes that have a resident set size (i.e., real memory
+  footprint) greater than their limit.  Processes with a limit set
+  that is below their actual need may still exceed their limits, and
+  in this instance kswapd may work excessively hard.
+
+  Because of the way that RSS is measured and controlled, the limit is
+  approximate only.
+
+  It is harmless to have RSS Softlimits and RSS Hardlimits both set.
+
+RSS Hardlimits (EXPERIMENTAL)
+CONFIG_RSS_HARDLIMIT
+  If you want the setrlimit(RLIMIT_RSS, ...) system call to work, say
+  Y either here or for RSS Softlimits.  If you don't understand this
+  you don't need it, so say N.
+
+  RSS Hardlimits changes the behaviour of the kernel at page-fault
+  time.  If a process is over its RSS limit when it wants to get a new
+  page, then with this configuration option enabled the process's
+  memory space will be reduced before the page-fault continues.
+
+  Because of the way that RSS is measured and controlled, the actual
+  memory footprint of a process may exceed the set limit for a short
+  time.
+
+  It is harmless to have RSS Softlimits and RSS Hardlimits both set.
+
+Support for /proc/pid/rss (EXPERIMENTAL)
+CONFIG_PROC_RSS
+  Saying Y here adds an extra file inside each process directory in the
+  /proc file system that allows measurement and control of resident
+  set size (real memory footprint).  The file format is documented in
+  Documentation/proc_rss.txt
+
+  The main purpose of this file is for testing the results of the RSS
+  Hardlimits or Softlimits configuration options.
+
 IA-64 system type
 CONFIG_IA64_GENERIC
   This selects the system type of your hardware.  A "generic" kernel
Index: linux-2.4.0/arch/alpha/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/alpha/config.in,v
retrieving revision 1.1.1.5
diff -u -b -u -r1.1.1.5 config.in
--- linux-2.4.0/arch/alpha/config.in    2001/01/04 23:31:47     1.1.1.5
+++ linux-2.4.0/arch/alpha/config.in    2001/01/08 04:41:42
@@ -231,6 +231,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
        "ELF            CONFIG_KCORE_ELF        \
Index: linux-2.4.0/arch/alpha/kernel/osf_sys.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/alpha/kernel/osf_sys.c,v
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.1 osf_sys.c
--- linux-2.4.0/arch/alpha/kernel/osf_sys.c     2000/10/04 00:17:47     1.1.1.1
+++ linux-2.4.0/arch/alpha/kernel/osf_sys.c     2001/01/08 04:41:42
@@ -1164,6 +1164,10 @@
                r.ru_minflt = current->min_flt;
                r.ru_majflt = current->maj_flt;
                r.ru_nswap = current->nswap;
+               r.ru_maxrss =  current->maxrss;
+               r.ru_ixrss = 0;
+               r.ru_idrss = current->irss;
+               r.ru_isrss = 0;
                break;
        case RUSAGE_CHILDREN:
                r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
@@ -1173,6 +1177,10 @@
                r.ru_minflt = current->cmin_flt;
                r.ru_majflt = current->cmaj_flt;
                r.ru_nswap = current->cnswap;
+               r.ru_maxrss = current->cmaxrss;
+               r.ru_ixrss = 0;
+               r.ru_idrss = current->cirss;
+               r.ru_isrss = 0;
                break;
        default:
                r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime +
@@ -1186,6 +1194,10 @@
                r.ru_minflt = current->min_flt + current->cmin_flt;
                r.ru_majflt = current->maj_flt + current->cmaj_flt;
                r.ru_nswap = current->nswap + current->cnswap;
+               r.ru_maxrss = current->maxrss  >  current->cmaxrss ? current->maxrss : 
+current->cmaxrss;
+               r.ru_ixrss = 0;
+               r.ru_idrss = current->irss + current>cirss;
+               r.ru_isrss = 0;
                break;
        }
 
Index: linux-2.4.0/arch/arm/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/arm/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/arm/config.in      2000/12/13 00:39:26     1.1.1.3
+++ linux-2.4.0/arch/arm/config.in      2001/01/08 04:41:42
@@ -251,6 +251,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 tristate 'NWFPE math emulation' CONFIG_NWFPE
 choice 'Kernel core (/proc/kcore) format' \
        "ELF            CONFIG_KCORE_ELF        \
Index: linux-2.4.0/arch/arm/mm/fault-common.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/arm/mm/fault-common.c,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 fault-common.c
--- linux-2.4.0/arch/arm/mm/fault-common.c      2000/12/13 05:19:47     1.1.1.2
+++ linux-2.4.0/arch/arm/mm/fault-common.c      2001/01/08 04:41:42
@@ -100,9 +100,15 @@
        switch (fault) {
        case 2:
                tsk->maj_flt++;
+#if CONFIG_PROC_RSS
+               update_flt_rate(&(tsk->maj_flt_rate), &(tsk->maj_flt_time));
+#endif         
                return fault;
        case 1:
                tsk->min_flt++;
+#if CONFIG_PROC_RSS
+               update_flt_rate(&(tsk->min_flt_rate), &(tsk->min_flt_time));
+#endif         
        case 0:
                return fault;
        }
Index: linux-2.4.0/arch/i386/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/i386/config.in,v
retrieving revision 1.1.1.5
diff -u -b -u -r1.1.1.5 config.in
--- linux-2.4.0/arch/i386/config.in     2001/01/04 23:31:17     1.1.1.5
+++ linux-2.4.0/arch/i386/config.in     2001/01/08 04:41:42
@@ -226,6 +226,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
        "ELF            CONFIG_KCORE_ELF        \
Index: linux-2.4.0/arch/i386/mm/fault.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/i386/mm/fault.c,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 fault.c
--- linux-2.4.0/arch/i386/mm/fault.c    2000/12/13 00:20:39     1.1.1.3
+++ linux-2.4.0/arch/i386/mm/fault.c    2001/01/08 04:41:42
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995  Linus Torvalds
  */
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -18,6 +19,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
+#ifdef CONFIG_PROC_RSS
+#include <linux/rss.h>
+#endif
+
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
@@ -196,9 +201,15 @@
        switch (handle_mm_fault(mm, vma, address, write)) {
        case 1:
                tsk->min_flt++;
+#if CONFIG_PROC_RSS
+               update_flt_rate(&(tsk->maj_flt_rate), &(tsk->maj_flt_time));
+#endif         
                break;
        case 2:
                tsk->maj_flt++;
+#if CONFIG_PROC_RSS
+               update_flt_rate(&(tsk->min_flt_rate), &(tsk->min_flt_time));
+#endif         
                break;
        case 0:
                goto do_sigbus;
Index: linux-2.4.0/arch/ia64/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/ia64/config.in,v
retrieving revision 1.1.1.4
diff -u -b -u -r1.1.1.4 config.in
--- linux-2.4.0/arch/ia64/config.in     2001/01/07 21:44:41     1.1.1.4
+++ linux-2.4.0/arch/ia64/config.in     2001/01/08 04:41:42
@@ -93,6 +93,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
Index: linux-2.4.0/arch/ia64/ia32/binfmt_elf32.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/ia64/ia32/binfmt_elf32.c,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 binfmt_elf32.c
--- linux-2.4.0/arch/ia64/ia32/binfmt_elf32.c   2001/01/07 21:44:41     1.1.1.3
+++ linux-2.4.0/arch/ia64/ia32/binfmt_elf32.c   2001/01/08 04:41:42
@@ -204,7 +204,8 @@
 
        for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
                if (bprm->page[i]) {
-                       current->mm->rss++;
+                       if (++(current->mm->rss) > current->mm->maxrss)
+                               current->mm->maxrss = current->mm->rss;
                        put_dirty_page(current,bprm->page[i],stack_base);
                }
                stack_base += PAGE_SIZE;
Index: linux-2.4.0/arch/m68k/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/m68k/config.in,v
retrieving revision 1.1.1.4
diff -u -b -u -r1.1.1.4 config.in
--- linux-2.4.0/arch/m68k/config.in     2001/01/07 21:44:42     1.1.1.4
+++ linux-2.4.0/arch/m68k/config.in     2001/01/08 04:41:42
@@ -91,6 +91,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
        "ELF            CONFIG_KCORE_ELF        \
Index: linux-2.4.0/arch/m68k/atari/stram.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/m68k/atari/stram.c,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 stram.c
--- linux-2.4.0/arch/m68k/atari/stram.c 2000/12/13 05:12:51     1.1.1.2
+++ linux-2.4.0/arch/m68k/atari/stram.c 2001/01/08 04:41:43
@@ -642,7 +642,8 @@
        set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
        swap_free(entry);
        get_page(page);
-       ++vma->vm_mm->rss;
+       if (++vma->vm_mm->rss > vma->vm_mm->maxrss)
+               vma->vm_mm->maxrss = vma->vm_mm->rss;
 }
 
 static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
Index: linux-2.4.0/arch/mips/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/mips/config.in,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 config.in
--- linux-2.4.0/arch/mips/config.in     2000/12/13 00:26:37     1.1.1.2
+++ linux-2.4.0/arch/mips/config.in     2001/01/08 04:41:43
@@ -168,6 +168,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 
 source drivers/parport/Config.in
 
Index: linux-2.4.0/arch/mips64/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/mips64/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/mips64/config.in   2000/12/13 05:22:46     1.1.1.3
+++ linux-2.4.0/arch/mips64/config.in   2001/01/08 04:41:43
@@ -104,6 +104,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
 bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
 if [ "$CONFIG_MIPS32_COMPAT" = "y" ]; then
Index: linux-2.4.0/arch/ppc/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/ppc/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/ppc/config.in      2000/12/13 00:28:43     1.1.1.3
+++ linux-2.4.0/arch/ppc/config.in      2001/01/08 04:41:43
@@ -118,6 +118,10 @@
 
 bool 'Networking support' CONFIG_NET
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 
Index: linux-2.4.0/arch/s390/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/s390/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/s390/config.in     2000/12/13 00:47:02     1.1.1.3
+++ linux-2.4.0/arch/s390/config.in     2001/01/08 04:41:43
@@ -44,6 +44,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 
 endmenu
Index: linux-2.4.0/arch/sh/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/sh/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/sh/config.in       2001/01/07 21:44:52     1.1.1.3
+++ linux-2.4.0/arch/sh/config.in       2001/01/08 04:41:43
@@ -129,6 +129,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
        "ELF            CONFIG_KCORE_ELF        \
Index: linux-2.4.0/arch/sparc/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/sparc/config.in,v
retrieving revision 1.1.1.4
diff -u -b -u -r1.1.1.4 config.in
--- linux-2.4.0/arch/sparc/config.in    2000/12/13 05:04:31     1.1.1.4
+++ linux-2.4.0/arch/sparc/config.in    2001/01/08 04:41:43
@@ -59,6 +59,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
 fi
Index: linux-2.4.0/arch/sparc64/config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/arch/sparc64/config.in,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 config.in
--- linux-2.4.0/arch/sparc64/config.in  2000/12/13 00:36:42     1.1.1.3
+++ linux-2.4.0/arch/sparc64/config.in  2001/01/08 04:41:43
@@ -51,6 +51,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'RSS Softlimits (EXPERIMENTAL)' CONFIG_RSS_SOFTLIMIT
+  bool 'RSS Hardlimits (EXPERIMENTAL)' CONFIG_RSS_HARDLIMIT
+fi
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
 fi
Index: linux-2.4.0/drivers/acpi/include/acgcc.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/include/acgcc.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/include/acgcc.h    2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/include/acgcc.h    2001/01/04 23:30:27     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acgcc.h - GCC specific defines, etc.
- *       $Revision: 1.1.1.2 $
+ *       $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/include/aclinux.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/include/aclinux.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/include/aclinux.h  2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/include/aclinux.h  2001/01/04 23:30:27     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: aclinux.h - OS specific defines, etc.
- *       $Revision: 1.1.1.2 $
+ *       $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/include/actbl1.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/include/actbl1.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/include/actbl1.h   2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/include/actbl1.h   2001/01/04 23:30:27     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actbl1.h - ACPI 1.0 tables
- *       $Revision: 1.1.1.2 $
+ *       $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/include/actbl2.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/include/actbl2.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/include/actbl2.h   2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/include/actbl2.h   2001/01/04 23:30:27     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actbl2.h - ACPI Specification Revision 2.0 Tables
- *       $Revision: 1.1.1.2 $
+ *       $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/include/actbl71.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/include/actbl71.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/include/actbl71.h  2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/include/actbl71.h  2001/01/04 23:30:24     1.1.1.1
@@ -3,7 +3,7 @@
  * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71
  *                   This file includes tables specific to this
  *                   specification revision.
- *       $Revision: 1.1.1.2 $
+ *       $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/namespace/nsinit.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/namespace/nsinit.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/namespace/nsinit.c 2001/01/07 21:44:56     1.1.1.2
+++ linux-2.4.0/drivers/acpi/namespace/nsinit.c 2001/01/04 23:30:33     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsinit - namespace initialization
- *              $Revision: 1.1.1.2 $
+ *              $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/tables/tbconvrt.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/tables/tbconvrt.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/tables/tbconvrt.c  2001/01/07 21:44:57     1.1.1.2
+++ linux-2.4.0/drivers/acpi/tables/tbconvrt.c  2001/01/04 23:30:38     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbconvrt - ACPI Table conversion utilities
- *              $Revision: 1.1.1.2 $
+ *              $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/acpi/tables/tbxfroot.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/acpi/tables/tbxfroot.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/acpi/tables/tbxfroot.c  2001/01/07 21:44:57     1.1.1.2
+++ linux-2.4.0/drivers/acpi/tables/tbxfroot.c  2001/01/04 23:30:37     1.1.1.1
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbxfroot - Find the root ACPI table (RSDT)
- *              $Revision: 1.1.1.2 $
+ *              $Revision: 1.1.1.1 $
  *
  *****************************************************************************/
 
Index: linux-2.4.0/drivers/scsi/README.osst
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/scsi/README.osst,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/scsi/README.osst        2001/01/07 21:45:39     1.1.1.2
+++ linux-2.4.0/drivers/scsi/README.osst        2001/01/04 23:22:35     1.1.1.1
@@ -189,7 +189,7 @@
 #!/bin/sh
 # Script to create OnStream SC-x0 device nodes (major 206)
 # Usage: Makedevs.sh [nos [path to dev]]
-# $Id: README.osst,v 1.1.1.2 2001/01/07 21:45:39 peterc Exp $
+# $Id: README.osst,v 1.1.1.1 2001/01/04 23:22:35 peterc Exp $
 major=206
 nrs=4
 dir=/dev
Index: linux-2.4.0/drivers/scsi/osst.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.c,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 osst.c
--- linux-2.4.0/drivers/scsi/osst.c     2001/01/07 21:45:39     1.1.1.2
+++ linux-2.4.0/drivers/scsi/osst.c     2001/01/08 04:41:46
@@ -16,14 +16,14 @@
   Copyright 1992 - 2000 Kai Makisara
                 email [EMAIL PROTECTED]
 
-  $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.c,v 1.1.1.2 2001/01/07 21:45:39 
peterc Exp $
+  $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.c,v 1.1.1.1 2001/01/04 23:22:39 
+peterc Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last modified: Wed Feb  2 22:04:05 2000 by [EMAIL PROTECTED]
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.1.1.2 2001/01/07 21:45:39 peterc Exp $";
+static const char * cvsid = "$Id: osst.c,v 1.1.1.1 2001/01/04 23:22:39 peterc Exp $";
 const char * osst_version = "0.9.4.3";
 
 /* The "failure to reconnect" firmware bug */
Index: linux-2.4.0/drivers/scsi/osst.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/scsi/osst.h     2001/01/07 21:45:39     1.1.1.2
+++ linux-2.4.0/drivers/scsi/osst.h     2001/01/04 23:22:39     1.1.1.1
@@ -1,5 +1,5 @@
 /*
- *     $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.h,v 1.1.1.2 2001/01/07 
21:45:39 peterc Exp $
+ *     $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst.h,v 1.1.1.1 2001/01/04 
+23:22:39 peterc Exp $
  */
 
 #include <asm/byteorder.h>
Index: linux-2.4.0/drivers/scsi/osst_options.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst_options.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.1
diff -u -b -u -r1.1.1.2 -r1.1.1.1
--- linux-2.4.0/drivers/scsi/osst_options.h     2001/01/07 21:45:39     1.1.1.2
+++ linux-2.4.0/drivers/scsi/osst_options.h     2001/01/04 23:22:39     1.1.1.1
@@ -8,7 +8,7 @@
    Changed (and renamed) for OnStream SCSI drives [EMAIL PROTECTED]
    2000-06-21
 
-   $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst_options.h,v 1.1.1.2 2001/01/07 
21:45:39 peterc Exp $
+   $Header: /wrk/CVSROOT/linux-2.4/drivers/scsi/osst_options.h,v 1.1.1.1 2001/01/04 
+23:22:39 peterc Exp $
 */
 
 #ifndef _OSST_OPTIONS_H
Index: linux-2.4.0/fs/Config.in
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/fs/Config.in,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 Config.in
--- linux-2.4.0/fs/Config.in    2000/12/12 21:49:13     1.1.1.2
+++ linux-2.4.0/fs/Config.in    2001/01/08 04:41:51
@@ -43,6 +43,10 @@
 
 bool '/proc file system support' CONFIG_PROC_FS
 
+if [ "$CONFIG_PROC_FS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'Support for /proc/pid/rss? (EXPERIMENTAL)' CONFIG_PROC_RSS
+fi
+
 dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS 
$CONFIG_EXPERIMENTAL
 dep_bool '  Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS
 dep_bool '  Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS
Index: linux-2.4.0/fs/exec.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/fs/exec.c,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 exec.c
--- linux-2.4.0/fs/exec.c       2001/01/07 21:45:49     1.1.1.6
+++ linux-2.4.0/fs/exec.c       2001/01/08 04:41:52
@@ -321,7 +321,8 @@
                struct page *page = bprm->page[i];
                if (page) {
                        bprm->page[i] = NULL;
-                       current->mm->rss++;
+                       if (++current->mm->rss > current->mm->maxrss)
+                               current->mm->maxrss = current->mm->rss;
                        put_dirty_page(current,page,stack_base);
                }
                stack_base += PAGE_SIZE;
Index: linux-2.4.0/fs/proc/Makefile
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/fs/proc/Makefile,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 Makefile
--- linux-2.4.0/fs/proc/Makefile        2001/01/04 23:03:09     1.1.1.2
+++ linux-2.4.0/fs/proc/Makefile        2001/01/08 04:41:52
@@ -14,8 +14,7 @@
 obj-y    := inode.o root.o base.o generic.o array.o \
                kmsg.o proc_tty.o proc_misc.o kcore.o procfs_syms.o
 
-ifeq ($(CONFIG_PROC_DEVICETREE),y)
-obj-y += proc_devtree.o
-endif
+obj-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
+obj-$(CONFIG_PROC_RSS) += rss.o
 
 include $(TOPDIR)/Rules.make
Index: linux-2.4.0/fs/proc/base.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/fs/proc/base.c,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 base.c
--- linux-2.4.0/fs/proc/base.c  2000/12/12 21:49:25     1.1.1.3
+++ linux-2.4.0/fs/proc/base.c  2001/01/08 04:41:52
@@ -11,6 +11,8 @@
  *  go into icache. We cache the reference to task_struct upon lookup too.
  *  Eventually it should become a filesystem in its own. We don't use the
  *  rest of procfs anymore.
+ *
+ *  Added support for /proc/<pid>/rss, 20.01.2000, Kingsley Cheung *
  */
 
 #include <asm/uaccess.h>
@@ -39,6 +41,10 @@
 int proc_pid_status(struct task_struct*,char*);
 int proc_pid_statm(struct task_struct*,char*);
 int proc_pid_cpu(struct task_struct*,char*);
+#ifdef CONFIG_PROC_RSS
+int proc_pid_rss_read(struct task_struct*,char*);
+ssize_t proc_pid_rss_write(struct task_struct*,struct file*,char*,size_t,loff_t*);
+#endif
 
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount 
**mnt)
 {
@@ -309,6 +315,14 @@
        read:           proc_info_read,
 };
 
+#ifdef CONFIG_PROC_RSS
+static struct file_operations proc_rss_file_operations = {
+       read:           proc_info_read,
+       write:          proc_pid_rss_write,
+};
+#endif
+
+
 #define MAY_PTRACE(p) \
 (p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED))
 
@@ -495,6 +509,9 @@
        PROC_PID_STATM,
        PROC_PID_MAPS,
        PROC_PID_CPU,
+#ifdef CONFIG_PROC_RSS
+       PROC_PID_RSS,
+#endif /* CONFIG_PROC_RSS */
        PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
 };
 
@@ -514,6 +531,9 @@
   E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
   E(PROC_PID_ROOT,     "root",         S_IFLNK|S_IRWXUGO),
   E(PROC_PID_EXE,      "exe",          S_IFLNK|S_IRWXUGO),
+#ifdef CONFIG_PROC_RSS
+  E(PROC_PID_RSS,      "rss",          S_IFREG|S_IRUGO|S_IWUSR),
+#endif
   {0,0,NULL,0}
 };
 #undef E
@@ -860,6 +880,12 @@
                        inode->i_op = &proc_mem_inode_operations;
                        inode->i_fop = &proc_mem_operations;
                        break;
+#ifdef CONFIG_PROC_RSS
+               case PROC_PID_RSS:
+                       inode->i_fop = &proc_info_file_operations;
+                       inode->u.proc_i.op.proc_read = proc_pid_rss_read;
+                       break;
+#endif
                default:
                        printk("procfs: impossible type (%d)",p->type);
                        iput(inode);
Index: linux-2.4.0/include/linux/sched.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/include/linux/sched.h,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 sched.h
--- linux-2.4.0/include/linux/sched.h   2001/01/07 21:46:10     1.1.1.6
+++ linux-2.4.0/include/linux/sched.h   2001/01/08 04:41:55
@@ -216,7 +216,9 @@
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long start_brk, brk, start_stack;
        unsigned long arg_start, arg_end, env_start, env_end;
-       unsigned long rss, total_vm, locked_vm;
+       unsigned long rss;
+       unsigned long maxrss, rss_limit;
+       unsigned long total_vm, locked_vm;
        unsigned long def_flags;
        unsigned long cpu_vm_mask;
        unsigned long swap_cnt; /* number of pages to swap on next pass */
@@ -351,6 +353,14 @@
 /* mm fault and swap info: this can arguably be seen as either mm-specific or 
thread-specific */
        unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
        int swappable:1;
+/* #if CONFIG_PROC_RSS keep same size, but do we remove ifdefs in fork too? */
+/* major and minor page fault rates and time of occurence */
+       unsigned long maj_flt_rate, min_flt_rate;  /* in pages per second */
+       unsigned long maj_flt_time, min_flt_time;  /* in seconds */
+/* #endif */
+/* rss statistics -- maxrss is in the struct mm */
+       unsigned long irss;
+       unsigned long cmaxrss, cirss;
 /* process credentials */
        uid_t uid,euid,suid,fsuid;
        gid_t gid,egid,sgid,fsgid;
Index: linux-2.4.0/include/linux/swap.h
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/include/linux/swap.h,v
retrieving revision 1.1.1.4
diff -u -b -u -r1.1.1.4 swap.h
--- linux-2.4.0/include/linux/swap.h    2001/01/04 23:06:01     1.1.1.4
+++ linux-2.4.0/include/linux/swap.h    2001/01/08 04:41:55
@@ -109,6 +109,9 @@
 extern int inactive_shortage(void);
 extern void wakeup_kswapd(int);
 extern int try_to_free_pages(unsigned int gfp_mask);
+#ifdef CONFIG_RSS_HARDLIMIT 
+extern int try_to_swap_out_page(unsigned int gfp_mask);
+#endif
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *, int);
Index: linux-2.4.0/kernel/exit.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/kernel/exit.c,v
retrieving revision 1.1.1.5
diff -u -b -u -r1.1.1.5 exit.c
--- linux-2.4.0/kernel/exit.c   2001/01/07 21:46:13     1.1.1.5
+++ linux-2.4.0/kernel/exit.c   2001/01/08 04:41:56
@@ -49,6 +49,8 @@
                current->cmin_flt += p->min_flt + p->cmin_flt;
                current->cmaj_flt += p->maj_flt + p->cmaj_flt;
                current->cnswap += p->nswap + p->cnswap;
+               if (p->cmaxrss > current->cmaxrss)
+                       current->cmaxrss = p->cmaxrss;
                /*
                 * Potentially available timeslices are retrieved
                 * here - this way the parent does not get penalized
@@ -308,6 +310,14 @@
                if (mm != tsk->active_mm) BUG();
                /* more a memory barrier than a real lock */
                task_lock(tsk);
+               /* 
+                * can't do this at wait() time, because mm is gone by then.
+                */
+               if (tsk->p_pptr) {
+                       if (mm->maxrss > tsk->p_pptr->cmaxrss)
+                               tsk->p_pptr->cmaxrss = mm->maxrss;
+               }
+
                tsk->mm = NULL;
                task_unlock(tsk);
                enter_lazy_tlb(mm, current, smp_processor_id());
Index: linux-2.4.0/kernel/fork.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/kernel/fork.c,v
retrieving revision 1.1.1.5
diff -u -b -u -r1.1.1.5 fork.c
--- linux-2.4.0/kernel/fork.c   2001/01/07 21:46:13     1.1.1.5
+++ linux-2.4.0/kernel/fork.c   2001/01/08 04:41:56
@@ -202,6 +202,7 @@
        atomic_set(&mm->mm_users, 1);
        atomic_set(&mm->mm_count, 1);
        init_MUTEX(&mm->mmap_sem);
+       mm->maxrss = mm->rss;
        mm->page_table_lock = SPIN_LOCK_UNLOCKED;
        mm->pgd = pgd_alloc();
        if (mm->pgd)
@@ -284,6 +285,12 @@
        tsk->min_flt = tsk->maj_flt = 0;
        tsk->cmin_flt = tsk->cmaj_flt = 0;
        tsk->nswap = tsk->cnswap = 0;
+       tsk->irss = 0;
+       tsk->cmaxrss = tsk->cirss = 0;
+#if CONFIG_PROC_RSS
+       tsk->maj_flt_time = tsk->min_flt_time = tsk->start_time / HZ;
+       tsk->maj_flt_rate = tsk->min_flt_rate = 0;
+#endif
 
        tsk->mm = NULL;
        tsk->active_mm = NULL;
Index: linux-2.4.0/kernel/sys.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/kernel/sys.c,v
retrieving revision 1.1.1.2
diff -u -b -u -r1.1.1.2 sys.c
--- linux-2.4.0/kernel/sys.c    2000/11/25 02:56:24     1.1.1.2
+++ linux-2.4.0/kernel/sys.c    2001/01/08 04:41:56
@@ -1077,6 +1077,10 @@
                        return -EPERM;
        }
        *old_rlim = new_rlim;
+
+       if (resource == RLIMIT_RSS && current->mm != &init_mm)
+               current->mm->rss_limit = (new_rlim.rlim_cur == RLIM_INFINITY) ? 
+ULONG_MAX : (new_rlim.rlim_cur >> PAGE_SHIFT);
+
        return 0;
 }
 
@@ -1111,6 +1115,10 @@
                        r.ru_minflt = p->min_flt;
                        r.ru_majflt = p->maj_flt;
                        r.ru_nswap = p->nswap;
+                       r.ru_maxrss = p->mm->maxrss;
+                       r.ru_ixrss = 0;
+                       r.ru_idrss = p->irss;
+                       r.ru_isrss = 0;
                        break;
                case RUSAGE_CHILDREN:
                        r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime);
@@ -1120,6 +1128,10 @@
                        r.ru_minflt = p->cmin_flt;
                        r.ru_majflt = p->cmaj_flt;
                        r.ru_nswap = p->cnswap;
+                       r.ru_maxrss = p->cmaxrss;
+                       r.ru_ixrss = 0;
+                       r.ru_idrss = p->cirss;
+                       r.ru_isrss = 0;
                        break;
                default:
                        r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + 
p->times.tms_cutime);
@@ -1129,6 +1141,10 @@
                        r.ru_minflt = p->min_flt + p->cmin_flt;
                        r.ru_majflt = p->maj_flt + p->cmaj_flt;
                        r.ru_nswap = p->nswap + p->cnswap;
+                       r.ru_maxrss = p->mm->maxrss  >  p->cmaxrss ? p->mm->maxrss : 
+p->cmaxrss;
+                       r.ru_ixrss = 0;
+                       r.ru_idrss = p->irss + p->cirss;
+                       r.ru_isrss = 0;
                        break;
        }
        return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
Index: linux-2.4.0/kernel/timer.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/kernel/timer.c,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 timer.c
--- linux-2.4.0/kernel/timer.c  2000/12/13 02:41:08     1.1.1.3
+++ linux-2.4.0/kernel/timer.c  2001/01/08 04:41:56
@@ -567,6 +567,9 @@
 {
        p->per_cpu_utime[cpu] += user;
        p->per_cpu_stime[cpu] += system;
+       if (p->mm)
+               p->irss += p->mm->rss;
+       
        do_process_times(p, user, system);
        do_it_virt(p, user);
        do_it_prof(p);
Index: linux-2.4.0/mm/filemap.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/mm/filemap.c,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 filemap.c
--- linux-2.4.0/mm/filemap.c    2001/01/07 21:46:13     1.1.1.6
+++ linux-2.4.0/mm/filemap.c    2001/01/08 04:41:57
@@ -1967,8 +1967,12 @@
 
        /* Make sure this doesn't exceed the process's max rss. */
        error = -EIO;
+#if defined(CONFIG_RSS_HARDLIMIT) || defined(CONFIG_RSS_SOFTLIMIT)
+       rlim_rss = vma->vm_mm->rss_limit;
+#else
        rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
                                LONG_MAX; /* default: see resource.h */
+#endif
        if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
                return error;
 
Index: linux-2.4.0/mm/memory.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/mm/memory.c,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 memory.c
--- linux-2.4.0/mm/memory.c     2001/01/07 21:46:13     1.1.1.6
+++ linux-2.4.0/mm/memory.c     2001/01/08 04:41:57
@@ -872,7 +872,8 @@
         */
        if (pte_same(*page_table, pte)) {
                if (PageReserved(old_page))
-                       ++mm->rss;
+                       if (++mm->rss > mm->maxrss)
+                               mm->maxrss = mm->rss;
                break_cow(vma, old_page, new_page, address, page_table);
 
                /* Free the old page.. */
@@ -1019,9 +1020,15 @@
        struct vm_area_struct * vma, unsigned long address,
        pte_t * page_table, swp_entry_t entry, int write_access)
 {
-       struct page *page = lookup_swap_cache(entry);
+       struct page *page;
        pte_t pte;
 
+#ifdef CONFIG_RSS_HARDLIMIT
+       if (mm->rss >= mm->rss_limit)
+               try_to_shrink_rss(mm, GFP_USER);
+#endif
+
+       page = lookup_swap_cache(entry);
        if (!page) {
                lock_kernel();
                swapin_readahead(entry);
@@ -1034,7 +1041,8 @@
                flush_icache_page(vma, page);
        }
 
-       mm->rss++;
+       if (++mm->rss > mm->maxrss)
+               mm->maxrss = mm->rss;
 
        pte = mk_pte(page, vma->vm_page_prot);
 
@@ -1062,13 +1070,18 @@
 {
        struct page *page = NULL;
        pte_t entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
+#ifdef CONFIG_RSS_HARDLIMIT
+       if (mm->rss > mm->rss_limit)
+               try_to_shrink_rss(mm, GFP_USER);
+#endif
        if (write_access) {
                page = alloc_page(GFP_HIGHUSER);
                if (!page)
                        return -1;
                clear_user_highpage(page, addr);
                entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-               mm->rss++;
+               if (++mm->rss > mm->maxrss)
+                       mm->maxrss = mm->rss;
                flush_page_to_ram(page);
        }
        set_pte(page_table, entry);
@@ -1107,7 +1120,8 @@
                return 0;
        if (new_page == NOPAGE_OOM)
                return -1;
-       ++mm->rss;
+       if (++mm->rss > mm->maxrss)
+               mm->maxrss = mm->rss;
        /*
         * This silly early PAGE_DIRTY setting removes a race
         * due to the bad i386 page protection. But it's valid
Index: linux-2.4.0/mm/swapfile.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/mm/swapfile.c,v
retrieving revision 1.1.1.3
diff -u -b -u -r1.1.1.3 swapfile.c
--- linux-2.4.0/mm/swapfile.c   2001/01/04 23:05:35     1.1.1.3
+++ linux-2.4.0/mm/swapfile.c   2001/01/08 04:41:58
@@ -231,7 +231,8 @@
        set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
        swap_free(entry);
        get_page(page);
-       ++vma->vm_mm->rss;
+       if (++vma->vm_mm->rss > vma->vm_mm->maxrss)
+               vma->vm_mm->maxrss = vma->vm_mm->rss;
 }
 
 static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
Index: linux-2.4.0/mm/vmscan.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/mm/vmscan.c,v
retrieving revision 1.1.1.6
diff -u -b -u -r1.1.1.6 vmscan.c
--- linux-2.4.0/mm/vmscan.c     2001/01/07 21:46:13     1.1.1.6
+++ linux-2.4.0/mm/vmscan.c     2001/01/08 04:41:58
@@ -294,6 +294,96 @@
        return result;
 }
 
+#if CONFIG_RSS_SOFTLIMIT
+int krssd(void *unused)
+{
+       struct task_struct *tsk = current;
+#define MAX_NPROCS 10
+       pid_t procs[MAX_NPROCS];
+       struct task_struct *p, *oldp;
+       unsigned long rss;
+       int nprocs, i;
+       
+       nprocs = 0;
+       (void)unused;
+
+       
+       tsk->session = 1;
+       tsk->pgrp = 1;
+       strcpy(tsk->comm, "krssd");
+       sigfillset(&tsk->blocked);
+
+       printk("Starting krssd\n");
+
+       for (;;) {
+               
+               /*
+                * Try not to wake up at the same time every second.
+                */
+               tsk->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ + 3);
+
+               /*
+                * Find up to MAX_NPROCS processes that exceed their RSS
+                * limit and attempt to shrink them.
+                * Save the PIDs of any over-limit processes in an array,
+                * so that swap_out_mm can sleep (processes can 
+                * die while we're asleep)
+                * Using PIDS rather than proc_t pointers also 
+                * reduces the time holding tasklist_lock. 
+                */
+               read_lock(&tasklist_lock);
+
+               /* select next processes to scan */
+               oldp = NULL;
+               while (nprocs && !(oldp = find_task_by_pid(procs[--nprocs])))
+                       ;
+
+               /* select init if no process found */
+               if (!oldp)
+                       oldp = &init_task;      
+
+               /* choose at most next MAX_NPROCS */
+               nprocs = 0; p = oldp;
+               while ((p = p->next_task) != oldp && nprocs < MAX_NPROCS)
+                       if (p != &init_task && p->swappable && p->mm &&
+                           p->mm->rss > p->mm->rss_limit)
+                               procs[nprocs++] = p->pid;
+               read_unlock(&tasklist_lock);
+
+               /* Attempt to shrink RSS till under limit  */
+               for (i = 0; i < nprocs; i ++) {
+                       struct mm_struct *mm;
+                       read_lock(&tasklist_lock);
+                       p = find_task_by_pid(procs[i]);
+                       if (p && (mm = p->mm))
+                               atomic_inc(&mm->mm_count);
+                       read_unlock(&tasklist_lock);
+
+                       if (!p)
+                               continue;
+
+                       /*
+                        * If pages are freed from the process but
+                        * are still in use elsewhere,
+                        * swap_out_process may return 0
+                        * but still shrink rss.
+                        * Keep calling it until it cannot do any more work,
+                        * or the limit is no longer exceeded.
+                        * TODO: think about hysteresis --- track 
+                        * persistent offenders and reduce RSS even further
+                        */
+                       while ((rss = mm->rss) > mm->rss_limit && 
+                           (swap_out_mm(mm, GFP_KSWAPD) || 
+                               rss != mm->rss))
+                               ;
+                       mmdrop(mm);
+               }
+       }
+}
+
+#endif /* CONFIG_RSS_SOFTLIMIT */
+
 /*
  * Select the task with maximal swap_cnt and try to swap out a page.
  * N.B. This function returns only 0 or 1.  Return values != 1 from
@@ -1149,7 +1239,17 @@
        swap_setup();
        kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
        kernel_thread(kreclaimd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+#ifdef CONFIG_RSS_SOFTLIMIT
+       kernel_thread(krssd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+#endif
        return 0;
 }
+
+#ifdef CONFIG_RSS_HARDLIMIT
+void try_to_shrink_rss(struct mm_struct *mm, int gfp_mask)
+{
+       swap_out_mm(mm, gfp_mask);
+}
+#endif
 
 module_init(kswapd_init)
Index: linux-2.4.0/fs/proc/rss.c
===================================================================
RCS file: /wrk/CVSROOT/linux-2.4/fs/proc/rss.c
retrieving revision 1.1
diff -u -b -u -r1.1 rss.c
--- /dev/null   Wed May  6 06:32:27 1998
+++ linux-2.4.0/fs/proc/rss.c   Mon Jan  8 15:31:22 2001
@@ -0,0 +1,239 @@
+/* fs/proc/rss.c 
+ *
+ * 15 March 2000, Kingsley Cheung 
+ * Support added for page fault calculation and /proc/pid/rss. 
+ */
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/resource.h>
+#include <linux/rss.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+
+/* 
+ * Below is a table of constants for ((k-1)/k)^n = (4/5)^n, where k is
+ * 5 seconds, n is [0..34] seconds. For n >= 35, (4/5)^n = 0.0
+ * These constants are scaled by 1000, as are the page fault
+ * rates displayed in /proc/<pid>/rss.  
+ */
+
+unsigned long mov_ave_table[MOV_AVE_TABLE_SIZE] = 
+{ 1000, 800, 640, 512, 410, 328, 262, 210, 168, 134, 107, 86, 
+  69, 55, 44, 35, 28, 23, 18, 14, 12, 9, 7, 6, 5, 4, 
+  3, 2, 2, 2, 1, 1, 1, 1, 1 };
+
+
+
+
+/* Support for /proc/<pid>/rss 
+ *
+ * pid_rss_read can integrated into array_read in fs/proc/array.c, but
+ * since we are required to support writing, we have a different set
+ * of file operations.  
+ *
+ * The data listed is the following:
+ *     - current RSS limit 
+ *     - maximum RSS limit
+ *     - RSS
+ *     - major fault rate
+ *     - minor fault rate
+ *
+ * Reading /proc/<pid>/rss is allowed only once through an open
+ * descriptor. To obtain more recent data, the file must be 
+ * closed and opened again. The file is readable by all everyone. 
+ */
+
+int proc_pid_rss_read(struct task_struct *tsk, char *buf)
+{
+       int count;
+       task_lock(tsk);
+
+       /* recalculate page fault rates due to decay */
+       decay_flt_rate(&(tsk->maj_flt_rate), &(tsk->maj_flt_time));
+       decay_flt_rate(&(tsk->min_flt_rate), &(tsk->min_flt_time)); 
+               
+       count = sprintf(buf,
+           "%ld %ld %lu %lu %lu\n",
+           tsk->rlim[RLIMIT_RSS].rlim_cur >> PAGE_SHIFT,
+           tsk->rlim[RLIMIT_RSS].rlim_max >> PAGE_SHIFT,
+           tsk->mm ? tsk->mm->rss : 0,
+           tsk->maj_flt_rate,
+           tsk->min_flt_rate);
+
+       task_unlock(tsk);
+       return count;
+}
+
+
+
+#define skip_space(buffer)                   \
+do {                                         \
+    while (*(buffer) && isspace(*(buffer)))  \
+      (buffer)++;                            \
+} while(0)
+
+
+static int get_unsigned_numbers(const char *buf, unsigned long *numbers, int count)
+/* Pre:  'numbers' is array of longs of length 'count'
+ * Post:  returns number of integers read and sets values in numbers
+ *        returns -1 whenever non-digit or white-space encountered
+ */           
+{
+       char *p; int i, neg;
+
+       /* loop and get integers, assuming all are in the buffer */
+       for (p = (char *) buf, i = 0; i < count && *p; i++) {
+               /* skip whitespace */
+               skip_space(p);
+               if (!(*p))
+                       break;
+               
+               /* test for negative values */
+               neg = 0;
+               if (*p == '-' && isdigit(*(p+1))) {
+                       neg = 1; p++;
+               }
+               
+               /* convert number */
+               numbers[i] = simple_strtoul(p, &p, 0);
+               if (neg)
+                       numbers[i] = - numbers[i];
+
+               if (*p && !isspace(*p))
+                       return -1;
+       }
+       
+       /* ensure remaining numbers are non-white space */
+       skip_space(p);
+       if (*p)
+               return -1;
+
+       return i;
+}
+
+
+#define bad_rss_limit(new_limit) \
+((new_limit) < 0 || (new_limit) > RLIM_INFINITY)
+
+#define getnextline(buf)    \
+({                          \
+        while (*(buf))      \
+                (buf)++;    \
+        (buf)++;            \
+})
+
+
+/*
+ * Only the user has write permission to proc/<pid>/rss. The contents
+ * that may be written to it specify the current and maximum RSS limits 
+ * the user wishes to set for that process. The contents written to the
+ * pseudo file must adhere to the following:
+ *
+ *     1. There can be at most two numbers per line: the new current
+ *        RSS limit followed by whitespace and the new maximum RSS
+ *        limit.
+ *
+ *      2. Whenever one number is specified on a line, the number is 
+ *         interpreted as the new current RSS limit.
+ * 
+ *      3. The current RSS limit must never exceed the maximum RSS
+ *         limit.
+ *
+ *     4. The maximum RSS limit cannot be increased except by
+ *        processes with system resource capabilities.
+ *
+ *      5. The limits must lie between the range 0 and 
+ *         RLIM_INFINITY / PAGE_SIZE inclusive.
+ *
+ * Violation of these rules will produce invalid or write permission
+ * errors. Attempts to write to /proc/<pid>/rss for non-existent
+ * processes will produce an I/O error.
+ *
+ * Writing to /proc/<pid>/rss can continue forever through an open
+ * descriptor as long as one abides by the rules stated above.
+ * Currently, ppos is not used to limit the number of characters
+ * written.  
+ */
+
+ssize_t proc_pid_rss_write(struct task_struct *tsk, struct file *file, const char 
+*buf, size_t count, loff_t *ppos)
+{
+       struct rlimit new_rss;
+       unsigned long numbers[2];
+       
+       char *page, *p; 
+       int res, ret;
+       
+       /* buffer to write to */   
+       if (!(page = (char * ) __get_free_page(GFP_KERNEL)))
+               return -ENOMEM;
+       
+       /* read user buffer up to one page only */
+       if (count > PAGE_SIZE - 1)
+               count = PAGE_SIZE - 1;
+
+       ret = count;
+
+       if (copy_from_user(page, buf, count))
+               return -EFAULT;
+
+       page[count] = 0;
+       for (p = page; *p; p++)
+               if (*p == '\n')
+                       *p = 0;
+       
+       /* obtain process current rss limits */
+       new_rss = tsk->rlim[RLIMIT_RSS];
+
+       /* for each line, read at most two integers */
+       for (p = page; p - page < count; getnextline(p)) {
+               /* read numbers from the line */
+               if ((res = get_unsigned_numbers(p, numbers, 2)) < 0) {
+                       ret = -EINVAL; 
+                       goto pid_rss_end;
+               }
+
+               /* if numbers where read from the line */
+               if (res) {
+                       /* assign values of new limits */
+                       new_rss.rlim_cur = numbers[0] * PAGE_SIZE;
+                       if (res == 2)
+                               new_rss.rlim_max = numbers[1] * PAGE_SIZE;
+                       
+                       /* ensure rss limits within defined range */
+                       if (bad_rss_limit(new_rss.rlim_cur) || 
+                           bad_rss_limit(new_rss.rlim_max) ||
+                           new_rss.rlim_cur > new_rss.rlim_max) {
+                               ret = -EINVAL; 
+                               goto pid_rss_end;
+                       } 
+                       
+                       if (new_rss.rlim_max > tsk->rlim[RLIMIT_RSS].rlim_max
+                           && !capable(CAP_SYS_RESOURCE)) {
+                               ret = -EPERM; 
+                               goto pid_rss_end;
+                       }
+                       
+                       tsk->rlim[RLIMIT_RSS] = new_rss;
+                       if (new_rss.rlim_cur == RLIM_INFINITY)
+                               tsk->mm->rss_limit = ULONG_MAX;
+                       else
+                               tsk->mm->rss_limit = new_rss.rlim_cur >> PAGE_SHIFT;
+               }
+       }
+       
+       *ppos += ret;   
+       file->f_pos += ret;
+       
+pid_rss_end:
+       free_page((unsigned long) page);  
+       
+       return ret;
+}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to