Fail to query via move_pages()

前端 未结 1 674
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-16 01:04
#include 
#include 
#include 
#include 
#include 
#include 
#include &         


        
相关标签:
1条回答
  • 2021-01-16 01:15

    Your usage of shm_open and mmap probably will not get huge pages as you want.

    move_pages syscall (and libnuma wrapper) works on standard pages of 4096 bytes for x86_64.

    And you use move_pages in wrong way with incorrect 3rd argument "pages". It should be not pointer to memory; but pointer to array which itself will contain nPages pointers:

    http://man7.org/linux/man-pages/man2/move_pages.2.html

      long move_pages(int pid, unsigned long count, void **pages,
                       const int *nodes, int *status, int flags);
    
       pages is an array of pointers to the pages that should be moved.
       These are pointers that should be aligned to page boundaries.
       Addresses are specified as seen by the process specified by pid.
    

    Without correct pointers in the "pages' you will get -14 which is EFAULT according to errno 14 (from moreutils package).

    //https://stackoverflow.com/questions/54546367/fail-to-query-via-move-pages
    //g++ 54546367.move_pages.cc -o 54546367.move_pages -lnuma -lrt
    #include <cstdint>
    #include <iostream>
    #include <numaif.h>
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <unistd.h>
    #include <string.h>
    #include <limits>
    
    int main(int argc, char** argv) {
        const constexpr uint64_t size = 256lu * 1024;// * 1024;
        const constexpr uint32_t nPages = size / (4lu * 1024);
        void * pages[nPages];
        int32_t status[nPages];
        std::fill_n(status, nPages, std::numeric_limits<int32_t>::min());
    
    //  auto fd = shm_open("test_shm", O_RDWR|O_CREAT, 0666);
    //  void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
        std::cout << "Ptr is " << ptr << std::endl;
        if (ptr == MAP_FAILED) {
    //      if (fd > 0) close(fd);
            throw "failed to map hugepages";
        }
        memset(ptr, 0x41, nPages*4096);
        for(uint32_t i = 0; i<nPages; i++) {
            pages[i] = &((char*)ptr)[i*4096];
        }
    
        if (0 != move_pages(0, nPages, pages, nullptr, status, 0)) {
            std::cout << "failed to inquiry pages because " << strerror(errno) << std::endl;
        }
        else {
            for (uint32_t i = 0; i < nPages; i++) {
                std::cout << "page # " << i << " locates at numa node " << status[i] << std::endl;
            }
        }
        munmap(ptr, size);
    //  close(fd);
    }
    

    With NUMA machine it outputs same node when started as taskset -c 7 ./54546367.move_pages and interleaved (0 1 0 1) when numactl -i all ./54546367.move_pages.

    0 讨论(0)
提交回复
热议问题