Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Performing Direct I/O
|
437
list from the array of struct page pointers. We discuss how to do this in the section,
“Scatter/gather mappings.”
Once your direct I/O operation is complete, you must release the user pages. Before
doing so, however, you must inform the kernel if you changed the contents of those
pages. Otherwise, the kernel may think that the pages are “clean,” meaning that they
match a copy found on the swap device, and free them without writing them out to
backing store. So, if you have changed the pages (in response to a user-space read
request), you must mark each affected page dirty with a call to:
void SetPageDirty(struct page *page);
(This macro is defined in <linux/page-flags.h>). Most code that performs this opera-
tion checks first to ensure that the page is not in the reserved part of the memory
map, which is never swapped out. Therefore, the code usually looks like:
if (! PageReserved(page))
SetPageDirty(page);
Since user-space memory is not normally marked reserved, this check should not
strictly be necessary, but when you are getting your hands dirty deep within the
memory management subsystem, it is best to be thorough and careful.
Regardless of whether the pages have been changed, they must be freed from the
page cache, or they stay there forever. The call to use is:
void page_cache_release(struct page *page);
This call should, of course, be made after the page has been marked dirty, if need be.
Asynchronous I/O
One of the new features added to the 2.6 kernel was the asynchronous I/O capabil-
ity. Asynchronous I/O allows user space to initiate operations without waiting for
their completion; thus, an application can do other processing while its I/O is in
flight. A complex, high-performance application can also use asynchronous I/O to
have multiple operations going at the same time.
The implementation of asynchronous I/O is optional, and very few driver authors
bother; most devices do not benefit from this capability. As we will see in the com-
ing chapters, block and network drivers are fully asynchronous at all times, so only
char drivers are candidates for explicit asynchronous I/O support. A char device can
benefit from this support if there are good reasons for having more than one I/O
operation outstanding at any given time. One good example is streaming tape drives,
where the drive can stall and slow down significantly if I/O operations do not arrive
quickly enough. An application trying to get the best performance out of a streaming
drive could use asynchronous I/O to have multiple operations ready to go at any
given time.
,ch15.13676 Page 437 Friday, January 21, 2005 11:04 AM