diff options
author | William Lee Irwin III <wli@holomorphy.com> | 2005-05-01 11:58:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:58:38 -0400 |
commit | dd1d5afca8d3bda7ff9db773fc08e648d2503dc6 (patch) | |
tree | b0cc49be9dc43558e31be18d6045181661492018 /mm/filemap.c | |
parent | 93ea1d0a12623dc1a693642b5758261f35f9bf96 (diff) |
[PATCH] sync_page() smp_mb() comment
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>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 9b74674e36ad..ee79b5d3439f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -139,7 +139,25 @@ static int sync_page(void *word) | |||
139 | page = container_of((page_flags_t *)word, struct page, flags); | 139 | page = container_of((page_flags_t *)word, struct page, flags); |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * FIXME, fercrissake. What is this barrier here for? | 142 | * page_mapping() is being called without PG_locked held. |
143 | * Some knowledge of the state and use of the page is used to | ||
144 | * reduce the requirements down to a memory barrier. | ||
145 | * The danger here is of a stale page_mapping() return value | ||
146 | * indicating a struct address_space different from the one it's | ||
147 | * associated with when it is associated with one. | ||
148 | * After smp_mb(), it's either the correct page_mapping() for | ||
149 | * the page, or an old page_mapping() and the page's own | ||
150 | * page_mapping() has gone NULL. | ||
151 | * The ->sync_page() address_space operation must tolerate | ||
152 | * page_mapping() going NULL. By an amazing coincidence, | ||
153 | * this comes about because none of the users of the page | ||
154 | * in the ->sync_page() methods make essential use of the | ||
155 | * page_mapping(), merely passing the page down to the backing | ||
156 | * device's unplug functions when it's non-NULL, which in turn | ||
157 | * ignore it for all cases but swap, where only page->private is | ||
158 | * of interest. When page_mapping() does go NULL, the entire | ||
159 | * call stack gracefully ignores the page and returns. | ||
160 | * -- wli | ||
143 | */ | 161 | */ |
144 | smp_mb(); | 162 | smp_mb(); |
145 | mapping = page_mapping(page); | 163 | mapping = page_mapping(page); |