Jump to content

    
novartis

Выделение Hugepage 1G в кернел модуле

Recommended Posts

На машине установлен CentOS (версия ядра 3.10.0-1127.el7.x86_64). Есть необходимость выделить огромные физически непрерывные куски памяти (несколько буферов по гигабайту к примеру).

В user space программе я выделил 8 hugepage 1G с помощью mmap(), код подсмотрел здесь https://github.com/max0x7ba/atomic_queue/tree/master/src

До запуска программы /proc/meminfo показывает, что доступно 13 Hugepage страниц, свободно 13 Hugepage страниц. При работающей программе количество свободных страниц = 5. Записываю, читаю данные в этих страницах. Ну как бы в user space задача решена.

Но руководитель проекта говорит надо в кернел модуле восемь Hugepage 1G страниц выделить, а юзерские программы уже будут обращаться к этому кернел модулю и мапить себе эти буферы.

Перерыл интернет, не могу найти как выделить Hugepage 1G в кернел модуле. Пните в нужную сторону.

 

 

Share this post


Link to post
Share on other sites
1 hour ago, gosha-z said:

Для начала попробуйте сказать ядру, чтобы распределил вам 8G CMA блок, а потом уже как обычно, dma_alloc_coherent

dma_alloc_coherent вернёт указатель на непрерывную физическую память, состоящую из восьми hugepage?

Share this post


Link to post
Share on other sites

Вернет указатеь на непрерывный блок запрошенного размера или обломает. Но вот как поведет себя ядро 3.10 - не возмусь сказать, я экспериментирую на 4.9

Share this post


Link to post
Share on other sites

С CMA и dma_alloc_coherent я разобрался 4 года назад (была OpenSuse 13.2, версия ядра 3.16), и не проблема сделать это и сейчас. Но нужно задействовать именно hugepages. Это повысит эффективность работы с памятью (будет меньше обращений к TLB).

Share this post


Link to post
Share on other sites
18 hours ago, novartis said:

Перерыл интернет, не могу найти как выделить Hugepage 1G в кернел модуле. Пните в нужную сторону.

Да вроде есть ответы

https://stackoverflow.com/questions/46212872/how-to-allocate-huge-pages-in-linux-kernel

Quote

I did a test again, with kmalloc(0x200000, GFP_KERNEL | __GFP_COMP), and the kernel returned me a 2MB huge page, this is what I want

насколько это работает неизвестно

Share this post


Link to post
Share on other sites
41 minutes ago, sasamy said:
u32 skp = 0x10000000;
u32* kp0 = (u32*)kmalloc(skp, GFP_KERNEL | __GFP_COMP);
u32* kp1 = (u32*)kmalloc(skp, GFP_KERNEL | __GFP_COMP);
printk(KERN_INFO "skp = %d (0x%016llx)\n", skp, skp);
printk(KERN_INFO "kp0 = %d (0x%016llx)\n", kp0, kp0);
printk(KERN_INFO "kp1 = %d (0x%016llx)\n", kp1, kp1);

u32 svp = 0x10000000;
u32* vp0 = (u32*)vmalloc(svp);
u32* vp1 = (u32*)vmalloc(svp);
printk(KERN_INFO "svp = %d (0x%016llx)\n", svp, svp);
printk(KERN_INFO "vp0 = %d (0x%016llx)\n", vp0, vp0);
printk(KERN_INFO "vp1 = %d (0x%016llx)\n", vp1, vp1);

Ага, тоже нашел этот ответ, попробовал, выдает следующее:

[ 1266.791973] skp = 268435456 (0x0000000010000000)
[ 1266.791975] kp0 = 0 (0x0000000000000000)
[ 1266.791976] kp1 = 0 (0x0000000000000000)
[ 1266.791976] svp = 268435456 (0x0000000010000000)
[ 1266.798007] vp0 = 1073762304 (0xffffa4f540005000)
[ 1266.830376] vp1 = 1342201856 (0xffffa4f550006000)

kmalloc() вернул нул, не смог выделить 256 МБ буферы. vmalloc() смог выделить. Задействованы ли при этом hugepage в 2 МБ не знаю. Hugepage 1G не задействованы, по-прежнему свободных 13 штук.

Если уменьшить размер запрашиваемого буфера, то kmalloc() и vmalloc() успешно возвращают указатели на память.

Если задать размер в гигабайт (0x40000000), то система падает, уходит в ребут (из-за vmalloc(0x40000000) )

Ну продолжаю дальше искать решение

 

Share this post


Link to post
Share on other sites
6 minutes ago, novartis said:

kmalloc() вернул нул, не смог выделить 256 МБ буферы

примерно это и ожидалось от kmalloc. Если буферы в ядре не нужны а драйвер использует их для DMA устройства то тут и аллокатор в принципе не нужен - надо как-то зарезервировать выровненный кусок памяти, а в юзерспейсе есть флаг у mmap чтобы при отображении физической памяти в адресном пространстве CPU использовались большие страницы. Для конкретного процессора на ARM когда известна карта памяти это без проблем можно сделать через параметр ядра mem = , как на x86 это оформить не знаю

Share this post


Link to post
Share on other sites
42 минуты назад, novartis сказал:

Если задать размер в гигабайт (0x40000000), то система падает, уходит в ребут (из-за vmalloc(0x40000000) )

Ну продолжаю дальше искать решение

в официальной доке https://www.kernel.org/doc/html/latest/admin-guide/mm/hugetlbpage.html

есть такой момент "x86 CPUs normally support 4K and 2M (1G if architecturally supported) page sizes", может поискать еще х86 машинку с другой конфигурацией, чисто для проверки

и еще, latest - это 5.9, а у вас мохнатое 3.10

Share this post


Link to post
Share on other sites
10 minutes ago, Jury093 said:

есть такой момент "x86 CPUs normally support 4K and 2M (1G if architecturally supported) page sizes", может поискать еще х86 машинку с другой конфигурацией, чисто для проверки

так в user space через mmap() я hugapage 1G выделил.

Вообще первым шагом добавил в grub строку "hugepagesz=1g hugepages=64 default_hugepagesz=1g".

После этого dmegs стал сообщать:

HugeTLB: allocating 64 of page size 1 GB failed.  Only allocated 13 hugepages.

И в /proc/meminfo тоже написано, что HugePages есть:

HugePages_Total:      13
HugePages_Free:       13
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:    1048576 kB
DirectMap4k:      125296 kB
DirectMap2M:     2881536 kB
DirectMap1G:    13631488 kB

Когда запускаю свою user программу, которая выделяет восемь hugapage 1G (физический адрес каждой страницы передается в fpga и fpga начинает по pcie последовательно записывать эти страницы данными), то в /proc/meminfo уже написано:

HugePages_Total:      13
HugePages_Free:        5
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:    1048576 kB
DirectMap4k:      125296 kB
DirectMap2M:     2881536 kB
DirectMap1G:    13631488 kB

Раз в user space через mmap() я hugapage 1G выделил, то должна же быть возможность сделать тоже самое в кернел модуле...

Share this post


Link to post
Share on other sites
15 minutes ago, novartis said:

Раз в user space через mmap() я hugapage 1G выделил

mmap память не выделяет, она её отображает в адреснои пространстве CPU. Примерный аналог для mmap в ядре ioremap

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.