在内核驱动程序

时间:2017-11-17 11:24:20

标签: linux-kernel huge-pages

我在下面的两个链接中指的是在我的linux驱动程序中使用大页面:

Sequential access to hugepages in kernel driver
http://nuncaalaprimera.com/2014/using-hugepage-backed-buffers-in-linux-kernel-driver

以下是我的代码:

#define PAGE_SHIFT_2M   21
pages = vmalloc(nr_pages * sizeof(struct page*));

down_read(&current->mm->mmap_sem);
get_nr_pages = get_user_pages(current, current->mm, buffer_start, nr_pages,
    1 /* Write enable */, 0 /* Force */, pages, NULL);
up_read(&current->mm->mmap_sem);

nid = page_to_nid(pages[0]);    // Remap on the same NUMA node.
remapped_addr = vm_map_ram(pages, nr_pages, nid, PAGE_KERNEL);

printf("page pfn [0]=%lX, [1]=0x%lX, [2]=0x%lX\n", 
    page_to_pfn(pages[0]), 
    page_to_pfn(pages[1]),
    page_to_pfn(pages[2]));
printf("page physical [0]=%lX, [1]=0x%lX, [2]=0x%lX\n", 
    page_to_pfn(pages[0])<<PAGE_SHIFT_2M, 
    page_to_pfn(pages[1])<<PAGE_SHIFT_2M,
    page_to_pfn(pages[2])<<PAGE_SHIFT_2M);
printf("page logical addr [0]=%p, [1]=%p, [2]=%p\n", 
    __va(page_to_pfn(pages[0])<<PAGE_SHIFT_2M), 
    __va(page_to_pfn(pages[1])<<PAGE_SHIFT_2M),
    __va(page_to_pfn(pages[2])<<PAGE_SHIFT_2M));
printf("page_address [0]=%p, [1]=%p, [2]=%p\n", 
    page_address(pages[0]), 
    page_address(pages[1]),
    page_address(pages[2]));

日志打印:

页面pfn [0] = 154A00,[1] = 0x154A01,[2] = 0x154A02
page physical [0] = 2A940000000,[1] = 0x2A940200000,[2] = 0x2A940400000
page logical addr [0] = ffff8aa940000000,[1] = ffff8aa940200000,[2] = ffff8aa940400000
page_address [0] = ffff880154a00000,[1] = ffff880154a01000,[2] = ffff880154a02000

我有几个问题:
1)我想知道vm_map_ram()是否适用于大页面。从内核源代码中,我可以看到vm_map_ram()使用PAGE_SIZE和PAGE_SHIFT,其值应为默认的4KB页面大小。 在我的情况下,在写入从vm_map_ram()返回的虚拟地址后,我遇到了&#34; BUG:无法在XXXX处理内核分页请求&#34;问题。
2)page_address两个页面的返回值是0x1000(4KB)间隙,而不是2MB间隙。那是为什么?
3)我使用&#34; __ va(page_to_pfn(pages [0])&lt;

提前致谢!

0 个答案:

没有答案