Перейти к содержанию
    

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

На машине установлен 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 в кернел модуле. Пните в нужную сторону.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, gosha-z said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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) )

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, novartis said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 выделил, то должна же быть возможность сделать тоже самое в кернел модуле...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, novartis said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...