Skip to content

Commit 4fe20e6

Browse files
Merge pull request #1109 from KimYannn/fix/posix-madvise-warning-severity
Centralize posix_madvise wrapper with errno-aware severity
2 parents 238da2c + 94fd7eb commit 4fe20e6

6 files changed

Lines changed: 62 additions & 23 deletions

File tree

src/commons/DBReader.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,14 +1126,10 @@ int DBReader<T>::isCompressed(int dbtype) {
11261126

11271127
template<typename T>
11281128
void DBReader<T>::setSequentialAdvice() {
1129-
#ifdef HAVE_POSIX_MADVISE
11301129
for(size_t i = 0; i < dataFileCnt; i++){
11311130
size_t dataSize = dataSizeOffset[i+1] - dataSizeOffset[i];
1132-
if (dataSize > 0 && posix_madvise (dataFiles[i], dataSize, POSIX_MADV_SEQUENTIAL) != 0){
1133-
Debug(Debug::ERROR) << "posix_madvise returned an error " << dataFileName << "\n";
1134-
}
1131+
Util::madviseLogged(dataFiles[i], dataSize, POSIX_MADV_SEQUENTIAL, dataFileName);
11351132
}
1136-
#endif
11371133
}
11381134

11391135
template<typename T>

src/commons/Util.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "MemoryMapped.h"
1919
#include "MemoryTracker.h"
2020
#include <algorithm>
21+
#include <cerrno>
22+
#include <cstring>
2123
#include <sys/mman.h>
2224
#include <fstream> // std::ifstream
2325

@@ -358,12 +360,39 @@ uint64_t Util::getL2CacheSize() {
358360
return 262144;
359361
}
360362

361-
char Util::touchMemory(const char *memory, size_t size) {
363+
int Util::madviseLogged(void* addr, size_t len, int advice, const char* context) {
362364
#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;
365371
}
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;
366391
#endif
392+
}
393+
394+
char Util::touchMemory(const char *memory, size_t size) {
395+
Util::madviseLogged((void*)memory, size, POSIX_MADV_WILLNEED, "touchMemory");
367396
if(size > Util::getTotalSystemMemory()){
368397
Debug(Debug::WARNING) << "Can not touch " << size << " into main memory\n";
369398
return 0;

src/commons/Util.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,28 @@ class Util {
9898

9999
static char touchMemory(const char* memory, size_t size);
100100

101+
// Wrap posix_madvise with errno-aware logging. Returns posix_madvise's
102+
// return value (errno-valued, 0 on success). Severity is WARNING for
103+
// benign cases (advisory SEQUENTIAL hint failures, or EINVAL on
104+
// WILLNEED — typically tail-page alignment on large-page kernels or
105+
// VMA types that reject the advice) and ERROR for real failures
106+
// (EIO/EBADF/ENOMEM on WILLNEED). A no-op when len == 0 or
107+
// HAVE_POSIX_MADVISE is undefined. `context` annotates the log line.
108+
//
109+
// Fallback POSIX_MADV_* constants so call sites compile even on
110+
// platforms without posix_madvise; madviseLogged is a no-op there,
111+
// so the literal values are unused.
112+
#ifndef HAVE_POSIX_MADVISE
113+
# ifndef POSIX_MADV_NORMAL
114+
# define POSIX_MADV_NORMAL 0
115+
# define POSIX_MADV_RANDOM 1
116+
# define POSIX_MADV_SEQUENTIAL 2
117+
# define POSIX_MADV_WILLNEED 3
118+
# define POSIX_MADV_DONTNEED 4
119+
# endif
120+
#endif
121+
static int madviseLogged(void* addr, size_t len, int advice, const char* context);
122+
101123
static size_t countLines(const char *data, size_t length);
102124

103125
static size_t ompCountLines(const char *data, size_t length, unsigned int threads);

src/linclust/KmerIndex.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// storage for k-mers
66
#include "IndexTypes.h"
77
#include "MathUtil.h"
8+
#include "Util.h"
89
#include <string>
910
#include <algorithm>
1011
#include <fcntl.h>
@@ -183,11 +184,8 @@ class KmerIndex{
183184
this->entryCount = entryCount;
184185
this->indexGridSize = MathUtil::ceilIntDivision( MathUtil::ipow<size_t>(alphabetSize, kmerSize), gridResolution );
185186
this->entryOffsets = (size_t *) entriesOffetData;
186-
#if HAVE_POSIX_MADVISE
187-
if (entryCount > 0 && posix_madvise (entriesData, entryCount* sizeof(KmerEntryRelative), POSIX_MADV_SEQUENTIAL) != 0){
188-
Debug(Debug::ERROR) << "KmerIndex posix_madvise returned an error\n";
189-
}
190-
#endif
187+
Util::madviseLogged(entriesData, entryCount * sizeof(KmerEntryRelative),
188+
POSIX_MADV_SEQUENTIAL, "KmerIndex");
191189

192190
this->prevKmerStartRange = 0;
193191
this->iteratorPos = -1;

src/linclust/kmermatcher.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,11 +1669,8 @@ void mergeKmerFilesAndOutput(DBWriter &dbw,
16691669

16701670
if (fstat(fileno(files[file]), &sb) == 0 && sb.st_size > 0) {
16711671
entries[file] = (T *)FileUtil::mmapFile(files[file], &dataSize);
1672-
#if HAVE_POSIX_MADVISE
1673-
if (posix_madvise(entries[file], dataSize, POSIX_MADV_SEQUENTIAL) != 0) {
1674-
Debug(Debug::ERROR) << "posix_madvise returned an error for file " << threadedFiles[threadIdx][file] << "\n";
1675-
}
1676-
#endif
1672+
Util::madviseLogged(entries[file], dataSize, POSIX_MADV_SEQUENTIAL,
1673+
threadedFiles[threadIdx][file].c_str());
16771674
} else {
16781675
entries[file] = nullptr;
16791676
dataSize = 0;

src/prefiltering/Prefiltering.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,8 @@ void Prefiltering::mergeTargetSplits(const std::string &outDB, const std::string
453453
for (size_t i = 0; i < splits; ++i) {
454454
files[i] = FileUtil::openFileOrDie(fileNames[i].first.c_str(), "r", true);
455455
dataFile[i] = static_cast<char*>(FileUtil::mmapFile(files[i], &dataFileSize[i]));
456-
#ifdef HAVE_POSIX_MADVISE
457-
if (dataFileSize[i] > 0 && posix_madvise (dataFile[i], dataFileSize[i], POSIX_MADV_SEQUENTIAL) != 0){
458-
Debug(Debug::ERROR) << "posix_madvise returned an error " << fileNames[i].first << "\n";
459-
}
460-
#endif
456+
Util::madviseLogged(dataFile[i], dataFileSize[i], POSIX_MADV_SEQUENTIAL,
457+
fileNames[i].first.c_str());
461458

462459
}
463460
Debug(Debug::INFO) << "Preparing offsets for merging: " << timer.lap() << "\n";

0 commit comments

Comments
 (0)