diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2011-05-04 02:01:20 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-05-04 02:02:21 -0400 |
commit | 9ee820fa005254dfc816330f6654f14dcb2beee1 (patch) | |
tree | 1d36b17ec6a4c56dd24f9be2f7f31e6321040ed0 /arch/powerpc/kernel | |
parent | 7707e4110e5692fe85e7e6c471c9bb2a9254d313 (diff) |
powerpc/pseries: Add page coalescing support
Adds support for page coalescing, which is a feature on IBM Power servers
which allows for coalescing identical pages between logical partitions.
Hint text pages as coalesce candidates, since they are the most likely
pages to be able to be coalesced between partitions. This patch also
exports some page coalescing statistics available from firmware via
lparcfg.
[BenH: Moved a couple of things around to fix compile problems]
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 53 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 2 |
3 files changed, 30 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 301db65f05a1..84daabe2fcba 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -132,34 +132,6 @@ static int iseries_lparcfg_data(struct seq_file *m, void *v) | |||
132 | /* | 132 | /* |
133 | * Methods used to fetch LPAR data when running on a pSeries platform. | 133 | * Methods used to fetch LPAR data when running on a pSeries platform. |
134 | */ | 134 | */ |
135 | /** | ||
136 | * h_get_mpp | ||
137 | * H_GET_MPP hcall returns info in 7 parms | ||
138 | */ | ||
139 | int h_get_mpp(struct hvcall_mpp_data *mpp_data) | ||
140 | { | ||
141 | int rc; | ||
142 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
143 | |||
144 | rc = plpar_hcall9(H_GET_MPP, retbuf); | ||
145 | |||
146 | mpp_data->entitled_mem = retbuf[0]; | ||
147 | mpp_data->mapped_mem = retbuf[1]; | ||
148 | |||
149 | mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff; | ||
150 | mpp_data->pool_num = retbuf[2] & 0xffff; | ||
151 | |||
152 | mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff; | ||
153 | mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff; | ||
154 | mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff; | ||
155 | |||
156 | mpp_data->pool_size = retbuf[4]; | ||
157 | mpp_data->loan_request = retbuf[5]; | ||
158 | mpp_data->backing_mem = retbuf[6]; | ||
159 | |||
160 | return rc; | ||
161 | } | ||
162 | EXPORT_SYMBOL(h_get_mpp); | ||
163 | 135 | ||
164 | struct hvcall_ppp_data { | 136 | struct hvcall_ppp_data { |
165 | u64 entitlement; | 137 | u64 entitlement; |
@@ -345,6 +317,30 @@ static void parse_mpp_data(struct seq_file *m) | |||
345 | seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem); | 317 | seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem); |
346 | } | 318 | } |
347 | 319 | ||
320 | /** | ||
321 | * parse_mpp_x_data | ||
322 | * Parse out data returned from h_get_mpp_x | ||
323 | */ | ||
324 | static void parse_mpp_x_data(struct seq_file *m) | ||
325 | { | ||
326 | struct hvcall_mpp_x_data mpp_x_data; | ||
327 | |||
328 | if (!firmware_has_feature(FW_FEATURE_XCMO)) | ||
329 | return; | ||
330 | if (h_get_mpp_x(&mpp_x_data)) | ||
331 | return; | ||
332 | |||
333 | seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes); | ||
334 | |||
335 | if (mpp_x_data.pool_coalesced_bytes) | ||
336 | seq_printf(m, "pool_coalesced_bytes=%ld\n", | ||
337 | mpp_x_data.pool_coalesced_bytes); | ||
338 | if (mpp_x_data.pool_purr_cycles) | ||
339 | seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles); | ||
340 | if (mpp_x_data.pool_spurr_cycles) | ||
341 | seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles); | ||
342 | } | ||
343 | |||
348 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 | 344 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 |
349 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) | 345 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) |
350 | 346 | ||
@@ -520,6 +516,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) | |||
520 | parse_system_parameter_string(m); | 516 | parse_system_parameter_string(m); |
521 | parse_ppp_data(m); | 517 | parse_ppp_data(m); |
522 | parse_mpp_data(m); | 518 | parse_mpp_data(m); |
519 | parse_mpp_x_data(m); | ||
523 | pseries_cmo_data(m); | 520 | pseries_cmo_data(m); |
524 | splpar_dispatch_data(m); | 521 | splpar_dispatch_data(m); |
525 | 522 | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 7839bd7bfd15..c016033ba78d 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -700,8 +700,10 @@ static void __init early_cmdline_parse(void) | |||
700 | #endif /* CONFIG_PCI_MSI */ | 700 | #endif /* CONFIG_PCI_MSI */ |
701 | #ifdef CONFIG_PPC_SMLPAR | 701 | #ifdef CONFIG_PPC_SMLPAR |
702 | #define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */ | 702 | #define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */ |
703 | #define OV5_XCMO 0x40 /* Page Coalescing */ | ||
703 | #else | 704 | #else |
704 | #define OV5_CMO 0x00 | 705 | #define OV5_CMO 0x00 |
706 | #define OV5_XCMO 0x00 | ||
705 | #endif | 707 | #endif |
706 | #define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ | 708 | #define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ |
707 | 709 | ||
@@ -756,7 +758,7 @@ static unsigned char ibm_architecture_vec[] = { | |||
756 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | | 758 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | |
757 | OV5_DONATE_DEDICATE_CPU | OV5_MSI, | 759 | OV5_DONATE_DEDICATE_CPU | OV5_MSI, |
758 | 0, | 760 | 0, |
759 | OV5_CMO, | 761 | OV5_CMO | OV5_XCMO, |
760 | OV5_TYPE1_AFFINITY, | 762 | OV5_TYPE1_AFFINITY, |
761 | 0, | 763 | 0, |
762 | 0, | 764 | 0, |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index f48446635c89..271ff6318eda 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/time.h> | 42 | #include <asm/time.h> |
43 | #include <asm/mmu.h> | 43 | #include <asm/mmu.h> |
44 | #include <asm/topology.h> | 44 | #include <asm/topology.h> |
45 | #include <asm/pSeries_reconfig.h> | ||
45 | 46 | ||
46 | struct rtas_t rtas = { | 47 | struct rtas_t rtas = { |
47 | .lock = __ARCH_SPIN_LOCK_UNLOCKED | 48 | .lock = __ARCH_SPIN_LOCK_UNLOCKED |
@@ -731,6 +732,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w | |||
731 | 732 | ||
732 | atomic_set(&data->error, rc); | 733 | atomic_set(&data->error, rc); |
733 | start_topology_update(); | 734 | start_topology_update(); |
735 | pSeries_coalesce_init(); | ||
734 | 736 | ||
735 | if (wake_when_done) { | 737 | if (wake_when_done) { |
736 | atomic_set(&data->done, 1); | 738 | atomic_set(&data->done, 1); |