about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2015-08-24 13:02:30 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2015-08-24 14:37:58 +0530
commitdb8629e263caface76d0989979937ef09654e96f (patch)
treeee7e1a6433ea525ab7305af967c2b6ec65065fd6
parentc3b9ef8dfc83e9d17da5adc73709d2f7dfbbaf13 (diff)
downloadglibc-siddhesh/mmap-fallback.tar.gz
glibc-siddhesh/mmap-fallback.tar.xz
glibc-siddhesh/mmap-fallback.zip
Don't fall back to mmap if the original arena is not corrupt siddhesh/mmap-fallback
The new logic to find an uncontended non-corrupt arena misses a case
where the current arena is contended, but is not corrupt.  In the
degenerate case, this is the only arena.  In both cases, the logic
falls back to using mmap despite there being an available arena.

Attached patch by Josef Bacik makes sure that all arenas are indeed
corrupt before falling back to malloc.  Verified on x86_64 that the
testsuite does not regress.

	* malloc/arena.c (reused_arena): return NULL only if all
	arenas are corrupt.
-rw-r--r--malloc/arena.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/malloc/arena.c b/malloc/arena.c
index b44e307ade..060eb95375 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -816,23 +816,28 @@ reused_arena (mstate avoid_arena)
     }
   while (result != next_to_use);
 
-  /* Avoid AVOID_ARENA as we have already failed to allocate memory
-     in that arena and it is currently locked.   */
+  /* Avoid AVOID_ARENA as we have already failed to allocate memory in that
+     arena.  We may however end up with AVOID_ARENA once again if it is
+     the only arena available.  */
   if (result == avoid_arena)
     result = result->next;
 
   /* Make sure that the arena we get is not corrupted.  */
   mstate begin = result;
+  bool looped = false;
+
   while (arena_is_corrupt (result) || result == avoid_arena)
     {
       result = result->next;
       if (result == begin)
-	break;
+	{
+	  looped = true;
+	  break;
+	}
     }
 
-  /* We could not find any arena that was either not corrupted or not the one
-     we wanted to avoid.  */
-  if (result == begin || result == avoid_arena)
+  /* We could not find any arena that was not corrupted.  */
+  if (looped)
     return NULL;
 
   /* No arena available without contention.  Wait for the next in line.  */