Linus Torvalds wrote:
> We don't want to lose dirty bits by mistake. The only cases where it's ok
> to clear the dirty bit is when we truncate a page completely (so it won't
> be needed and obviously really shouldn't be written out) and when we've
> lost the last user of a swap cache entry.
> 
> Any other cases might be bugs, where we remove a page from a mapping
> without noticing that it is dirty (we had this bug in reclaim_pages(), for
> example).

I tried to go the lazy way the first time.  This time I put the BUG in
there and then went chasing all the places that do
(__)remove_inode_page.  There are tentacles all over the place but I
*think* I found them all.  That turned up one more place needing
changing, and this is one you already spotted a couple of days ago, in
reclaim_page.  I subjected this patch to some dbenching without
triggering the BUG.

The try_to_unuse function calls delete_from_swap_cache and this is
pretty unfamiliar stuff for me, but it looks like the page is just
freshly read and couldn't be dirty.  There's one more case in
arch/68K/atari/stram.c (unswap_by_read), similar to try_to_unuse.

OK, I see you just posted -pre5 while I was making the patch, but here
it is anyway, as a cross-check.

--- 2.4.0-test13-pre4.clean/mm/filemap.c        Fri Dec 29 03:14:58 2000
+++ 2.4.0-test13-pre4/mm/filemap.c      Fri Dec 29 04:29:09 2000
@@ -96,6 +96,7 @@
        remove_page_from_inode_queue(page);
        remove_page_from_hash_queue(page);
        page->mapping = NULL;
+       if (PageDirty(page)) BUG();
 }
 
 void remove_inode_page(struct page *page)
@@ -132,7 +133,7 @@
                curr = curr->next;
 
                /* We cannot invalidate a locked page */
-               if (TryLockPage(page))
+               if (PageDirty(page) || TryLockPage(page))
                        continue;
 
                /* Neither can we invalidate something in use.. */
--- 2.4.0-test13-pre4.clean/mm/vmscan.c Fri Dec 29 03:14:58 2000
+++ 2.4.0-test13-pre4/mm/vmscan.c       Fri Dec 29 04:30:48 2000
@@ -484,7 +484,7 @@
                }
 
                /* The page is dirty, or locked, move to inactive_dirty list. */
-               if (page->buffers || TryLockPage(page)) {
+               if (page->buffers || PageDirty(page) || TryLockPage(page)) {
                        del_page_from_inactive_clean_list(page);
                        add_page_to_inactive_dirty_list(page);
                        continue;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to