Tag: 巨页

在内核驱动程序中顺序访问大页面

我正在使用一个使用由大页面支持的缓冲区的驱动程序,我发现大页面的后续性存在一些问题。 在用户空间中,程序使用mmap系统调用分配由largepages支持的大缓冲区。 然后通过ioctl调用将缓冲区传送给驱动程序。 驱动程序使用get_user_pages函数来获取该缓冲区的内存地址。 这适用于1 GB的缓冲区大小(1个巨页)。 get_user_pages返回了很多页面( HUGE_PAGE_SIZE / PAGE_SIZE ),但它们都是HUGE_PAGE_SIZE / PAGE_SIZE ,所以没有问题。 我只是使用page_address获取第一页的地址并使用它。 当另一个程序在char设备上执行mmap调用时,驱动程序还可以使用remap_pfn_range将该缓冲区映射回用户空间。 但是,当缓冲区由多个巨页支持时,事情会变得复杂。 似乎内核可以返回由非连续的大页面支持的缓冲区。 即,如果巨页页面的布局是这样的 +——+——+——+——+ | HP 1 | HP 2 | HP 3 | HP 4 | +——+——+——+——+ ,通过保留HP1和HP4,或HP3,然后HP2,可以满足对大页面支持的缓冲区的请求。 这意味着当我在最后一种情况下使用get_user_pages获取页面时,页面0的地址实际上是在页面262.144(下一个巨页的头部)的地址之后的1 GB。 有没有办法隔离访问这些页面? 我尝试重新排序地址以找到较低的地址,这样我就可以使用整个缓冲区(例如,如果内核给我一个由HP3支持的缓冲区,HP2我用作HP2的基地址),但它似乎会扰乱数据在用户空间中(该重新排序的缓冲区中的偏移量0可能在用户空间缓冲区中偏移1GB)。 TL; DR:给定> 1个无序的大页面,有没有办法在Linux内核驱动程序中按顺序访问它们? 顺便说一句,我正在使用3.8.0-29通用内核的Linux机器。