|
18 | 18 | #include "MemoryMapped.h" |
19 | 19 | #include "MemoryTracker.h" |
20 | 20 | #include <algorithm> |
| 21 | +#include <cerrno> |
| 22 | +#include <cstring> |
21 | 23 | #include <sys/mman.h> |
22 | 24 | #include <fstream> // std::ifstream |
23 | 25 |
|
@@ -358,12 +360,39 @@ uint64_t Util::getL2CacheSize() { |
358 | 360 | return 262144; |
359 | 361 | } |
360 | 362 |
|
361 | | -char Util::touchMemory(const char *memory, size_t size) { |
| 363 | +int Util::madviseLogged(void* addr, size_t len, int advice, const char* context) { |
362 | 364 | #ifdef HAVE_POSIX_MADVISE |
363 | | - if (size > 0 && posix_madvise ((void*)memory, size, POSIX_MADV_WILLNEED) != 0){ |
364 | | - Debug(Debug::ERROR) << "posix_madvise returned an error (touchMemory)\n"; |
| 365 | + if (len == 0) { |
| 366 | + return 0; |
| 367 | + } |
| 368 | + int rc = posix_madvise(addr, len, advice); |
| 369 | + if (rc == 0) { |
| 370 | + return 0; |
365 | 371 | } |
| 372 | + // SEQUENTIAL is a pure readahead hint; failure is never functional. |
| 373 | + // WILLNEED with EINVAL is also benign: unaligned tail on large-page |
| 374 | + // kernels (e.g. ARM64 64K pages) or advice unsupported for the VMA |
| 375 | + // type (HugeTLB, certain filesystems). Other WILLNEED errnos |
| 376 | + // (EIO/EBADF/ENOMEM) indicate real problems. |
| 377 | + const char* adviceName = (advice == POSIX_MADV_WILLNEED) ? "WILLNEED" |
| 378 | + : (advice == POSIX_MADV_SEQUENTIAL) ? "SEQUENTIAL" |
| 379 | + : (advice == POSIX_MADV_RANDOM) ? "RANDOM" |
| 380 | + : (advice == POSIX_MADV_NORMAL) ? "NORMAL" |
| 381 | + : (advice == POSIX_MADV_DONTNEED) ? "DONTNEED" |
| 382 | + : "?"; |
| 383 | + bool benign = (advice == POSIX_MADV_SEQUENTIAL) || (rc == EINVAL); |
| 384 | + Debug(benign ? Debug::WARNING : Debug::ERROR) |
| 385 | + << "posix_madvise(" << adviceName << ") failed for " << context |
| 386 | + << ": " << strerror(rc) << "\n"; |
| 387 | + return rc; |
| 388 | +#else |
| 389 | + (void)addr; (void)len; (void)advice; (void)context; |
| 390 | + return 0; |
366 | 391 | #endif |
| 392 | +} |
| 393 | + |
| 394 | +char Util::touchMemory(const char *memory, size_t size) { |
| 395 | + Util::madviseLogged((void*)memory, size, POSIX_MADV_WILLNEED, "touchMemory"); |
367 | 396 | if(size > Util::getTotalSystemMemory()){ |
368 | 397 | Debug(Debug::WARNING) << "Can not touch " << size << " into main memory\n"; |
369 | 398 | return 0; |
|
0 commit comments