diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2007-11-20 05:13:36 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-11-20 05:13:46 -0500 |
commit | ce7e9fae8db07af4080e868f4588f8f095f803dc (patch) | |
tree | 000a6cc755ee35ef3cfc0795c13ed500dc5457de /mm | |
parent | b8e7a54cd06b0b0174029ef3a7f5a1415a2c28f2 (diff) |
[S390] Optimize storage key handling for anonymous pages
page_mkclean used to call page_clear_dirty for every given page. This
is different to all other architectures, where the dirty bit in the
PTEs is only resetted, if page_mapping() returns a non-NULL pointer.
We can move the page_test_dirty/page_clear_dirty sequence into the
2nd if to avoid unnecessary iske/sske sequences, which are expensive.
This change also helps kvm for s390 as the host must transfer the
dirty bit into the guest status bits. By moving the page_clear_dirty
operation into the 2nd if, the vm will only call page_clear_dirty
for pages where it walks the mapping anyway. There it calls
ptep_clear_flush for writable ptes, so we can transfer the dirty bit
to the guest.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/rmap.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -471,11 +471,12 @@ int page_mkclean(struct page *page) | |||
471 | 471 | ||
472 | if (page_mapped(page)) { | 472 | if (page_mapped(page)) { |
473 | struct address_space *mapping = page_mapping(page); | 473 | struct address_space *mapping = page_mapping(page); |
474 | if (mapping) | 474 | if (mapping) { |
475 | ret = page_mkclean_file(mapping, page); | 475 | ret = page_mkclean_file(mapping, page); |
476 | if (page_test_dirty(page)) { | 476 | if (page_test_dirty(page)) { |
477 | page_clear_dirty(page); | 477 | page_clear_dirty(page); |
478 | ret = 1; | 478 | ret = 1; |
479 | } | ||
479 | } | 480 | } |
480 | } | 481 | } |
481 | 482 | ||