Commit Graph

28 Commits

Author SHA1 Message Date
Alex Shlyapnikov 8a8d945df7 [Sanitizers] Add more details to ASan allocator stats report.
Summary: .

Reviewers: cryptoad

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D38834

llvm-svn: 315730
2017-10-13 18:38:10 +00:00
Alex Shlyapnikov 04ce5ac306 [Sanitizers] Allocator: new "release memory to OS" implementation
Summary:
The current implementation of the allocator returning freed memory
back to OS (controlled by allocator_release_to_os_interval_ms flag)
requires sorting of the free chunks list, which has two major issues,
first, when free list grows to millions of chunks, sorting, even the
fastest one, is just too slow, and second, sorting chunks in place
is unacceptable for Scudo allocator as it makes allocations more
predictable and less secure.

The proposed approach is linear in complexity (altough requires quite
a bit more temporary memory). The idea is to count the number of free
chunks on each memory page and release pages containing free chunks
only. It requires one iteration over the free list of chunks and one
iteration over the array of page counters. The obvious disadvantage
is the allocation of the array of the counters, but even in the worst
case we support (4T allocator space, 64 buckets, 16 bytes bucket size,
full free list, which leads to 2 bytes per page counter and ~17M page
counters), requires just about 34Mb of the intermediate buffer (comparing
to ~64Gb of actually allocated chunks) and usually it stays under 100K
and released after each use. It is expected to be a relatively rare event,
releasing memory back to OS, keeping the buffer between those runs
and added complexity of the bookkeeping seems unnesessary here (it can
always be improved later, though, never say never).

The most interesting problem here is how to calculate the number of chunks
falling into each memory page in the bucket. Skipping all the details,
there are three cases when the number of chunks per page is constant:
  1) P >= C, P % C == 0 --> N = P / C
  2) C > P , C % P == 0 --> N = 1
  3) C <= P, P % C != 0 && C % (P % C) == 0 --> N = P / C + 1
where P is page size, C is chunk size and N is the number of chunks per
page and the rest of the cases, where the number of chunks per page is
calculated on the go, during the page counter array iteration.

Among the rest, there are still cases where N can be deduced from the
page index, but they require not that much less calculations per page
than the current "brute force" way and 2/3 of the buckets fall into
the first three categories anyway, so, for the sake of simplicity,
it was decided to stick to those two variations. It can always be
refined and improved later, should we see that brute force way slows
us down unacceptably.

Reviewers: eugenis, cryptoad, dvyukov

Subscribers: kubamracek, mehdi_amini, llvm-commits

Differential Revision: https://reviews.llvm.org/D38245

llvm-svn: 314311
2017-09-27 15:38:05 +00:00
Kostya Kortchinsky b138ab810f [sanitizer] Small tweaks and fixes to allocator related functions
Summary:
In `sanitizer_allocator_primary32.h`:
- rounding up in `MapWithCallback` is not needed as `MmapOrDie` does it. Note
  that the 64-bit counterpart doesn't round up, this keeps the behavior
  consistent;
- since `IsAligned` exists, use it in `AllocateRegion`;
- in `PopulateFreeList`:
  - checking `b->Count` to be greater than 0 when `b->Count() == max_count` is
    redundant when done more than once. Just check that `max_count` is greater
    than 0 out of the loop; the compiler (at least on ARM) didn't optimize it;
  - mark the batch creation failure as `UNLIKELY`;

In `sanitizer_allocator_primary64.h`:
- in `MapWithCallback`, mark the failure condition as `UNLIKELY`;

In `sanitizer_posix.h`:
- mark a bunch of Mmap related failure conditions as `UNLIKELY`;
- in `MmapAlignedOrDieOnFatalError`, we have `IsAligned`, so use it; rearrange
  the conditions as one test was redudant;
- in `MmapFixedImpl`, 30 chars was not large enough to hold the message and a
  full 64-bit address (or at least a 48-bit usermode address), increase to 40.

Reviewers: alekseyshl

Reviewed By: alekseyshl

Subscribers: aemerson, kubamracek, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D34840

llvm-svn: 306834
2017-06-30 16:05:40 +00:00
Alex Shlyapnikov 01676883cd [Sanitizers] 64 bit allocator respects allocator_may_return_null flag
Summary:
Make SizeClassAllocator64 return nullptr when it encounters OOM, which
allows the entire sanitizer's allocator to follow
allocator_may_return_null=1 policy
(LargeMmapAllocator: D34243, SizeClassAllocator64: D34433).

Reviewers: eugenis

Subscribers: srhines, kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D34540

llvm-svn: 306342
2017-06-26 22:54:10 +00:00
Evgeniy Stepanov 04cfed9af5 Improved ASAN allocator and quarantine stats.
Summary: Improved ASAN allocator and quarantine stats.

Reviewers: eugenis

Patch by Alex Shlyapnikov.

Subscribers: llvm-commits, kubabrecka

Differential Revision: https://reviews.llvm.org/D28333

llvm-svn: 291183
2017-01-05 22:17:53 +00:00
Evgeniy Stepanov e109ef854a Release memory to OS only when the requested range covers the entire page
Summary:
The current code was sometimes attempting to release huge chunks of
memory due to undesired RoundUp/RoundDown interaction when the requested
range is fully contained within one memory page.

Reviewers: eugenis

Subscribers: kubabrecka, llvm-commits

Patch by Aleksey Shlyapnikov.

Differential Revision: https://reviews.llvm.org/D27228

llvm-svn: 288271
2016-11-30 20:41:59 +00:00
Evgeniy Stepanov d3305afc75 Return memory to OS right after free (not in the async thread).
Summary:
In order to avoid starting a separate thread to return unused memory to
the system (the thread interferes with process startup on Android,
Zygota waits for all threads to exit before fork, but this thread never
exits), try to return it right after free.

Reviewers: eugenis

Subscribers: cryptoad, filcab, danalbert, kubabrecka, llvm-commits

Patch by Aleksey Shlyapnikov.

Differential Revision: https://reviews.llvm.org/D27003

llvm-svn: 288091
2016-11-29 00:22:50 +00:00
Kostya Serebryany 58560a05ad [sanitizer] fix an allocator bug where the allocated memory may overlap with the free array (kudos to Kostya Korcthinsky). Also make sure that the allocator does not mmap more than requested. Test both.
llvm-svn: 281103
2016-09-09 21:42:33 +00:00
Kostya Serebryany 6496de48c7 [scudo] use 32 bits of ASLR entropy instead of just 24 when shuffling allocated chunks
llvm-svn: 279983
2016-08-29 17:45:43 +00:00
Kostya Serebryany b72479b84a [asan] first attempt at releasing free-d memory back to the system using madvise. Requires quite some tuning.
llvm-svn: 279887
2016-08-26 23:58:42 +00:00
Kostya Serebryany 7c5ae7cbc6 [sanitizer] enable random shuffling the memory chunks inside the allocator, under a flag. Set this flag for the scudo allocator, add a test.
llvm-svn: 279793
2016-08-26 00:06:03 +00:00
Kostya Serebryany 15647b17f3 [sanitizer] change SizeClassAllocator64 to accept just one template parameter instead of 5. First, this will make the mangled names shorter. Second, this will make adding more parameters simpler.
llvm-svn: 279771
2016-08-25 20:23:08 +00:00
Kostya Serebryany 8e7ea9ddb5 [sanitizer] re-apply r279572 and r279595 reverted in r279643: change the 64-bit allocator to use a single array for free-d chunks instead of a lock-free linked list of tranfer batches. This change simplifies the code, makes the allocator more 'hardened', and will allow simpler code to release RAM to OS. This may also slowdown malloc stress tests due to lock contension, but I did not observe noticeable slowdown on various real multi-threaded benchmarks.
llvm-svn: 279664
2016-08-24 21:20:10 +00:00
Vitaly Buka 769ec705bc Revert r279572 "[sanitizer] change the 64-bit..." because of failures on ubsan
This reverts commit r279572 and r279595.

llvm-svn: 279643
2016-08-24 17:40:29 +00:00
Kostya Serebryany 865a98d2ed [sanitizer] trying to fix the PPC bots
llvm-svn: 279595
2016-08-24 00:10:25 +00:00
Kostya Serebryany f46d50e360 [sanitizer] change the 64-bit allocator to use a single array for free-d chunks instead of a lock-free linked list of tranfer batches. This change simplifies the code, makes the allocator more 'hardened', and will allow simpler code to release RAM to OS. This may also slowdown malloc stress tests due to lock contension, but I did not observe noticeable slowdown on various real multi-threaded benchmarks.
llvm-svn: 279572
2016-08-23 21:19:47 +00:00
Kostya Serebryany ce2163459f [sanitizer] allocator: split the local cache class into two, one for 32-bit allocator and one for 64-bit one. NFC. The two imlementations will diverge in the following changes.
llvm-svn: 279495
2016-08-23 00:30:43 +00:00
Kostya Serebryany 1ab649649d [sanitizer] use 32-bit offset instead of 64-bit pointers in the 64-bit allocator's transfer batches. This saves 2x memory for the transfer batches (up to ~1.5% overall in some cases)
llvm-svn: 278179
2016-08-09 23:30:22 +00:00
Kostya Serebryany d4a5749677 [sanitizer] minor refactoring in the allocator, NFC
llvm-svn: 278163
2016-08-09 20:54:50 +00:00
Kostya Serebryany 4cd2845e6a [sanitizer] allocator: move TransferBatch into SizeClassAllocator64/SizeClassAllocator32 because we actually need different iplementations for the 64- and 32-bit case. NFC; the following patches will make the TransferBatch implementations differ
llvm-svn: 277899
2016-08-06 01:24:11 +00:00
Etienne Bergeron d2b37ada4d fix whitespaces from https://reviews.llvm.org/D23170
llvm-svn: 277746
2016-08-04 18:30:41 +00:00
Etienne Bergeron 27eb6d521e [compiler-rt] Fix memory allocator for dynamic address space
Summary:
The sanitizer allocators can works with a dynamic address space
(i.e. specified with ~0ULL).

Unfortunately, the code was broken on GetMetadata and GetChunkIdx.

The current patch is moving the Win64 memory test to a dynamic
address space. There is a migration to move every concept to a
dynamic address space on windows.

To have a better coverage, the unittest are now testing
dynamic address space on other platforms too.

Reviewers: rnk, kcc

Subscribers: kubabrecka, dberris, llvm-commits, chrisha

Differential Revision: https://reviews.llvm.org/D23170

llvm-svn: 277745
2016-08-04 18:15:38 +00:00
Kostya Serebryany c49e296805 [sanitizer] refactor TransferBatch to hide the implementation. NFC expected. Second attempt after failed r276383 which was reverted.
llvm-svn: 277554
2016-08-03 00:14:10 +00:00
Kostya Serebryany d251e94a01 [sanitizer] revert r276383 while investigating failures on bot
llvm-svn: 276456
2016-07-22 19:02:59 +00:00
Kostya Serebryany 5bc01c108d [sanitizer] refactor TransferBatch to hide the implementation. NFC
llvm-svn: 276383
2016-07-22 02:21:12 +00:00
Kostya Serebryany 395386f910 [sanitizer] better allocator stats (with rss)
llvm-svn: 276343
2016-07-21 21:38:40 +00:00
Kostya Serebryany 35eeea707e [sanitizer] allocator: remove kPopulateSize and only use SizeClassMap::MaxCached; ensure that TransferBatch size is a power of two, refactor TransferBatch creation/destruction into separate functions.
llvm-svn: 276318
2016-07-21 18:47:53 +00:00
Kostya Serebryany 9835a81529 [sanitizers] split sanitizer_allocator.h into a number of smaller .h files; NFC
llvm-svn: 276195
2016-07-20 22:06:41 +00:00