summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-01-25 02:05:48 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-01-25 02:05:48 +0000
commitf4e7051c6736e83facc072e06344b7b52bbf2183 (patch)
treee9516a035c5c1680eb963d34c1232f242b16de0a
parent9ea001401caa607dccbd974df0d44b13be63de20 (diff)
downloadbcm5719-llvm-f4e7051c6736e83facc072e06344b7b52bbf2183.tar.gz
bcm5719-llvm-f4e7051c6736e83facc072e06344b7b52bbf2183.zip
[hwasan] Madvise away thread aux data
Summary: Release memory pages for thread data (allocator cache, stack allocations ring buffer, etc) when a thread exits. We can not simply munmap them because this memory is custom allocated within a limited address range, and it needs to stay "reserved". This change alters thread storage layout by putting the ring buffer before Thread instead of after it. This makes it possible to find the start of the thread aux allocation given only the Thread pointer. Reviewers: kcc, pcc Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D56621 llvm-svn: 352151
-rw-r--r--compiler-rt/lib/hwasan/hwasan_thread_list.h42
1 files changed, 29 insertions, 13 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan_thread_list.h b/compiler-rt/lib/hwasan/hwasan_thread_list.h
index 72827861ac3..914b632d977 100644
--- a/compiler-rt/lib/hwasan/hwasan_thread_list.h
+++ b/compiler-rt/lib/hwasan/hwasan_thread_list.h
@@ -108,38 +108,52 @@ struct ThreadStats {
class HwasanThreadList {
public:
HwasanThreadList(uptr storage, uptr size)
- : free_space_(storage),
- free_space_end_(storage + size),
- ring_buffer_size_(RingBufferSize()) {}
+ : free_space_(storage), free_space_end_(storage + size) {
+ // [storage, storage + size) is used as a vector of
+ // thread_alloc_size_-sized, ring_buffer_size_*2-aligned elements.
+ // Each element contains
+ // * a ring buffer at offset 0,
+ // * a Thread object at offset ring_buffer_size_.
+ ring_buffer_size_ = RingBufferSize();
+ thread_alloc_size_ =
+ RoundUpTo(ring_buffer_size_ + sizeof(Thread), ring_buffer_size_ * 2);
+ }
Thread *CreateCurrentThread() {
Thread *t;
{
SpinMutexLock l(&list_mutex_);
t = free_list_.Pop();
- if (t)
- internal_memset((void *)t, 0, sizeof(Thread) + ring_buffer_size_);
- else
+ if (t) {
+ uptr start = (uptr)t - ring_buffer_size_;
+ internal_memset((void *)start, 0, ring_buffer_size_ + sizeof(Thread));
+ } else {
t = AllocThread();
+ }
live_list_.Push(t);
}
- t->Init((uptr)(t + 1), ring_buffer_size_);
+ t->Init((uptr)t - ring_buffer_size_, ring_buffer_size_);
AddThreadStats(t);
return t;
}
+ void DontNeedThread(Thread *t) {
+ uptr start = (uptr)t - ring_buffer_size_;
+ ReleaseMemoryPagesToOS(start, start + thread_alloc_size_);
+ }
+
void ReleaseThread(Thread *t) {
- // FIXME: madvise away the ring buffer?
RemoveThreadStats(t);
t->Destroy();
SpinMutexLock l(&list_mutex_);
live_list_.Remove(t);
free_list_.Push(t);
+ DontNeedThread(t);
}
Thread *GetThreadByBufferAddress(uptr p) {
- uptr align = ring_buffer_size_ * 2;
- return (Thread *)(RoundDownTo(p, align) - sizeof(Thread));
+ return (Thread *)(RoundDownTo(p, ring_buffer_size_ * 2) +
+ ring_buffer_size_);
}
uptr MemoryUsedPerThread() {
@@ -175,15 +189,17 @@ class HwasanThreadList {
private:
Thread *AllocThread() {
uptr align = ring_buffer_size_ * 2;
- uptr ring_buffer_start = RoundUpTo(free_space_ + sizeof(Thread), align);
- free_space_ = ring_buffer_start + ring_buffer_size_;
+ CHECK(IsAligned(free_space_, align));
+ Thread *t = (Thread *)(free_space_ + ring_buffer_size_);
+ free_space_ += thread_alloc_size_;
CHECK(free_space_ <= free_space_end_ && "out of thread memory");
- return (Thread *)(ring_buffer_start - sizeof(Thread));
+ return t;
}
uptr free_space_;
uptr free_space_end_;
uptr ring_buffer_size_;
+ uptr thread_alloc_size_;
ThreadListHead free_list_;
ThreadListHead live_list_;
OpenPOWER on IntegriCloud