diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-03-14 11:46:05 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 08:07:29 -0400 |
commit | f7f8d7e51d3c31426ee006c38d5b0ae3c9b8733e (patch) | |
tree | de91adcab7bc1b86dfc40194595d827f0c1dc41b /arch | |
parent | 1bca09f7144450989e409c82ff0db83dddf489ac (diff) |
s390/mm: speedup storage key initialization
Use sske with multiple block control to initialize storage keys within
a 1 MB frame at once.
It turned out that the sske with mb=1 is an order of magnitude faster
than pfmf. This is only an issue for very large systems (several 100GB)
where storage key initialization could last more than a minute.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/mm/pageattr.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index d21040ed5e59..80adfbf75065 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c | |||
@@ -9,31 +9,25 @@ | |||
9 | #include <asm/pgtable.h> | 9 | #include <asm/pgtable.h> |
10 | #include <asm/page.h> | 10 | #include <asm/page.h> |
11 | 11 | ||
12 | static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) | ||
13 | { | ||
14 | asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0" | ||
15 | : [addr] "+a" (addr) : [skey] "d" (skey)); | ||
16 | return addr; | ||
17 | } | ||
18 | |||
12 | void storage_key_init_range(unsigned long start, unsigned long end) | 19 | void storage_key_init_range(unsigned long start, unsigned long end) |
13 | { | 20 | { |
14 | unsigned long boundary, function, size; | 21 | unsigned long boundary, size; |
15 | 22 | ||
16 | while (start < end) { | 23 | while (start < end) { |
17 | if (MACHINE_HAS_EDAT2) { | ||
18 | /* set storage keys for a 2GB frame */ | ||
19 | function = 0x22000 | PAGE_DEFAULT_KEY; | ||
20 | size = 1UL << 31; | ||
21 | boundary = (start + size) & ~(size - 1); | ||
22 | if (boundary <= end) { | ||
23 | do { | ||
24 | start = pfmf(function, start); | ||
25 | } while (start < boundary); | ||
26 | continue; | ||
27 | } | ||
28 | } | ||
29 | if (MACHINE_HAS_EDAT1) { | 24 | if (MACHINE_HAS_EDAT1) { |
30 | /* set storage keys for a 1MB frame */ | 25 | /* set storage keys for a 1MB frame */ |
31 | function = 0x21000 | PAGE_DEFAULT_KEY; | ||
32 | size = 1UL << 20; | 26 | size = 1UL << 20; |
33 | boundary = (start + size) & ~(size - 1); | 27 | boundary = (start + size) & ~(size - 1); |
34 | if (boundary <= end) { | 28 | if (boundary <= end) { |
35 | do { | 29 | do { |
36 | start = pfmf(function, start); | 30 | start = sske_frame(start, PAGE_DEFAULT_KEY); |
37 | } while (start < boundary); | 31 | } while (start < boundary); |
38 | continue; | 32 | continue; |
39 | } | 33 | } |