aboutsummaryrefslogtreecommitdiff
path: root/mm/rmap.c
diff options
context:
space:
mode:
authorMartin Schwidefsky2012-11-07 13:17:37 +0100
committerMartin Schwidefsky2013-02-14 15:55:23 +0100
commitabf09bed3cceadd809f0356065c2ada6cee90d4a (patch)
treeb81cac34a4111f498cdef104a2b9c4c444faf0bd /mm/rmap.c
parent486c0a0bc80d370471b21662bf03f04fbb37cdc6 (diff)
s390/mm: implement software dirty bits
The s390 architecture is unique in respect to dirty page detection, it uses the change bit in the per-page storage key to track page modifications. All other architectures track dirty bits by means of page table entries. This property of s390 has caused numerous problems in the past, e.g. see git commit ef5d437f71afdf4a "mm: fix XFS oops due to dirty pages without buffers on s390". To avoid future issues in regard to per-page dirty bits convert s390 to a fault based software dirty bit detection mechanism. All user page table entries which are marked as clean will be hardware read-only, even if the pte is supposed to be writable. A write by the user process will trigger a protection fault which will cause the user pte to be marked as dirty and the hardware read-only bit is removed. With this change the dirty bit in the storage key is irrelevant for Linux as a host, but the storage key is still required for KVM guests. The effect is that page_test_and_clear_dirty and the related code can be removed. The referenced bit in the storage key is still used by the page_test_and_clear_young primitive to provide page age information. For page cache pages of mappings with mapping_cap_account_dirty there will not be any change in behavior as the dirty bit tracking already uses read-only ptes to control the amount of dirty pages. Only for swap cache pages and pages of mappings without mapping_cap_account_dirty there can be additional protection faults. To avoid an excessive number of additional faults the mk_pte primitive checks for PageDirty if the pgprot value allows for writes and pre-dirties the pte. That avoids all additional faults for tmpfs and shmem pages until these pages are added to the swap cache. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'mm/rmap.c')
-rw-r--r--mm/rmap.c24
1 files changed, 0 insertions, 24 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 2c78f8cadc95..3d38edffda41 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1126,7 +1126,6 @@ void page_add_file_rmap(struct page *page)
*/
void page_remove_rmap(struct page *page)
{
- struct address_space *mapping = page_mapping(page);
bool anon = PageAnon(page);
bool locked;
unsigned long flags;
@@ -1144,29 +1143,6 @@ void page_remove_rmap(struct page *page)
goto out;
/*
- * Now that the last pte has gone, s390 must transfer dirty
- * flag from storage key to struct page. We can usually skip
- * this if the page is anon, so about to be freed; but perhaps
- * not if it's in swapcache - there might be another pte slot
- * containing the swap entry, but page not yet written to swap.
- *
- * And we can skip it on file pages, so long as the filesystem
- * participates in dirty tracking (note that this is not only an
- * optimization but also solves problems caused by dirty flag in
- * storage key getting set by a write from inside kernel); but need to
- * catch shm and tmpfs and ramfs pages which have been modified since
- * creation by read fault.
- *
- * Note that mapping must be decided above, before decrementing
- * mapcount (which luckily provides a barrier): once page is unmapped,
- * it could be truncated and page->mapping reset to NULL at any moment.
- * Note also that we are relying on page_mapping(page) to set mapping
- * to &swapper_space when PageSwapCache(page).
- */
- if (mapping && !mapping_cap_account_dirty(mapping) &&
- page_test_and_clear_dirty(page_to_pfn(page), 1))
- set_page_dirty(page);
- /*
* Hugepages are not counted in NR_ANON_PAGES nor NR_FILE_MAPPED
* and not charged by memcg for now.
*/