shmget не работает с ENOMEM, хотя доступно достаточно страниц

Мы получаем странное поведение при попытке выделить приблизительно 10 МБ блок памяти из огромных страниц. Система SL6.4 64-разрядная, новейший процессор Intel, 64 ГБ оперативной памяти.

Изначально мы выделили 20 огромных страниц, которых должно быть достаточно.

$ cat /proc/meminfo | grep Huge
AnonHugePages:         0 kB
HugePages_Total:      20
HugePages_Free:       20
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Другие огромные настройки страницы:

/proc/sys/kernel/shmall = 4294967296
/proc/sys/kernel/shmmax = 68719476736
/proc/sys/kernel/shmmni = 4096
/proc/sys/kernel/shm_rmid_forced = 0

shmget не работает с ENOMEM. Единственное объяснение, которое я могу найти для этого, находится на странице руководства, которая гласит: «Не может быть выделено памяти для служебных данных сегмента». но я не смог обнаружить, что такое «накладные расходы сегмента».

На другом сервере с таким же количеством настроенных страниц shmget возвращается успешно.

На проблемном сервере мы увеличили количество огромных страниц до 100. Выделение выполняется успешно, но также выделяется 64 огромных страницы по 2 МБ:

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x0091efab 10223638   rsprod     600        2097152    1
0x0092efab 10256407   rsprod     600        2097152    1
0x0093efab 10289176   rsprod     600        2097152    1
0x0094efab 10321945   rsprod     600        2097152    1
0x0095efab 10354714   rsprod     600        2097152    1
0x0096efab 10387483   rsprod     600        2097152    1
...
0x00cdefab 12189778   rsprod     600        2097152    1
0x00ceefab 12222547   rsprod     600        2097152    1
0x00cfefab 12255316   rsprod     600        2097152    1
0x00d0efab 12288085   rsprod     600        2097152    1
0x00000000 12320854   rsprod     600        10485760   1

Код, вызывающий shmget, находится ниже. Это вызывается только один раз в приложении.
uint64_t GetHugePageSize ()
{
FILE * meminfo = fopen («/ proc / meminfo», «r»);
if (meminfo == NULL) {
вернуть 0;
}

    char line[256];
while(fgets(line, sizeof(line), meminfo)) {
uint64_t zHugePageSize = 0;
if(sscanf(line, "Hugepagesize: %lu kB", &zHugePageSize) == 1) {
fclose(meminfo);
return zHugePageSize*1024;
}
}

fclose(meminfo);
return 0;
}

char* HugeTableNew(size_t aSize, int& aSharedMemID)
{
static const uint64_t sHugePageSize = GetHugePageSize();

uint64_t zSize = aSize;
// round up to next page size, otherwise shmat fails with EINVAL (22)
const uint64_t HUGE_PAGE_MASK = sHugePageSize-1;
if(aSize & HUGE_PAGE_MASK) {
zSize = (aSize&~HUGE_PAGE_MASK) + sHugePageSize;
}

aSharedMemID = shmget(IPC_PRIVATE, zSize, IPC_CREAT|SHM_HUGETLB|SHM_R|SHM_W);
if(aSharedMemID < 0) {
perror("shmget");
return nullptr;
}
...

Кто-нибудь знает:

  • Что приводит к сбою размещения при наличии достаточного количества свободных огромных страниц?
  • Что вызывает выделение дополнительных 2 МБ страниц?
  • Что такое «накладные расходы сегмента»?

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]