From: Rob L. <ro...@la...> - 2005-11-28 16:30:23
|
Signed-off-by: Rob Landley <ro...@la...> UML really wants shared memory semantics form its physical memory map file, and the place for that is /dev/shm. So move the default, and fix the error messages to recognize that this value can be overridden. --- Let's try that again with wordrap off... UML calls mmap() to allocate some "physical memory" it shares between processes. If we're not careful, every page of this memory that gets dirtied is pointelessly scheduled for writeout, which means an active user mode instance running a compiler or some such can keep the disk pegged with unnecessary I/O and slow the rest of the system to a crawl. Back under 2.4 there was a performance hack that if you deleted a file you had open and mmaped, dirty pages wouldn't get written out anymore unless they were evicted due to memory pressure. This hack got yanked sometime during 2.5, and now you're supposed to use tmpfs if you want file-backed memory you can dirty without causing unnecessary write I/O. UML assumed that /tmp would be tmpfs, but this turns out not to be the default on the systems I checked (Fedora Core 4, Ubuntu, and Gentoo). But all of these systems _do_ default to having a tmpfs mount on /dev/shm, which makes sense since tmpfs used to be shmfs. So that's a more logical default location for UML's physical memory file. (You can override the default location with the TMPDIR environment variable, but you can't create a new tmpdir mount without root access, and running UML should never require that.) One function is moved to another file, but the only changes are to its printf()s. diff -ur linux-2.6.15-rc2/arch/um-old/os-Linux/mem.c linux-2.6.15-rc2/arch/um/os-Linux/mem.c --- linux-2.6.15-rc2/arch/um-old/os-Linux/mem.c 2005-11-23 02:35:49.000000000 -0600 +++ linux-2.6.15-rc2/arch/um/os-Linux/mem.c 2005-11-28 09:33:21.158395976 -0600 @@ -34,7 +34,7 @@ break; } if((dir == NULL) || (*dir == '\0')) - dir = "/tmp"; + dir = "/dev/shm"; tempdir = malloc(strlen(dir) + 2); if(tempdir == NULL){ @@ -159,3 +159,26 @@ } return(fd); } + + +void check_tmpexec(void) +{ + void *addr; + int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); + + addr = mmap(NULL, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); + printf("Checking PROT_EXEC mmap in %s...",tempdir); + fflush(stdout); + if(addr == MAP_FAILED){ + err = errno; + perror("failed"); + if(err == EPERM) + printf("%s must be not mounted noexec\n",tempdir); + exit(1); + } + printf("OK\n"); + munmap(addr, UM_KERN_PAGE_SIZE); + + close(fd); +} diff -ur linux-2.6.15-rc2/arch/um-old/os-Linux/start_up.c linux-2.6.15-rc2/arch/um/os-Linux/start_up.c --- linux-2.6.15-rc2/arch/um-old/os-Linux/start_up.c 2005-11-23 02:35:49.000000000 -0600 +++ linux-2.6.15-rc2/arch/um/os-Linux/start_up.c 2005-11-28 09:41:04.051025600 -0600 @@ -296,29 +296,7 @@ check_sysemu(); } -extern int create_tmp_file(unsigned long long len); - -static void check_tmpexec(void) -{ - void *addr; - int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); - - addr = mmap(NULL, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); - printf("Checking PROT_EXEC mmap in /tmp..."); - fflush(stdout); - if(addr == MAP_FAILED){ - err = errno; - perror("failed"); - if(err == EPERM) - printf("/tmp must be not mounted noexec\n"); - exit(1); - } - printf("OK\n"); - munmap(addr, UM_KERN_PAGE_SIZE); - - close(fd); -} +extern void check_tmpexec(void); void os_early_checks(void) { -- Steve Ballmer: Innovation! Inigo Montoya: You keep using that word. I do not think it means what you think it means. |