novartis 0 17 сентября, 2020 Опубликовано 17 сентября, 2020 · Жалоба На машине установлен 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 в кернел модуле. Пните в нужную сторону. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 17 сентября, 2020 Опубликовано 17 сентября, 2020 · Жалоба Для начала попробуйте сказать ядру, чтобы распределил вам 8G CMA блок, а потом уже как обычно, dma_alloc_coherent Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novartis 0 17 сентября, 2020 Опубликовано 17 сентября, 2020 · Жалоба 1 hour ago, gosha-z said: Для начала попробуйте сказать ядру, чтобы распределил вам 8G CMA блок, а потом уже как обычно, dma_alloc_coherent dma_alloc_coherent вернёт указатель на непрерывную физическую память, состоящую из восьми hugepage? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 17 сентября, 2020 Опубликовано 17 сентября, 2020 · Жалоба Вернет указатеь на непрерывный блок запрошенного размера или обломает. Но вот как поведет себя ядро 3.10 - не возмусь сказать, я экспериментирую на 4.9 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novartis 0 17 сентября, 2020 Опубликовано 17 сентября, 2020 · Жалоба С CMA и dma_alloc_coherent я разобрался 4 года назад (была OpenSuse 13.2, версия ядра 3.16), и не проблема сделать это и сейчас. Но нужно задействовать именно hugepages. Это повысит эффективность работы с памятью (будет меньше обращений к TLB). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 9 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 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 насколько это работает неизвестно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novartis 0 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 41 minutes ago, sasamy said: Да вроде есть ответы https://stackoverflow.com/questions/46212872/how-to-allocate-huge-pages-in-linux-kernel 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) ) Ну продолжаю дальше искать решение Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 9 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 6 minutes ago, novartis said: kmalloc() вернул нул, не смог выделить 256 МБ буферы примерно это и ожидалось от kmalloc. Если буферы в ядре не нужны а драйвер использует их для DMA устройства то тут и аллокатор в принципе не нужен - надо как-то зарезервировать выровненный кусок памяти, а в юзерспейсе есть флаг у mmap чтобы при отображении физической памяти в адресном пространстве CPU использовались большие страницы. Для конкретного процессора на ARM когда известна карта памяти это без проблем можно сделать через параметр ядра mem = , как на x86 это оформить не знаю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jury093 2 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novartis 0 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 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 выделил, то должна же быть возможность сделать тоже самое в кернел модуле... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 9 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба 15 minutes ago, novartis said: Раз в user space через mmap() я hugapage 1G выделил mmap память не выделяет, она её отображает в адреснои пространстве CPU. Примерный аналог для mmap в ядре ioremap Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться