aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-25 10:10:14 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:15 -0400
commite2b8d7af0e3a9234de06606f9151f28cf847a8d6 (patch)
tree64bc03271383a43c2097b84b6f0e25c34ed13553
parent92f842eac7ee321c8a0749aba2513541b4ac226f (diff)
[S390] add support for nonquiescing sske
Improve performance of the sske operation by using the nonquiescing variant if the affected page has no mappings established. On machines with no support for the new sske variant the mask bit will be ignored. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/page.h8
-rw-r--r--arch/s390/include/asm/pgtable.h8
-rw-r--r--arch/s390/kernel/early.c3
-rw-r--r--arch/s390/kernel/setup.c3
-rw-r--r--include/asm-generic/pgtable.h2
-rw-r--r--include/linux/page-flags.h2
-rw-r--r--mm/rmap.c4
7 files changed, 18 insertions, 12 deletions
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index af650fb4720..a8729ea7e9a 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -108,9 +108,13 @@ typedef pte_t *pgtable_t;
108#define __pgprot(x) ((pgprot_t) { (x) } ) 108#define __pgprot(x) ((pgprot_t) { (x) } )
109 109
110static inline void 110static inline void
111page_set_storage_key(unsigned long addr, unsigned int skey) 111page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
112{ 112{
113 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); 113 if (!mapped)
114 asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
115 : : "d" (skey), "a" (addr));
116 else
117 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
114} 118}
115 119
116static inline unsigned int 120static inline unsigned int
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 85cd4b039de..f79e7bb9ae1 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -590,7 +590,7 @@ static inline void rcp_unlock(pte_t *ptep)
590} 590}
591 591
592/* forward declaration for SetPageUptodate in page-flags.h*/ 592/* forward declaration for SetPageUptodate in page-flags.h*/
593static inline void page_clear_dirty(struct page *page); 593static inline void page_clear_dirty(struct page *page, int mapped);
594#include <linux/page-flags.h> 594#include <linux/page-flags.h>
595 595
596static inline void ptep_rcp_copy(pte_t *ptep) 596static inline void ptep_rcp_copy(pte_t *ptep)
@@ -800,7 +800,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
800 } 800 }
801 dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); 801 dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
802 if (skey & _PAGE_CHANGED) 802 if (skey & _PAGE_CHANGED)
803 page_clear_dirty(page); 803 page_clear_dirty(page, 1);
804 rcp_unlock(ptep); 804 rcp_unlock(ptep);
805 return dirty; 805 return dirty;
806} 806}
@@ -975,9 +975,9 @@ static inline int page_test_dirty(struct page *page)
975} 975}
976 976
977#define __HAVE_ARCH_PAGE_CLEAR_DIRTY 977#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
978static inline void page_clear_dirty(struct page *page) 978static inline void page_clear_dirty(struct page *page, int mapped)
979{ 979{
980 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY); 980 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped);
981} 981}
982 982
983/* 983/*
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c00856ad4e5..0badc6344eb 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -208,7 +208,8 @@ static noinline __init void init_kernel_storage_key(void)
208 end_pfn = PFN_UP(__pa(&_end)); 208 end_pfn = PFN_UP(__pa(&_end));
209 209
210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) 210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
211 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 211 page_set_storage_key(init_pfn << PAGE_SHIFT,
212 PAGE_DEFAULT_KEY, 0);
212} 213}
213 214
214static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); 215static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c8e8e1354e1..9071e984dcf 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -627,7 +627,8 @@ setup_memory(void)
627 add_active_range(0, start_chunk, end_chunk); 627 add_active_range(0, start_chunk, end_chunk);
628 pfn = max(start_chunk, start_pfn); 628 pfn = max(start_chunk, start_pfn);
629 for (; pfn < end_chunk; pfn++) 629 for (; pfn < end_chunk; pfn++)
630 page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); 630 page_set_storage_key(PFN_PHYS(pfn),
631 PAGE_DEFAULT_KEY, 0);
631 } 632 }
632 633
633 psw_set_key(PAGE_DEFAULT_KEY); 634 psw_set_key(PAGE_DEFAULT_KEY);
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index f4d4120e512..6f3c6ae4fe0 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -108,7 +108,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
108#endif 108#endif
109 109
110#ifndef __HAVE_ARCH_PAGE_CLEAR_DIRTY 110#ifndef __HAVE_ARCH_PAGE_CLEAR_DIRTY
111#define page_clear_dirty(page) do { } while (0) 111#define page_clear_dirty(page, mapped) do { } while (0)
112#endif 112#endif
113 113
114#ifndef __HAVE_ARCH_PAGE_TEST_DIRTY 114#ifndef __HAVE_ARCH_PAGE_TEST_DIRTY
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 6fa317801e1..5f38c460367 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -310,7 +310,7 @@ static inline void SetPageUptodate(struct page *page)
310{ 310{
311#ifdef CONFIG_S390 311#ifdef CONFIG_S390
312 if (!test_and_set_bit(PG_uptodate, &page->flags)) 312 if (!test_and_set_bit(PG_uptodate, &page->flags))
313 page_clear_dirty(page); 313 page_clear_dirty(page, 0);
314#else 314#else
315 /* 315 /*
316 * Memory barrier must be issued before setting the PG_uptodate bit, 316 * Memory barrier must be issued before setting the PG_uptodate bit,
diff --git a/mm/rmap.c b/mm/rmap.c
index 92e6757f196..5f17fad1bee 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -745,7 +745,7 @@ int page_mkclean(struct page *page)
745 if (mapping) { 745 if (mapping) {
746 ret = page_mkclean_file(mapping, page); 746 ret = page_mkclean_file(mapping, page);
747 if (page_test_dirty(page)) { 747 if (page_test_dirty(page)) {
748 page_clear_dirty(page); 748 page_clear_dirty(page, 1);
749 ret = 1; 749 ret = 1;
750 } 750 }
751 } 751 }
@@ -942,7 +942,7 @@ void page_remove_rmap(struct page *page)
942 * containing the swap entry, but page not yet written to swap. 942 * containing the swap entry, but page not yet written to swap.
943 */ 943 */
944 if ((!PageAnon(page) || PageSwapCache(page)) && page_test_dirty(page)) { 944 if ((!PageAnon(page) || PageSwapCache(page)) && page_test_dirty(page)) {
945 page_clear_dirty(page); 945 page_clear_dirty(page, 1);
946 set_page_dirty(page); 946 set_page_dirty(page);
947 } 947 }
948 /* 948 /*