]> sourceware.org Git - glibc.git/commitdiff
Reduce number of mmap calls from __libc_memalign in ld.so
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 23 Apr 2016 13:05:01 +0000 (06:05 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 23 Apr 2016 13:05:15 +0000 (06:05 -0700)
__libc_memalign in ld.so allocates one page at a time and tries to
optimize consecutive __libc_memalign calls by hoping that the next
mmap is after the current memory allocation.

However, the kernel hands out mmap addresses in top-down order, so
this optimization in practice never happens, with the result that we
have more mmap calls and waste a bunch of space for each __libc_memalign.

This change makes __libc_memalign to mmap one page extra.  Worst case,
the kernel never puts a backing page behind it, but best case it allows
__libc_memalign to operate much much better.  For elf/tst-align --direct,
it reduces number of mmap calls from 12 to 9.

* elf/dl-minimal.c (__libc_memalign): Mmap one extra page.

ChangeLog
elf/dl-minimal.c

index 5cd8c4012bdcb076736c3899c435195be5045ded..744c0c0fb7cfa7abdb7d253e819c44e8365f8287 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2016-04-23   H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf/dl-minimal.c (__libc_memalign): Mmap one extra page.
+
 2016-04-23  Mike Frysinger  <vapier@gentoo.org>
 
        * locale/programs/ld-time.c (time_finish): Set week_1stweek to 7
index 762e65b4d079f71f0b477560d4414730c86458c8..c8a8f8dc931a1bc5119b71534d044323bc618fde 100644 (file)
@@ -66,15 +66,13 @@ __libc_memalign (size_t align, size_t n)
 
   if (alloc_ptr + n >= alloc_end || n >= -(uintptr_t) alloc_ptr)
     {
-      /* Insufficient space left; allocate another page.  */
+      /* Insufficient space left; allocate another page plus one extra
+        page to reduce number of mmap calls.  */
       caddr_t page;
       size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
-      if (__glibc_unlikely (nup == 0))
-       {
-         if (n)
-           return NULL;
-         nup = GLRO(dl_pagesize);
-       }
+      if (__glibc_unlikely (nup == 0 && n != 0))
+       return NULL;
+      nup += GLRO(dl_pagesize);
       page = __mmap (0, nup, PROT_READ|PROT_WRITE,
                     MAP_ANON|MAP_PRIVATE, -1, 0);
       if (page == MAP_FAILED)
This page took 0.172204 seconds and 5 git commands to generate.