Linux内核中的内存通常是不可交换的(Do Kernel pages get swapped out?)。但是,有时允许换出内存是很有用的。是否可以在Linux内核中显式地分配可交换内存?我想到的一种方法是创建一个用户空间进程并使用它的内存。还有更好的吗?
发布于 2017-07-15 07:04:40
您可以在内部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);发布于 2019-02-08 09:01:56
你的问题的答案是简单的否,或者是对内核源代码进行了复杂的修改。
首先,要启用换出,您必须问自己当kswapd换出时发生了什么。本质上,它将遍历所有进程,并决定是否可以交换其内存。所有这些内存都具有环3的硬件模式。因此SMAP本质上禁止它作为数据读取或作为程序在内核中执行(环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())中完成的。
https://stackoverflow.com/questions/45112292
复制相似问题