Skip to contentSkip to conversation

mm: add ulimit API for user

PATCH In review Xishi Qiu 2 participants 2 messages Dec 31, 2013 – Jan 6, 2014

Subsystems (3)
lore
Share & tools
lore

Xishi Qiu

author
#0 lore raw

PATCH 1/1 mm: add ulimit API for user

Add ulimit API for users. When memory is not enough, user's app will receive a signal, and it can do something in the handler.

e.g.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
void handler(int sig)
{
char *b = malloc(1000000000);
memset(b, '\0', 1000000000);
printf("catch the signal by wwy\n");
exit(1);
}
int main ( int argc, char *argv[] )
{
struct rlimit r1 = { 3600000000, 3600000000}; setrlimit(RLIMIT_AS, &r1);
signal(47, &handler);
char * a = malloc(3600000000);
int fd=open("/home/wayne/qemu.tar.bz2", O_RDONLY); char abc[2000000] = {'\0'};
mmap(NULL, 10000000, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd , 0); sleep(100);
free(a);
while(1){
}
}

RTOS-x86_64 /tmp # ./a.out
catch the signal by wwy

mm/Makefile +1 -0
index 9c60f76..a5dec90 100644
@@ -18,6 +18,7 @@ obj-y += init-mm.o
 ifdef CONFIG_OOM_EXTEND
 obj-y += oom_extend.o pagecache_info.o
 endif
+obj-y += ulimit-init.o
 
 obj-$(CONFIG_BOUNCE)	+= bounce.o
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
mm/mmap.c +6 -0
index 4ff7f52..a10155f 100644
@@ -2402,6 +2402,11 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
  * Return true if the calling process may expand its vm space by the passed
  * number of pages
  */
+
+#ifdef CONFIG_ULIMIT_VM_SIG
+unsigned long vm_expand_signal_enable = 0;
+EXPORT_SYMBOL(vm_expand_signal_enable);
+#endif
+
 int may_expand_vm(struct mm_struct *mm, unsigned long npages)
 {

unsigned long cur = mm->total_vm; /* pages */
@@ -2410,7 +2415,9 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;

if (cur + npages > lim){
- send_sig(SIGRTMIN+15, current, 1);
+#ifdef CONFIG_ULIMIT_VM_SIG
+ if (vm_expand_signal_enable){
+ send_sig(SIGRTMIN+15, current, 1);
+ }
+#endif
return 0;
}
return 1;

mm/ulimit-init.c new file +65 -0

65 lines not on this page · raw message

+MODULE_AUTHOR("Wayne");

mm/Kconfig +2 -0
index ef891af..dc9c881 100644
@@ -295,3 +295,6 @@ config NOMMU_INITIAL_TRIM_EXCESS
 	  of 1 says that all excess pages should be trimmed.
 
 	  See Documentation/nommu-mmap.txt for more information.
+config ULIMIT_VM_SIG
+	bool "vm expand send SIG 47"
mm/Makefile +2 -1
index a5dec90..5c4d70f 100644
@@ -18,8 +18,9 @@ obj-y += init-mm.o
 ifdef CONFIG_OOM_EXTEND
 obj-y += oom_extend.o pagecache_info.o
 endif
+ifdef CONFIG_ULIMIT_VM_SIG
 obj-y += ulimit-init.o
-
+endif
 obj-$(CONFIG_BOUNCE)	+= bounce.o
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HAS_DMA)	+= dmapool.o

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#1 lore raw
Quoted 30 lines · Xishi Qiu

Add ulimit API for users. When memory is not enough, user's app will receive a signal, and it can do something in the handler.

e.g.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
void handler(int sig)
{
char *b = malloc(1000000000);
memset(b, '\0', 1000000000);
printf("catch the signal by wwy\n");
exit(1);
}
int main ( int argc, char *argv[] )
{
struct rlimit r1 = { 3600000000, 3600000000}; setrlimit(RLIMIT_AS, &r1);
signal(47, &handler);
char * a = malloc(3600000000);
int fd=open("/home/wayne/qemu.tar.bz2", O_RDONLY); char abc[2000000] = {'\0'};
mmap(NULL, 10000000, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd , 0); sleep(100);
free(a);
while(1){
}
}

Quoted 2 lines

RTOS-x86_64 /tmp # ./a.out
catch the signal by wwy

How does this demonstrate the newly added knob?

[...]

Quoted 18 lines
mm/mmap.c +6 -0
index 4ff7f52..a10155f 100644
@@ -2402,6 +2402,11 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
  * Return true if the calling process may expand its vm space by the passed
  * number of pages
  */
+
+#ifdef CONFIG_ULIMIT_VM_SIG
+unsigned long vm_expand_signal_enable = 0;
+EXPORT_SYMBOL(vm_expand_signal_enable);
+#endif
+
 int may_expand_vm(struct mm_struct *mm, unsigned long npages)
 {
 	unsigned long cur = mm->total_vm;	/* pages */

mm/mmap.c int may_expand_vm(struct mm_struct *mm, unsigned long npages) · line 2413

Quoted 4 lines
mm/mmap.c +0 -1
@@ -2410,7 +2415,9 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
 	lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
 
 	if (cur + npages > lim){
-		send_sig(SIGRTMIN+15, current, 1);

What kind of tree is this based on? Neither Linus' nor Andrew's tree sends the signal. And I would be really surprised if such a change would be accepted at all because may_expand_vm is not supposed to send a signal. Only automatic stack expansion is supposed to send SEGV other callers should simply return ENOMEM

Quoted 8 lines
mm/mmap.c +5 -0
+#ifdef	CONFIG_ULIMIT_VM_SIG
+		if (vm_expand_signal_enable){
+			send_sig(SIGRTMIN+15, current, 1);
+		}
+#endif
 		return 0;
 	}
 	return 1;
Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>