【发布时间】:2012-06-02 03:28:24
【问题描述】:
当一个进程在调用“read”后被阻塞时,内核从ios读取数据并将其复制到缓冲区,但是缓冲区在哪里,在内核还是在用户空间(这是“read”函数)。它节省了从内核空间到用户空间的处理,以供以后选择,而且用户空间有更多的缓冲区。但是每次应对时都要更改cr3,这会刷新所有TLB数据。这就是我所知道的两个选择,还有其他的吗?
【问题讨论】:
标签: operating-system linux-kernel kernel
当一个进程在调用“read”后被阻塞时,内核从ios读取数据并将其复制到缓冲区,但是缓冲区在哪里,在内核还是在用户空间(这是“read”函数)。它节省了从内核空间到用户空间的处理,以供以后选择,而且用户空间有更多的缓冲区。但是每次应对时都要更改cr3,这会刷新所有TLB数据。这就是我所知道的两个选择,还有其他的吗?
【问题讨论】:
标签: operating-system linux-kernel kernel
我在内核中看到的一个常见模式是缓冲区通常分配在内核空间 - kzalloc(PAGE_SIZE, GFP_KERNEL)(不一定是 PAGE_SIZE),然后读取发生在该缓冲区中。然后使用simple_read_from_buffer(..) (fs/libfs.c) 将其复制到用户空间——内部使用copy_to_user()。虽然这通常用于简单的 I/O 操作或其他(例如 debugfs)读取。
【讨论】:
其中一种方法是要求设备驱动程序通过 mmap 将其内核缓冲区映射到进程的用户地址空间,然后使用 remap_pfn_range 之类的东西。
当驱动程序完成 I/O 操作后,复制到其内核缓冲区不需要更改 cr3 或击落 TLB。
当用户进程在等待 I/O 时,很有可能它会被调度到另一个新进程来运行,然后 cr3 必须为整个 I/O 更改(+ TLB 刷新)操作完成。
【讨论】: