Messages in this thread | | | Date | Tue, 1 Jul 1997 10:50:00 +0100 (BST) | From | Mark Hemment <> | Subject | Re: Page cache and swapping |
| |
Hi Jim,
On Fri, 27 Jun 1997, Jim Nance wrote: > But it does fit in memory, at least if you are talking about the program > I posted. I _think_ the problem is update (or whatever update calls) locks > all the pages when tries to synchronzie the disk and memory images. If > this is what it going on it would be nice if the kernel would not try to > flush diry file pages if they had been accessed in the last second or so. > > I would love to have someone look at this and confirm/deny my hypothesis > though.
No, update (kflushd) does not "lock all the pages". It is the "buffer flush" task. It scans the dirty-buffer list and kicks a write to their block-device (ll_rw_block()).
Dirty named pages (file pages) are written to disk when they are unmapped(), msync()ed, or reaped via swap_out(). swap_out() uses the "age" of a page to determine what to reap, so the dirty-pages you refer to are not always being written to disk.
As I believe has already been mentioned in this thread, page-writes use a slightly different buffer scheme to page-reads. Most page-reads go via brw_page(), which uses "async" buffer-heads. These heads do not appear on the normal buffer lists.
Page-writes go via file-system specific function (there is a generic_file_write(), but I believe it is only used by NFS at the moment, and requires a bit more work). The fs code normally calls ll_rw_block().
ll_rw_block() queues the buffers up for a device by making a "request" for it and adding the request to per-device queue. It also locks the buffer(s).
ll_rw_block() returns when it has added a request, not when the buffer(s) have been read/written. When a device has finished processing a request, it marks the request's buffer(s) has upto date (mark_buffer_uptodate()), and unlocks the buffer (unlock_buffer()).
Unlocking the buffer wakes up any task blocking on that buffer (bh->b_wait).
Sorry to be long winded, but you see everything happens nicely in the background. Only buffers which are queued for a read/write for a device are locked, not "all the pages".
However, when writing a dirty-named page back to its file, the inode of the file is 'locked' via its semaphore (inode->i_sem). This can cause problems, and hit performance, but I guess someone is working on this.
Writing anonymous pages to a swap-device/swap-file is different, but uses the some of the same functions. Have a look in mm/page_io.c.
Hope this is some help (and apologies to those who know there is a lot missing from the above).
NOTE: When writing a dirty named page to file, the page itself is _not_ locked. Infact the kernel cannot lock all references to the page without performing a large search. I haven't checked it all through, but there maybe a small window for problems here.
Regards,
markhe
----------------------------------------------------- Mark Hemment UNIX/C Software Engineer (contractor) "Success has many fathers. Failure is a b**tard" -----------------------------------------------------
| |