diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2009-10-19 01:51:34 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-10-30 02:20:56 -0400 |
commit | 8be8cf5b47f72096e42bf88cc3afff7a942a346c (patch) | |
tree | 9adff0fa02123f48fbfa40abb55a5c01be8c2fa4 /arch/powerpc/platforms/pseries | |
parent | 6cff46f4bc6cc4a8a4154b0b6a2e669db08e8fd2 (diff) |
powerpc: Add kdump support to Collaborative Memory Manager
When running Active Memory Sharing, the Collaborative Memory Manager (CMM)
may mark some pages as "loaned" with the hypervisor. Periodically, the
CMM will query the hypervisor for a loan request, which is a single signed
value. When kexec'ing into a kdump kernel, the CMM driver in the kdump
kernel is not aware of the pages the previous kernel had marked as "loaned",
so the hypervisor and the CMM driver are out of sync. Fix the CMM driver
to handle this scenario by ignoring requests to decrease the number of loaned
pages if we don't think we have any pages loaned. Pages that are marked as
"loaned" which are not in the balloon will automatically get switched to "active"
the next time we touch the page. This also fixes the case where totalram_pages
is smaller than min_mem_mb, which can occur during kdump.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r-- | arch/powerpc/platforms/pseries/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/cmm.c | 29 |
2 files changed, 20 insertions, 11 deletions
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 26a24bd92623..27554c807fd5 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -60,7 +60,7 @@ config PPC_SMLPAR | |||
60 | 60 | ||
61 | config CMM | 61 | config CMM |
62 | tristate "Collaborative memory management" | 62 | tristate "Collaborative memory management" |
63 | depends on PPC_SMLPAR && !CRASH_DUMP | 63 | depends on PPC_SMLPAR |
64 | default y | 64 | default y |
65 | help | 65 | help |
66 | Select this option, if you want to enable the kernel interface | 66 | Select this option, if you want to enable the kernel interface |
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index 6567439fe78d..bcdcf0ccc8d7 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c | |||
@@ -229,8 +229,9 @@ static void cmm_get_mpp(void) | |||
229 | { | 229 | { |
230 | int rc; | 230 | int rc; |
231 | struct hvcall_mpp_data mpp_data; | 231 | struct hvcall_mpp_data mpp_data; |
232 | unsigned long active_pages_target; | 232 | signed long active_pages_target, page_loan_request, target; |
233 | signed long page_loan_request; | 233 | signed long total_pages = totalram_pages + loaned_pages; |
234 | signed long min_mem_pages = (min_mem_mb * 1024 * 1024) / PAGE_SIZE; | ||
234 | 235 | ||
235 | rc = h_get_mpp(&mpp_data); | 236 | rc = h_get_mpp(&mpp_data); |
236 | 237 | ||
@@ -238,17 +239,25 @@ static void cmm_get_mpp(void) | |||
238 | return; | 239 | return; |
239 | 240 | ||
240 | page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE); | 241 | page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE); |
241 | loaned_pages_target = page_loan_request + loaned_pages; | 242 | target = page_loan_request + (signed long)loaned_pages; |
242 | if (loaned_pages_target > oom_freed_pages) | 243 | |
243 | loaned_pages_target -= oom_freed_pages; | 244 | if (target < 0 || total_pages < min_mem_pages) |
245 | target = 0; | ||
246 | |||
247 | if (target > oom_freed_pages) | ||
248 | target -= oom_freed_pages; | ||
244 | else | 249 | else |
245 | loaned_pages_target = 0; | 250 | target = 0; |
251 | |||
252 | active_pages_target = total_pages - target; | ||
253 | |||
254 | if (min_mem_pages > active_pages_target) | ||
255 | target = total_pages - min_mem_pages; | ||
246 | 256 | ||
247 | active_pages_target = totalram_pages + loaned_pages - loaned_pages_target; | 257 | if (target < 0) |
258 | target = 0; | ||
248 | 259 | ||
249 | if ((min_mem_mb * 1024 * 1024) > (active_pages_target * PAGE_SIZE)) | 260 | loaned_pages_target = target; |
250 | loaned_pages_target = totalram_pages + loaned_pages - | ||
251 | ((min_mem_mb * 1024 * 1024) / PAGE_SIZE); | ||
252 | 261 | ||
253 | cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n", | 262 | cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n", |
254 | page_loan_request, loaned_pages, loaned_pages_target, | 263 | page_loan_request, loaned_pages, loaned_pages_target, |