Files
Sourabh U Betigeri fdc1660dfa SWDEV-565304 - Pass numa node to migrate pages correctly (#1729)
* SWDEV-565304 - Pass cpuId of the the thread currently running

* SWDEV-565304 - Numa id to be returned

* SWDEV-565304 - Numa id to be returned
2025-12-19 13:36:53 -08:00

366 wiersze
12 KiB
C++

/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
#ifndef OS_HPP_
#define OS_HPP_
#include "top.hpp"
#include "utils/util.hpp"
#include "utils/flags.hpp"
#include <vector>
#include <string>
namespace amd {
/*! \addtogroup Os Operating System Abstraction
*
* \copydoc amd::Os
*
* @{
*/
class Thread; // For Os::createOsThread()
class Os : AllStatic {
public:
// File Desc abstraction between OS
#if defined(_WIN32)
typedef void* FileDesc;
#else
typedef int FileDesc;
#endif
enum MemProt { MEM_PROT_NONE = 0, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
static FileDesc FDescInit() {
#if defined(__linux__)
return -1;
#else
return reinterpret_cast<void*>(-1);
#endif
}
// Returns unique resource indicator for a particular memory
static bool GetURIFromMemory(const void* image, size_t image_size, std::string& uri);
// Closes the file Handle
static bool CloseFileHandle(FileDesc fdesc);
// Given a valid file name, returns file descriptor and file size
static bool GetFileHandle(const char* fname, FileDesc* fd_ptr, size_t* sz_ptr);
// Returns the file name & file offset of mapped memory if the file is mapped.
static bool FindFileNameFromAddress(const void* image, std::string* fname_ptr,
size_t* foffset_ptr);
// Given a valid file descriptor returns mmaped memory for size and offset
static bool MemoryMapFileDesc(FileDesc fdesc, size_t fsize, size_t foffset,
const void** mmap_ptr);
// Given a valid file name, returns mmapped memory with the mapped size.
static bool MemoryMapFile(const char* fname, const void** mmap_ptr, size_t* mmap_size);
// Given a valid file name amd mapped size, returns ftruncated mmaped memory
static bool MemoryMapFileTruncated(const char* fname, const void** mmap_ptr, size_t mmap_size);
// Given a valid mmaped ptr with correct size, unmaps the ptr from memory
static bool MemoryUnmapFile(const void* mmap_ptr, size_t mmap_size);
// Given a valid filename create system memory that can be shared between processes
static void* CreateIpcMemory(const char* fname, size_t size, FileDesc* desc);
// Given a valid file descriptor open IPC memory
static void* OpenIpcMemory(const char* fname, const FileDesc desc, size_t size);
// Given a valid file descriptor close IPC memory
static void CloseIpcMemory(const FileDesc desc, const void* ptr, size_t size);
private:
static constexpr size_t FILE_PATH_MAX_LENGTH = 1024;
static size_t pageSize_; //!< The default os page size.
static int processorCount_; //!< The number of active processors.
private:
//! Load the shared library named by \a filename
static void* loadLibrary_(const char* filename);
public:
//! Initialize the Os package.
static bool init();
//! Tear down the Os package.
static void tearDown();
// Topology helper routines:
//
//! Return the number of active processors in the system.
inline static int processorCount();
#if defined(ATI_ARCH_X86)
//! Query the processor information about supported features and CPU type.
static void cpuid(int regs[4], int info);
//! Get value of extended control register
static uint64_t xgetbv(uint32_t which);
#endif // ATI_ARCH_X86
// Stack helper routines:
//
//! Return the current stack base and size information.
static void currentStackInfo(address* base, size_t* size);
//! Return the value of the current stack pointer.
static address currentStackPtr();
//! Touches all stack pages between [bottom,top[
static void touchStackPages(address bottom, address top);
// Thread routines:
//
//! Create a native thread and link it to the given OsThread.
static const void* createOsThread(Thread* osThread);
//! Set the currently running thread's name.
static void setCurrentThreadName(const char* name);
//! Check if the thread is alive
static bool isThreadAlive(const Thread& osThread);
//! Sleep for n milli-seconds.
static void sleep(long n);
//! Yield to threads of the same or lower priority
static void yield();
//! Execute a pause instruction (for spin loops).
static void spinPause();
// Memory routines:
//
//! Return the default os page size.
inline static size_t pageSize();
//! Return the amount of host total physical memory in bytes.
static uint64_t hostTotalPhysicalMemory();
//! Reserve a chunk of memory (priv | anon | noreserve).
static address reserveMemory(address start, size_t size, size_t alignment = 0,
MemProt prot = MEM_PROT_NONE);
//! Release a chunk of memory reserved with reserveMemory.
static bool releaseMemory(void* addr, size_t size);
//! Commit a chunk of memory previously reserved with reserveMemory.
static bool commitMemory(void* addr, size_t size, MemProt prot = MEM_PROT_NONE);
//! Uncommit a chunk of memory previously committed with commitMemory.
static bool uncommitMemory(void* addr, size_t size);
//! Set the page protections for the given memory region.
static bool protectMemory(void* addr, size_t size, MemProt prot);
//! Allocate an aligned chunk of memory.
static void* alignedMalloc(size_t size, size_t alignment);
//! Deallocate an aligned chunk of memory.
static void alignedFree(void* mem);
//! NUMA related settings
inline static void setPreferredNumaNode(uint32_t node);
// File/Path helper routines:
//
//! Return the shared library extension string.
static const char* libraryExtension();
//! Return the shared library prefix string.
static const char* libraryPrefix();
//! Return the object extension string.
static const char* objectExtension();
//! Return the file separator char.
static char fileSeparator();
//! Return the path separator char.
static char pathSeparator();
//! Return whether the path exists
static bool pathExists(const std::string& path);
//! Create the path if it does not exist
static bool createPath(const std::string& path);
//! Remove the path if it is empty
static bool removePath(const std::string& path);
//! Printf re-implementation (due to MS CRT problem)
static int printf(const char* fmt, ...);
/*! \brief Invokes the command processor for the command execution
*
* \result Returns the operation result
*/
static int systemCall(const std::string& command); //!< command for execution
/*! \brief Retrieves a string containing the value
* of the environment variable
*
* \result Returns the environment variable value
*/
static std::string getEnvironment(const std::string& name); //!< the environment variable's name
/*! \brief Retrieves the path of the directory designated for temporary
* files
*
* \result Returns the temporary path
*/
static std::string getTempPath();
/*! \brief Creates a name for a temporary file
*
* \result Returns the name of temporary file
*/
static std::string getTempFileName();
//! Deletes file
static int unlink(const std::string& path);
//! Removes the shared memory object name
static int shm_unlink(const std::string& path);
// Library routines:
//
typedef bool (*SymbolCallback)(std::string, const void*, void*);
//! checks if file descriptor is valid
static bool isValidFileDesc(const amd::Os::FileDesc& desc);
//! Load the shared library named by \a filename
static void* loadLibrary(const char* filename);
//! Unload the shared library.
static void unloadLibrary(void* handle);
//! Return the address of the function identified by \a name.
static void* getSymbol(void* handle, const char* name);
// Time routines:
//
//! Return the current system time counter in nanoseconds.
static uint64_t timeNanos();
//! Return the system timer's resolution in nanoseconds.
static uint64_t timerResolutionNanos();
//! Return the timeNanos starting point offset to Epoch.
static uint64_t offsetToEpochNanos();
// X86 Instructions helpers:
//
//! Skip an IDIV (F6/F7) instruction and return a pointer to the next insn.
static bool skipIDIV(address& insn);
// return gloabal memory size to be assigned to device info
static size_t getPhysicalMemSize();
//! get Application file name and path
static void getAppPathAndFileName(std::string& appName, std::string& appPathAndName);
//! Install SIGFPE handler for CPU device
static bool installSigfpeHandler();
//! Uninstall SIGFPE handler for CPU device
static void uninstallSigfpeHandler();
//! Return the current process id
static int getProcessId();
//! Prints the location of the currently loaded library (shared object or DLL)
static void PrintLibraryLocation();
//! Checks if a core dump must be generated (rocgdb detection). Returns false in Windows
static bool DumpCoreFile();
//! Demangle a C++ name. The function will return the same name if couldn't demangle
static void CxaDemangle(const std::string& name, std::string* demangle);
};
/*@}*/
inline size_t Os::pageSize() {
assert(pageSize_ != 0 && "runtime is not initialized");
return pageSize_;
}
inline int Os::processorCount() { return processorCount_; }
/* Mini numa interface instead of numa lib apis */
namespace numa {
static constexpr uint32_t kBitsPerUInt64 = 8 * sizeof(uint64_t);
//! Get the NUMA node ID of the current thread
uint32_t getCurrentNumaNode();
/*! \brief Manage Numa policy.
*
* \note Works in Linux only, dummy in Windows.
*/
class NumaPolicy final {
public:
enum class Policy {
kDefault = 0,
kPrefered = 1,
kBind = 2,
kInterleave = 3,
kLocal = 4,
kPreferedMany = 5,
kWeightedInterleave = 6,
kMax = 7
};
NumaPolicy(uint32_t numa_node_count);
//! Query memory policy and node bitmask from Linux kernel
bool GetMemPolicy();
//! Check whether node_index is in bitmask for kPrefered and kBind modes
bool IsPolicySetAt(uint32_t node_index) const;
//! Return the queried policy
Policy GetPolicy() const { return policy_; }
private:
std::vector<uint64_t> node_map_{}; //!< Node bitmask for kPrefered and kBind modes
Policy policy_{Policy::kDefault}; //!< The policy
};
/*! \brief Manage Numa node.
*
* \note Works in Linux and Windows.
*/
class NumaNode final {
public:
NumaNode (uint32_t node_index): node_index_(node_index) {}
~NumaNode();
//! Apply the CPU affinity mask of the node onto the current thread
bool SchedSetAffinity();
private:
uint32_t node_index_; //! Index of the Numa node
void* affinity_ = nullptr; //!< Affinity mask of logical CPUs on this node
uint32_t size_ = 0; //!< Number of valid bits
//! Guery the affinity mask of logical CPUs on this node
bool GetAffinity();
};
} // namespace numa
inline void Os::setPreferredNumaNode(uint32_t node) {
if (AMD_CPU_AFFINITY) {
numa::NumaNode numaNode(node);
numaNode.SchedSetAffinity();
}
}
} // namespace amd
#endif /*OS_HPP_*/