当一个进程在调用“read”后被阻塞时,内核从ios读取数据并将其复制到缓冲区,但缓冲区在内核或用户空间中(这是参数) “读取”功能)。为了以后的选择,它可以节省从内核空间到用户空间的应对,而且用户空间中有更多的缓冲区。但每次应对时都应该更改cr3,这会刷新所有TLB数据。这就是我所知道的两个选择,还有什么吗?
答案 0 :(得分:1)
其中一种方法是让设备驱动程序通过mmap将其内核缓冲区映射到进程的用户地址空间,然后使用像remap_pfn_range这样的东西。
当驱动程序完成I / O操作时,复制到其内核缓冲区不需要更改cr3或击落TLB。
当用户进程正在等待I / O时,很可能它会被安排出来运行另一个新进程,然后cr3必须更改(+ TLB flush)以获得整个I / O操作完成。
答案 1 :(得分:1)
我在内核中看到的一个常见模式是缓冲区通常在内核空间中分配 - kzalloc(PAGE_SIZE, GFP_KERNEL)
(不一定是PAGE_SIZE),然后读取发生在该缓冲区中。然后使用simple_read_from_buffer(..)
(fs / libfs.c)将其复制到用户空间 - 内部使用copy_to_user()
。虽然这通常用于简单的I / O操作或其他(例如debugfs)读取。