Linux内核中的内存通常是不可替换的(Do Kernel pages get swapped out?)。但是,有时允许换出内存很有用。是否可以在Linux内核中显式分配可交换内存?我想到的一种方法是创建用户空间进程并使用其内存。还有什么更好的吗?
答案 0 :(得分:2)
您可以在内部shm
共享内存文件系统中创建文件。
const char *name = "example";
loff_t size = PAGE_SIZE;
unsigned long flags = 0;
struct file *filp = shmem_file_setup(name, size, flags);
/* assert(!IS_ERR(filp)); */
文件实际上并未链接,因此名称不可见。标志可以包括VM_NORESERVE
以预先跳过会计,而不是在分配页面时进行计费。现在您有一个shmem
文件。您可以像这样映射页面:
struct address_space *mapping = filp->f_mapping;
pgoff_t index = 0;
struct page *p = shmem_read_mapping_page(mapping, index);
/* assert(!IS_ERR(filp)); */
void *data = page_to_virt(p);
memset(data, 0, PAGE_SIZE);
还有shmem_read_mapping_page_gfp(..., gfp_t)
来指定页面的分配方式。完成后不要忘记把页面放回去。
put_page(p);
与文件同上。
fput(filp);
答案 1 :(得分:0)
问题的答案是简单的“否”或“是”,但对内核源代码进行了复杂的修改。
首先,要启用换出,您必须问自己,kswapd换出时发生了什么。本质上,它将遍历所有过程并确定是否可以换出其内存。而且所有这些内存的硬件模式都为ring3。因此,SMAP本质上禁止将其作为数据读取或作为程序在内核(ring 0)中执行:
https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
并检查您的发行版“ CONFIG_X86_SMAP”,对于我的Ubuntu,默认情况下为“ y”,这在过去几年中一直存在。
但是,如果将内存保留为内核地址(0环),则可能需要考虑更改kswapd操作以触发内核地址换出。鞭打内核地址先走?如果地址是kswapd内核操作的一部分,该怎么办?涉及的复杂性很大。
接下来要考虑的是操作中的交换:尝试读取内存并且启用它的“不存在”位时,硬件异常将触发linux内核内存故障处理程序(即__do_page_fault())。
并查看__do_page_fault:
https://elixir.bootlin.com/linux/latest/source/arch/x86/mm/fault.c#L1477
以及如何处理内核地址(do_kern_address_fault()):
https://elixir.bootlin.com/linux/latest/source/arch/x86/mm/fault.c#L1174
实质上只是报告可能情况下的错误。如果要启用内核地址页面错误,则必须修改此路径。
还要注意,SMAP检查(在smap_violation内部)是在用户地址页面错误(do_usr_addr_fault())中完成的。