通常情况下,大多数I/O操作在内核层次上都会进行数据缓冲,以提高性能。然后,有些情况下,直接对用户空间的缓冲区进行I/O读写操作可能更能提高性能和数据传输速率,特别针对大数据传递的情形,这样将省去了将数据从内核空间复制到用户空间的操作,从而节省了传输时间。
当然,在使用Direct I/O之间,也有必要了解下它的一些开销,毕竟,天下没有免费的午餐。
首先,启用Direct I/O,意味着将失去Buffered I/O的一切好处。其次,Direct I/O要求write系统调用必须同步执行,否则应用程序将不知道何时可重用它的I/O Buffer。很明显,这将影响应用程序的速度。不过,也有补救措施,即在这种情况下,一般都会同时使用异步I/O操作。
实现Direct I/O的核心函数是get_user_pages, 它的原形如下:
int get_user_pages(struct task_struct *tsk, // current
struct mm_struct *mm, // current->mm.
unsigned long start, // start is the (page-aligned) address of the user-space buffer
int len, // len is the length of the buffer in pages.
int write, // If write is nonzero, the pages are mapped for write access
int force, // The force flag tells get_user_pages
//to override the protections on the given pages to provide the requested access
// drivers should always pass 0 here.
struct page **pages,
struct vm_area_struct **vmas);
使用示例:
down_read(¤t->mm->mmap_sem);
result = get_user_pages(current, current->mm, ...);
up_read(¤t->mm->mmap_sem);
…
//avoid pages to be swapped out
if (! PageReserved(page))
SetPageDirty(page);
…
// free pages
//void page_cache_release(struct page *page);