Вызов mmap работает в одной системе, но не работает с сообщением «Невозможно выделить память» в другой. Оба работают с одним и тем же изображением linux с большим количеством памяти - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь запустить код, который я не писал, для которого требуется большой кусок (~ 1 ГБ) непрерывной памяти. Я пробую на двух разных конфигурациях оборудования, но с одним и тем же двоичным кодом linux. Он работает в одной системе, но выдает ошибку «Невозможно выделить память» в другой.

uint64_t alloc_flags = MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS | MAP_HUGETLB | (30 << MAP_HUGE_SHIFT) 

mem->buffer = (char *)mmap(NULL, mem->size, PROT_READ | PROT_WRITE,
                  alloc_flags, mem->fd, 0);
       if (mem->buffer == MAP_FAILED) {
       perror("[ERROR] - mmap() failed with");
       exit(1);
   }

Есть идеи, в чем может быть проблема или на что обратить внимание?

/ proc / meminfo выглядит примерно одинаково в обеих системах.

Я безуспешно пытался: echo 20 > /proc/sys/vm/nr_hugepages

РЕДАКТИРОВАТЬ: в обеих системах / sys / kernel / mm / hugepages / есть: "hugepages-1048576kB hugepages -2048kB "

.. / sys / kernel / mm / hugepages / hugepages-1048576kB / free_hugepages показывает 1 в успешной системе и 0 в неисправной системе!

Ответы [ 2 ]

3 голосов
/ 29 мая 2020

Недостаточно иметь много памяти. Аппаратное обеспечение требует, чтобы каждая страница была непрерывным диапазоном физической памяти, выровненной по размеру страницы.

Если ваша системная память фрагментирована и не имеет достаточного количества смежных областей, распределение не удастся.

Вы можете спросить ядро, чтобы зарезервировать некоторый объем памяти во время загрузки * от до параметры ядра :

hugepagesz=1G hugepages=2

Это должно выделить 2 страницы по 1 ГБ. Обратите внимание, что на вашем ЦП должен быть установлен флаг pdpe1gb:

grep pdpe1gb /proc/cpuinfo

Это не должно быть проблемой, поскольку все ЦП начиная с Westmere (выпущенного в 2010 году).

2 голосов
/ 28 мая 2020

При чтении из mmap (2) кажется, что MAP_HUGE_1GB (то есть ваш (30 << MAP_HUGE_SHIFT) флаг) не поддерживается везде: </p>

Диапазон огромных размеров страниц, поддерживаемых систему можно обнаружить, перечислив подкаталоги в / sys / kernel / mm / hugepages

Какой у вас ls /sys/kernel/mm/hugepages/ вывод?

...