Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

William Lee Irwin III and committed by
Linus Torvalds
dd1d5afc 93ea1d0a

+19 -1
+19 -1
mm/filemap.c
··· 139 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 162 smp_mb(); 145 163 mapping = page_mapping(page);