vmslice通过将用户态输入的虚拟地址转换为物理地址,然后在内核中直接将数据Move到Pipe中,根据上图可知,实际上就是将指针指向了用户态的数据对应的struct page上。将用户态的地址转换为虚拟地址这个工作是通过iov_iter_get_pages来完成的。通过iov_iter_get_pages,可以将iov_iter作为输入的一串buffer转换为一串struct page。
Therefore we need turn arbitrary chunks of virtual memory into a bunch of struct page
s. This is exactly what iov_iter_get_pages
does, and where we’re spending half of our time:
ssize_t iov_iter_get_pages(
struct iov_iter *i, // input: a sized buffer in virtual memory
struct page **pages, // output: the list of pages which back the input buffers
size_t maxsize, // maximum number of bytes to get
unsigned maxpages, // maximum number of pages to get
size_t *start // offset into first page, if the input buffer wasn't page-aligned
);