Бесплатные `mmap()-ed` частные огромные страницы

У меня есть следующий код:

mmap(NULL, 2048, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB, -1, 0);

Интересно, как освободить огромные страницы после аварийного выхода моего приложения (например, сбоя).

Перезагрузка машины освободит все огромные страницы. Но это немного мешает рабочему серверу. Поэтому я ищу способ не нарушать существующие процессы.

Заранее спасибо!


person HCSF    schedule 29.08.2019    source источник
comment
Я почти уверен, что нечего убирать, если приложение уже разбилось :)   -  person tangrs    schedule 29.08.2019
comment
@tangrs Я заметил, что количество бесплатных страниц падает (numastat -vm).   -  person HCSF    schedule 29.08.2019
comment
Linux будет иметь сложные алгоритмы управления памятью. Я сомневаюсь, что вывод numastat будет иметь прямое отношение к сбою или запуску ваших процессов. Linux Ate My RAM не имеет прямого отношения к этому, но помогает проиллюстрировать суть (в частности, различие между < i>бесплатно и доступно).   -  person tangrs    schedule 29.08.2019
comment
@tangrs правильно, счетчик может быть неправильным, но когда мое приложение снова попытается выполнить mmap. Mmap жалуется, что больше нет ресурсов   -  person HCSF    schedule 29.08.2019
comment
@HCFS Может быть, просто попробуйте удалить файлы в точке монтирования огромных страниц. Это не решение, а грязный хак. Это сработало для меня, но может не сработать для вас, особенно если несколько приложений совместно используют tlbpages. ммв.   -  person Unmanned Player    schedule 29.08.2019
comment
@UnmannedPlayer В итоге я перезагрузил машину, что дало тот же эффект, что и вы предложили. Поэтому я ищу решение без перезагрузки и не затрагивая существующие процессы. Спасибо   -  person HCSF    schedule 29.08.2019
comment
@HCSF Извините за это. Даже дубликат с принятым ответом, кажется, предлагает этот взлом. По-видимому, файлы tlb удаляются, когда последний FD к нему закрывается. Я не буду ссылаться на этот дубликат, потому что парни здесь быстро отметят дубликат без надлежащего рассуждения/изучения альтернатив/объяснения почему.   -  person Unmanned Player    schedule 29.08.2019
comment
@UnmannedPlayer, не беспокойся. Я обновлю свой пост, чтобы уточнить, что я ищу. Спасибо :)   -  person HCSF    schedule 29.08.2019


Ответы (2)


Когда программа завершается, сопоставления автоматически сбрасываются.

Ниже приведено утверждение из книги «Интерфейс программирования Linux».

Все сопоставления процесса автоматически удаляются, когда он завершает работу или выполняет функцию exec().

person Pavan Chandaka    schedule 29.08.2019
comment
Учебники могут быть устаревшими. Может быть, показать ссылку на справочные страницы или что-то, что достаточно актуально? - person Unmanned Player; 29.08.2019
comment
Manpage действительно так говорит The region is also automatically unmapped when the process is terminated. On the other hand, closing the file descriptor does not unmap the region. Хотя я знаю, что это неправда, потому что я также имел дело с обычным SHM в /dev/shm, который не очищался месяцами... - person HCSF; 29.08.2019

Это возможный путь решения проблемы, но не единственный.

Вы открываете mmap с FD, установленным на -1. Вместо этого попробуйте с таким файлом:

char page_file[256];
static unsigned page_counter;
int fd;

/* page_counter must be counted up and must be unique. */
snprintf(page_file, sizeof(page_file), "/var/huge/my_page_%u", page_counter);

fd = open(page_file, O_CREAT | O_RDWR, 0755);
if (fd == -1) {
    /* Handle error. */
}

addr = mmap(NULL, 2048, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB, fd, 0);

Затем процедура инициализации вашего приложения может искать файлы с префиксом /var/huge/my_page_* или любым другим, который вы выбрали для своего приложения, и удалять эти файлы перед вызовом mmap. Таким образом, вы не потеряете место.

Теперь о предостережениях.

  1. Если эта страница используется другими приложениями, и ваше приложение возвращается после сбоя, все может стать фатальным. Поэтому используйте это решение с осторожностью. Я предложил это, потому что, насколько я понимаю, вы не делитесь своими страницами с другими приложениями.

  2. После того, как вы удалите файлы, другое приложение mmapс огромными страницами в течение этого времени, прежде чем вы сможете их выделить, вы не сможете использовать огромные страницы.

person Unmanned Player    schedule 29.08.2019
comment
$ ll /var/huge/ возвращает ls: cannot access /var/huge/: No such file or directory. Вероятно, CentOS 7 отличается. И я думаю, что mmap() будет игнорировать или отклонять файловый дескриптор != -1, когда указано MAP_PRIVATE, потому что регион должен быть частным, и содержимое не будет записываться обратно на диск. - person HCSF; 29.08.2019
comment
@HCSF Это ваш выбор, где вы монтируете огромные страницы (как root). Люди обычно монтируют его на /mnt/huge или еще куда-нибудь. Подробности смотрите в своем /proc/mounts. Я обычно делаю это в /var/huge. Что касается MAP_PRIVATE, я не думаю, что его отклонят. - person Unmanned Player; 29.08.2019