Hi Folks!
Hi Rik!

here is a preliminary patch to allow Per Context
Virtual Memory Limits for ctx17a ...

to set the limit, no additional tool is required,
just setting the virtual memory resource limit 
(ulimit -v <size>) is sufficient, the limit and 
the current value can be read via /proc/self/status

| total_vm: 25600/876

I'm not sure if virtual memory limits really are
a GoodThing(tm) but without trying it, nobody will
know ...

http://vserver.13thfloor.at/Experimental/patch-2.4.22-ctx17a-ml0.01.diff.bz2

enjoy,
Herbert




;
; Virtual Server Project
; Per Context Virtual Memory Limit
;
; (C) 2003 Herbert P�tzl <[EMAIL PROTECTED]>
;
; Changelog:
;
;   0.01  - first public release
;         - whitespace cleanups
;
; this patch is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; this patch is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;

diff -NurP --minimal linux-2.4.22-ctx17a/arch/ia64/ia32/binfmt_elf32.c 
linux-2.4.22-ctx17a-ml0.01/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.22-ctx17a/arch/ia64/ia32/binfmt_elf32.c   2003-08-25 20:32:07.000000000 
+0200
+++ linux-2.4.22-ctx17a-ml0.01/arch/ia64/ia32/binfmt_elf32.c    2003-09-05 
09:28:23.000000000 +0200
@@ -188,6 +188,7 @@
                mpnt->vm_private_data = 0;
                insert_vm_struct(current->mm, mpnt);
                current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+               ctx_vmpages_add((mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT);
        }
 
        for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
diff -NurP --minimal linux-2.4.22-ctx17a/arch/ia64/kernel/perfmon.c 
linux-2.4.22-ctx17a-ml0.01/arch/ia64/kernel/perfmon.c
--- linux-2.4.22-ctx17a/arch/ia64/kernel/perfmon.c      2003-08-25 20:32:07.000000000 
+0200
+++ linux-2.4.22-ctx17a-ml0.01/arch/ia64/kernel/perfmon.c       2003-09-05 
09:28:23.000000000 +0200
@@ -965,6 +965,7 @@
        insert_vm_struct(mm, vma);
 
        mm->total_vm  += size >> PAGE_SHIFT;
+       ctx_vmpages_add(size >> PAGE_SHIFT);
 
        up_write(&current->mm->mmap_sem);
 
diff -NurP --minimal linux-2.4.22-ctx17a/arch/ia64/mm/fault.c 
linux-2.4.22-ctx17a-ml0.01/arch/ia64/mm/fault.c
--- linux-2.4.22-ctx17a/arch/ia64/mm/fault.c    2003-08-25 20:32:07.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/arch/ia64/mm/fault.c     2003-09-05 09:28:23.000000000 
+0200
@@ -33,11 +33,14 @@
        unsigned long grow;
 
        grow = PAGE_SIZE >> PAGE_SHIFT;
+       if (!ctx_vmpages_avail(grow))
+               return -ENOMEM;
        if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur
            || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > 
current->rlim[RLIMIT_AS].rlim_cur))
                return -ENOMEM;
        vma->vm_end += PAGE_SIZE;
        vma->vm_mm->total_vm += grow;
+       ctx_vmpages_add(grow);
        if (vma->vm_flags & VM_LOCKED)
                vma->vm_mm->locked_vm += grow;
        return 0;
diff -NurP --minimal linux-2.4.22-ctx17a/arch/s390x/kernel/exec32.c 
linux-2.4.22-ctx17a-ml0.01/arch/s390x/kernel/exec32.c
--- linux-2.4.22-ctx17a/arch/s390x/kernel/exec32.c      2001-04-12 04:02:29.000000000 
+0200
+++ linux-2.4.22-ctx17a-ml0.01/arch/s390x/kernel/exec32.c       2003-09-05 
09:28:23.000000000 +0200
@@ -67,6 +67,7 @@
                mpnt->vm_private_data = (void *) 0;
                insert_vm_struct(current->mm, mpnt);
                current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+               ctx_vmpages_add((mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT);
        } 
 
        for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
diff -NurP --minimal linux-2.4.22-ctx17a/arch/x86_64/ia32/ia32_binfmt.c 
linux-2.4.22-ctx17a-ml0.01/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.4.22-ctx17a/arch/x86_64/ia32/ia32_binfmt.c  2003-08-25 20:32:10.000000000 
+0200
+++ linux-2.4.22-ctx17a-ml0.01/arch/x86_64/ia32/ia32_binfmt.c   2003-09-05 
09:28:23.000000000 +0200
@@ -253,6 +253,7 @@
                mpnt->vm_private_data = (void *) 0;
                insert_vm_struct(current->mm, mpnt);
                current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+               ctx_vmpages_add((mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT);
        } 
 
        for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
diff -NurP --minimal linux-2.4.22-ctx17a/fs/exec.c linux-2.4.22-ctx17a-ml0.01/fs/exec.c
--- linux-2.4.22-ctx17a/fs/exec.c       2003-08-26 06:27:39.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/fs/exec.c        2003-09-05 09:28:23.000000000 +0200
@@ -352,6 +352,7 @@
                mpnt->vm_private_data = (void *) 0;
                insert_vm_struct(current->mm, mpnt);
                current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+               ctx_vmpages_add((mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT);
        } 
 
        for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
diff -NurP --minimal linux-2.4.22-ctx17a/fs/proc/array.c 
linux-2.4.22-ctx17a-ml0.01/fs/proc/array.c
--- linux-2.4.22-ctx17a/fs/proc/array.c 2003-08-26 06:27:39.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/fs/proc/array.c  2003-09-05 09:28:23.000000000 +0200
@@ -316,6 +316,9 @@
                        ,task->s_info->flags);
                buffer += sprintf (buffer,"initpid: %d\n"
                        ,task->s_info->initpid);
+               buffer += sprintf (buffer,"total_vm: %ld/%d\n"
+                       ,task->s_info->rlim[RLIMIT_AS]
+                       ,atomic_read(&task->s_info->res[RLIMIT_AS]));
        }else{
                buffer += sprintf (buffer,"s_context: %d\n",task->s_context);
                buffer += sprintf (buffer,"ctxticks: none\n");
@@ -334,7 +337,7 @@
                buffer += sprintf (buffer,"ipv4root_bcast: %08x\n"
                        ,task->ip_info->v4_bcast);
                buffer += sprintf (buffer,"ipv4root_refcnt: %d\n"
-                       ,task->ip_info->refcount);
+                       ,atomic_read(&task->ip_info->refcount));
        }else{
                buffer += sprintf (buffer,"ipv4root: 0\n");
                buffer += sprintf (buffer,"ipv4root_bcast: 0\n");
diff -NurP --minimal linux-2.4.22-ctx17a/include/linux/mm.h 
linux-2.4.22-ctx17a-ml0.01/include/linux/mm.h
--- linux-2.4.22-ctx17a/include/linux/mm.h      2003-09-03 19:23:51.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/include/linux/mm.h       2003-09-05 09:40:36.000000000 
+0200
@@ -649,6 +649,8 @@
        address &= PAGE_MASK;
        spin_lock(&vma->vm_mm->page_table_lock);
        grow = (vma->vm_start - address) >> PAGE_SHIFT;
+       if (!ctx_vmpages_avail(grow))
+               return -ENOMEM;
        if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
            ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > 
current->rlim[RLIMIT_AS].rlim_cur) {
                spin_unlock(&vma->vm_mm->page_table_lock);
@@ -657,6 +659,7 @@
        vma->vm_start = address;
        vma->vm_pgoff -= grow;
        vma->vm_mm->total_vm += grow;
+       ctx_vmpages_add(grow);
        if (vma->vm_flags & VM_LOCKED)
                vma->vm_mm->locked_vm += grow;
        spin_unlock(&vma->vm_mm->page_table_lock);
diff -NurP --minimal linux-2.4.22-ctx17a/include/linux/sched.h 
linux-2.4.22-ctx17a-ml0.01/include/linux/sched.h
--- linux-2.4.22-ctx17a/include/linux/sched.h   2003-08-31 17:38:34.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/include/linux/sched.h    2003-09-05 09:40:36.000000000 
+0200
@@ -1017,6 +1017,35 @@
 void sys_assign_ip_info (struct iproot_info *);
 void sys_alloc_ip_info (void);
 
+
+static inline int ctx_vmpages_avail(int pages)
+{
+       struct context_info *si = current->s_info;
+       if (!si)
+               return 1;
+       if (si->rlim[RLIMIT_AS] == RLIM_INFINITY)
+               return 1;
+       if (si->rlim[RLIMIT_AS] < atomic_read(&si->res[RLIMIT_AS]) + pages)
+               return 0;
+       return 1;
+}
+
+static inline void ctx_vmpages_add(int pages)
+{
+       struct context_info *si = current->s_info;
+       if (!si)
+               return;
+       atomic_add(pages, &si->res[RLIMIT_AS]);
+}
+
+static inline void ctx_vmpages_sub(int pages)
+{
+       struct context_info *si = current->s_info;
+       if (!si)
+               return;
+       atomic_sub(pages, &si->res[RLIMIT_AS]);
+}
+
 static inline int need_resched(void)
 {
        return (unlikely(current->need_resched));
diff -NurP --minimal linux-2.4.22-ctx17a/kernel/fork.c 
linux-2.4.22-ctx17a-ml0.01/kernel/fork.c
--- linux-2.4.22-ctx17a/kernel/fork.c   2003-08-26 06:27:40.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/kernel/fork.c    2003-09-05 09:47:11.000000000 +0200
@@ -759,6 +759,9 @@
        if (retval)
                goto bad_fork_cleanup_namespace;
        p->semundo = NULL;
+
+       if (p->mm)
+               ctx_vmpages_add(p->mm->total_vm);
        
        /* Our parent execution domain becomes current domain
           These must match for thread signalling to apply */
diff -NurP --minimal linux-2.4.22-ctx17a/kernel/signal.c 
linux-2.4.22-ctx17a-ml0.01/kernel/signal.c
--- linux-2.4.22-ctx17a/kernel/signal.c 2003-08-26 06:27:40.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/kernel/signal.c  2003-09-05 09:28:23.000000000 +0200
@@ -1458,9 +1458,11 @@
                                found = 1;
                                if (p->s_info == NULL
                                        || (p->s_info->flags & S_CTX_INFO_PRIVATE)==0){
+                                       ctx_vmpages_sub(current->mm->total_vm);
                                        sys_release_s_info(current);
                                        sys_assign_s_info (p);
                                        current->s_info = p->s_info;
+                                       ctx_vmpages_add(current->mm->total_vm);
                                }else{
                                        ret = -EPERM;
                                }
diff -NurP --minimal linux-2.4.22-ctx17a/kernel/sys.c 
linux-2.4.22-ctx17a-ml0.01/kernel/sys.c
--- linux-2.4.22-ctx17a/kernel/sys.c    2003-08-26 06:27:40.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/kernel/sys.c     2003-09-05 09:28:23.000000000 +0200
@@ -1075,7 +1075,8 @@
 void sys_assign_s_info (struct task_struct *p)
 {
        down_write (&uts_sem);
-       if (p->s_info != NULL) p->s_info->refcount++;
+       if (p->s_info != NULL)
+               p->s_info->refcount++;
        up_write (&uts_sem);
 }
 
@@ -1123,6 +1124,9 @@
                        ,atomic_read(&current->files->count));
                // printk ("new s_info ctx=%d file->count %d\n",current->s_context
                // ,atomic_read (&s_info->res[RLIMIT_NOFILE]));
+               
+               s_info->rlim[RLIMIT_AS] = current->rlim[RLIMIT_AS].rlim_max >> 
PAGE_SHIFT;
+               atomic_set (&s_info->res[RLIMIT_AS], current->mm->total_vm);
        }
 }
 
diff -NurP --minimal linux-2.4.22-ctx17a/mm/mmap.c linux-2.4.22-ctx17a-ml0.01/mm/mmap.c
--- linux-2.4.22-ctx17a/mm/mmap.c       2003-06-13 16:51:39.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/mm/mmap.c        2003-09-05 09:28:23.000000000 +0200
@@ -500,6 +500,10 @@
            !vm_enough_memory(len >> PAGE_SHIFT))
                return -ENOMEM;
 
+       /* check context space, maybe only Private writable mapping? */
+       if (!ctx_vmpages_avail(len >> PAGE_SHIFT))
+               return -ENOMEM;
+
        /* Can we just expand an old anonymous mapping? */
        if (!file && !(vm_flags & VM_SHARED) && rb_parent)
                if (vma_merge(mm, prev, rb_parent, addr, addr + len, vm_flags))
@@ -581,6 +585,7 @@
 
 out:   
        mm->total_vm += len >> PAGE_SHIFT;
+       ctx_vmpages_add(len >> PAGE_SHIFT);
        if (vm_flags & VM_LOCKED) {
                mm->locked_vm += len >> PAGE_SHIFT;
                make_pages_present(addr, addr + len);
@@ -792,6 +797,7 @@
        unsigned long end = addr + len;
 
        area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+       ctx_vmpages_sub(len >> PAGE_SHIFT);
        if (area->vm_flags & VM_LOCKED)
                area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
 
@@ -1073,6 +1079,10 @@
        if (!vm_enough_memory(len >> PAGE_SHIFT))
                return -ENOMEM;
 
+       /* Check against context space limits */
+       if (!ctx_vmpages_avail(len >> PAGE_SHIFT))
+               return -ENOMEM;
+
        flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
 
        /* Can we just expand an old anonymous mapping? */
@@ -1100,6 +1110,7 @@
 
 out:
        mm->total_vm += len >> PAGE_SHIFT;
+       ctx_vmpages_add(len >> PAGE_SHIFT);
        if (flags & VM_LOCKED) {
                mm->locked_vm += len >> PAGE_SHIFT;
                make_pages_present(addr, addr + len);
@@ -1135,6 +1146,7 @@
        mm->mm_rb = RB_ROOT;
        mm->rss = 0;
        spin_unlock(&mm->page_table_lock);
+       ctx_vmpages_sub(mm->total_vm);
        mm->total_vm = 0;
        mm->locked_vm = 0;
 
diff -NurP --minimal linux-2.4.22-ctx17a/mm/mremap.c 
linux-2.4.22-ctx17a-ml0.01/mm/mremap.c
--- linux-2.4.22-ctx17a/mm/mremap.c     2003-08-25 20:32:20.000000000 +0200
+++ linux-2.4.22-ctx17a-ml0.01/mm/mremap.c      2003-09-05 09:28:23.000000000 +0200
@@ -195,6 +195,7 @@
                do_munmap(current->mm, addr, old_len);
 
                current->mm->total_vm += new_len >> PAGE_SHIFT;
+               ctx_vmpages_add(new_len >> PAGE_SHIFT);
                if (vm_locked) {
                        current->mm->locked_vm += new_len >> PAGE_SHIFT;
                        if (new_len > old_len)
@@ -295,6 +296,9 @@
            !(flags & MAP_NORESERVE)                             &&
            !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
                goto out;
+       /* check context space, maybe only Private writable mapping? */
+       if (!ctx_vmpages_avail((new_len - old_len) >> PAGE_SHIFT))
+               goto out;
 
        /* old_len exactly to the end of the area..
         * And we're not relocating the area.
@@ -312,6 +316,7 @@
                        vma->vm_end = addr + new_len;
                        spin_unlock(&vma->vm_mm->page_table_lock);
                        current->mm->total_vm += pages;
+                       ctx_vmpages_add(pages);
                        if (vma->vm_flags & VM_LOCKED) {
                                current->mm->locked_vm += pages;
                                make_pages_present(addr + old_len,

Reply via email to