Nick Piggin wrote: > Jakub Jelinek wrote: > >> On Wed, Apr 04, 2007 at 05:46:12PM +1000, Nick Piggin wrote: >> >>> Does mmap(PROT_NONE) actually free the memory? >> >> >> >> Yes. >> /* Clear old maps */ >> error = -ENOMEM; >> munmap_back: >> vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); >> if (vma && vma->vm_start < addr + len) { >> if (do_munmap(mm, addr, len)) >> return -ENOMEM; >> goto munmap_back; >> } > > > Thanks, I overlooked the mmap vs mprotect detail. So how are the subsequent > access faults avoided? AFAIKS, the faults are not avoided. Not for single page allocations, not for multi-page allocations. So what glibc currently does to allocate, use, then deallocate a page is this: mprotect(PROT_READ|PROT_WRITE) -> down_write(mmap_sem) touch page -> page fault -> down_read(mmap_sem) mmap(PROT_NONE) -> down_write(mmap_sem) What it could be doing is: touch page -> page fault -> down_read(mmap_sem) madvise(MADV_DONTNEED) -> down_read(mmap_sem) So after my previously posted patch (attached again) to only take down_read in madvise where possible... With 2 threads, the attached test.c ends up doing about 140,000 context switches per second with just 2 threads/2CPUs, takes a little over 2 million faults, and about 80 seconds to complete, when running the old_test() function (ie. mprotect,touch,mmap). When running new_test() (ie. touch,madvise), context switches stay well under 100, it takes slightly fewer faults, and it completes in about 8 seconds. With 1 thread, new_test() actually completes in under half the time as well (4.55 vs 9.88 seconds). This result won't have been altered by my madvise patch, because the down_write fastpath is no slower than down_read. Any comments? -- SUSE Labs, Novell Inc.