Каковы требования 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 и аннулирование предсказания ветвления вместо сотен тактов).