[PATCH] pagecache lock ordering

From: Hugh Dickins (hugh@veritas.com)
Date: Wed Jan 09 2002 - 19:42:08 EST


There's two places, do_buffer_fdatasync and __find_lock_page_helper,
which violate the pagemap_lru_lock before pagecache_lock rule,
if page_cache_release frees page calling lru_cache_del.

I was worried when I saw Ben's patch to move lru_cache_del down
into __free_pages_ok: thought it might cause a spinlock ordering
violation somewhere. Source check showed up no new problem from
his patch, but these two already a problem (and still a problem
when Ben's patch goes in).

Hugh

--- 2.4.18-pre2/mm/filemap.c Wed Jan 9 18:17:39 2002
+++ linux/mm/filemap.c Wed Jan 9 19:11:17 2002
@@ -493,6 +493,7 @@
 {
         struct list_head *curr;
         struct page *page;
+ struct page *relpage = NULL;
         int retval = 0;
 
         spin_lock(&pagecache_lock);
@@ -509,6 +510,9 @@
 
                 page_cache_get(page);
                 spin_unlock(&pagecache_lock);
+ if (relpage)
+ page_cache_release(relpage);
+ relpage = page;
                 lock_page(page);
 
                 /* The buffers could have been free'd while we waited for the page lock */
@@ -518,10 +522,11 @@
                 UnlockPage(page);
                 spin_lock(&pagecache_lock);
                 curr = page->list.next;
- page_cache_release(page);
         }
         spin_unlock(&pagecache_lock);
 
+ if (relpage)
+ page_cache_release(relpage);
         return retval;
 }
 
@@ -900,14 +905,15 @@
                 if (TryLockPage(page)) {
                         spin_unlock(&pagecache_lock);
                         lock_page(page);
- spin_lock(&pagecache_lock);
 
                         /* Has the page been re-allocated while we slept? */
                         if (page->mapping != mapping || page->index != offset) {
                                 UnlockPage(page);
                                 page_cache_release(page);
+ spin_lock(&pagecache_lock);
                                 goto repeat;
                         }
+ spin_lock(&pagecache_lock);
                 }
         }
         return page;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jan 15 2002 - 21:00:29 EST