[PATCH] sync_page() smp_mb() comment
authorWilliam Lee Irwin III <wli@holomorphy.com>
Sun, 1 May 2005 15:58:38 +0000 (08:58 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 1 May 2005 15:58:38 +0000 (08:58 -0700)
The smp_mb() is becaus sync_page() doesn't have PG_locked while it accesses
page_mapping(page).  The comments in the patch (the entire patch is the
addition of this comment) try to explain further how and why smp_mb() is
used.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
mm/filemap.c

index 9b74674e36adff14a1977dcc4055f9e9c3be115b..ee79b5d3439f74126ad2fc0e659f3e39f4703997 100644 (file)
@@ -139,7 +139,25 @@ static int sync_page(void *word)
        page = container_of((page_flags_t *)word, struct page, flags);
 
        /*
-        * FIXME, fercrissake.  What is this barrier here for?
+        * page_mapping() is being called without PG_locked held.
+        * Some knowledge of the state and use of the page is used to
+        * reduce the requirements down to a memory barrier.
+        * The danger here is of a stale page_mapping() return value
+        * indicating a struct address_space different from the one it's
+        * associated with when it is associated with one.
+        * After smp_mb(), it's either the correct page_mapping() for
+        * the page, or an old page_mapping() and the page's own
+        * page_mapping() has gone NULL.
+        * The ->sync_page() address_space operation must tolerate
+        * page_mapping() going NULL. By an amazing coincidence,
+        * this comes about because none of the users of the page
+        * in the ->sync_page() methods make essential use of the
+        * page_mapping(), merely passing the page down to the backing
+        * device's unplug functions when it's non-NULL, which in turn
+        * ignore it for all cases but swap, where only page->private is
+        * of interest. When page_mapping() does go NULL, the entire
+        * call stack gracefully ignores the page and returns.
+        * -- wli
         */
        smp_mb();
        mapping = page_mapping(page);