Memory management 如何在内核中从一个物理页复制到另一个物理页

Memory management 如何在内核中从一个物理页复制到另一个物理页,memory-management,linux-kernel,Memory Management,Linux Kernel,我有一个164K物理页面的列表(由structpage表示),我希望将其收集到一个64KB的连续巨大页面中。这当然是在内核中完成的。 现在我这样做如下(下面的咆哮可能有错误,这只是为了想法): struct page*ground\u page=alloc\u页面(gfp\u标志,获取订单(16*页面大小)); char*gather\u buff=(char*)kmap(巨大的页面); 对于(i=0;i

我有一个164K物理页面的列表(由structpage表示),我希望将其收集到一个64KB的连续巨大页面中。这当然是在内核中完成的。 现在我这样做如下(下面的咆哮可能有错误,这只是为了想法):

struct page*ground\u page=alloc\u页面(gfp\u标志,获取订单(16*页面大小));
char*gather\u buff=(char*)kmap(巨大的页面);
对于(i=0;i<16;i++){
char*tmp_addr=(char*)kmap(小页面);
memcpy(聚集buff+i*页面大小、tmp地址、页面大小);
kunmap(小页数[i]);
}
kunmap(巨大的页面);
我担心kmap/kunmap在性能方面非常低效,我想知道是否有其他方法可以做到这一点? (看了一份又一份的复印件以供参考,但必须承认我在那里迷路了)


谢谢

我认为kmap/kunmap相当于x86_64系统上的一个简单指针算术运算,因此它不会显著影响性能


在这个问题中,有一些关于64位系统中高内存的详细信息:

谢谢!我不知道我怎么能理解这仅仅是指针运算。kmap/unmap不应该包含页表更新吗?定位空闲PTE、更新映射、将页面更新为映射等…由于64位系统中没有高mem区域,因此所有物理页面都提前映射到内核页面表。
struct page *huge_page = alloc_pages(gfp_flags, get_order(16*PAGE_SIZE));
char *gather_buff = (char *)kmap(huge_page); 
for (i = 0; i < 16; i++) {
     char* tmp_addr = (char *)kmap(small_pages_arr[i]);
     memcpy(gather_buff + i*PAGE_SIZE, tmp_addr, PAGE_SIZE);
     kunmap(small_pages_arr[i]);
}
kunmap(huge_page);