Use MADV_DONTNEED for alternate signal stack.
It seems MADV_FREE still counts toward PSS.
Also add a few checks before the `madvise()` call.
Test: testrunner.py --target --64 --optimizing
Bug: 38383823
Bug: 213757852
Change-Id: I8659f8f0490004eb5caba63d0c913931597393b9
diff --git a/runtime/thread_android.cc b/runtime/thread_android.cc
index 9b58c95..e8d01cc 100644
--- a/runtime/thread_android.cc
+++ b/runtime/thread_android.cc
@@ -17,6 +17,8 @@
#include <signal.h>
#include <sys/mman.h>
+#include "base/globals.h"
+#include "base/bit_utils.h"
#include "thread.h"
namespace art {
@@ -33,10 +35,16 @@
stack_t old_ss;
int result = sigaltstack(nullptr, &old_ss);
CHECK_EQ(result, 0);
- // Note: We're testing and benchmarking ART on devices with old kernels
- // which may not support `MADV_FREE`, so we do not check the result.
- // It should succeed on devices with Android 12+.
- madvise(old_ss.ss_sp, old_ss.ss_size, MADV_FREE);
+ // Only call `madvise()` on enabled page-aligned alternate signal stack. Processes can
+ // create different arbitrary alternate signal stacks and we do not want to erroneously
+ // `madvise()` away pages that may hold data other than the alternate signal stack.
+ if ((old_ss.ss_flags & SS_DISABLE) == 0 &&
+ IsAligned<kPageSize>(old_ss.ss_sp) &&
+ IsAligned<kPageSize>(old_ss.ss_size)) {
+ CHECK_EQ(old_ss.ss_flags & SS_ONSTACK, 0);
+ result = madvise(old_ss.ss_sp, old_ss.ss_size, MADV_DONTNEED);
+ CHECK_EQ(result, 0);
+ }
}
} // namespace art