About this list Date view Thread view Subject view Author view Attachment view

From: Herbert Poetzl (herbert_at_13thfloor.at)
Date: Fri 05 Sep 2003 - 09:11:32 BST


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 <herbert_at_13thfloor.at>
;
; 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,


About this list Date view Thread view Subject view Author view Attachment view
[Next/Previous Months] [Main vserver Project Homepage] [Howto Subscribe/Unsubscribe] [Paul Sladen's vserver stuff]
Generated on Fri 05 Sep 2003 - 09:44:45 BST by hypermail 2.1.3