Каковы требования aligment для sys_brk

Я использую sys_brk syscall для динамического выделения памяти в куче. Я заметил, что при получении текущего местоположения разрыва я обычно получаю значение, подобное этому:

mov rax, 0x0C
mov rdi, 0x00
syscall

результаты в

rax   0x401000

Значение обычно 512 байтов выровнено. Итак, я хотел бы спросить, есть ли какие-то требования по выравниванию по значению разрыва? Или мы можем выровнять это так, как мы хотим?

1 ответ

Ядро отслеживает разрыв с байтовой гранулярностью. Но не используйте его напрямую для небольших распределений, если вам небезразлична производительность.


В комментариях обсуждалось ядро, округляющее разрыв до границы страницы, но это не так. Реализацияsys_brkиспользует это (с добавлением моих комментариев, так что это имеет смысл вне контекста)

newbrk = PAGE_ALIGN(brk);     // the syscall arg
oldbrk = PAGE_ALIGN(mm->brk); // the current break
if (oldbrk == newbrk)
    goto set_brk;      // no need to map / unmap any pages, just update mm->brk

Это проверяет, переместился ли перерыв на другую страницу, но в конечном итогеmm->brk = brk;устанавливает текущий разрыв в точный аргумент, переданный системному вызову (если он действителен). Если текущий разрыв всегда выровнен по странице, ядру не понадобитсяPAGE_ALIGN()в теме.


Конечно, защита памяти имеет как минимум гранулярность страницы (и, возможно, огромную страницу, если ядро ​​решает использовать анонимные огромные страницы для этого отображения). Таким образом, вы можете получить доступ к памяти до конца страницы, содержащей разрыв, без ошибок. Вот почему код ядра просто проверяет, переместился ли перенос на другую страницу, чтобы пропустить логику map / unmap, но все же обновляет фактический brk.

AFAIK, ничто никогда не будет использовать эту отображаемую память над разрывом как пустое пространство, поэтому она не похожа на память под указателем стека, которая может быть асинхронно захвачена.

brkэто просто простая система управления памятью, встроенная в ядро. Системные вызовы стоят дорого, поэтому, если вы заботитесь о производительности, вы должны отслеживать вещи в пользовательском пространстве и делать системные вызовы вообще, когда вам нужна новая страница.С помощью sys_brkнепосредственно для крошечных распределений ужасно для производительности, особенно в ядрах с включенным смягчением Meltdown + Spectre (что делает системные вызовы намного более дорогими, например, десятки тысяч тактов + TLB и аннулирование предсказания ветвления вместо сотен тактов).

Другие вопросы по тегам