]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
powerpc/pseries: CMO unused page hinting
authorRobert Jennings <rcj@linux.vnet.ibm.com>
Wed, 15 Apr 2009 05:55:32 +0000 (05:55 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 21 May 2009 05:43:58 +0000 (15:43 +1000)
Adds support for the "unused" page hint which can be used in shared
memory partitions to flag pages not in use, which will then be stolen
before active pages by the hypervisor when memory needs to be moved to
LPARs in need of additional memory.  Failure to mark pages as 'unused'
makes the LPAR slower to give up unused memory to other partitions.

This adds the kernel parameter 'cmo_free_hint' to disable this
functionality.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Documentation/kernel-parameters.txt
arch/powerpc/include/asm/page.h
arch/powerpc/platforms/pseries/lpar.c

index e87bdbfbcc75e236124a526d4456ddf3c6afc4e3..844e9a654d0b084ab6d9ed82e8de9b67e3f255d8 100644 (file)
@@ -497,6 +497,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        Also note the kernel might malfunction if you disable
                        some critical bits.
 
+       cmo_free_hint=  [PPC] Format: { yes | no }
+                       Specify whether pages are marked as being inactive
+                       when they are freed.  This is used in CMO environments
+                       to determine OS memory pressure for page stealing by
+                       a hypervisor.
+                       Default: yes
+
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
index 32cbf16f10eac9090640bbb9c8d4033870989892..4940662ee87ef09c512d46c437ed0e848e51a2d3 100644 (file)
@@ -231,6 +231,11 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr,
                struct page *p);
 extern int page_is_ram(unsigned long pfn);
 
+#ifdef CONFIG_PPC_SMLPAR
+void arch_free_page(struct page *page, int order);
+#define HAVE_ARCH_FREE_PAGE
+#endif
+
 struct vm_area_struct;
 
 typedef struct page *pgtable_t;
index 52a80e5840e87ee51c6ff33eea5fbdc83d9c7205..e3139fa5e556e78ddcdeacc4e4850b7aeeba6ed4 100644 (file)
@@ -609,3 +609,55 @@ void __init hpte_init_lpar(void)
        ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
        ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
 }
+
+#ifdef CONFIG_PPC_SMLPAR
+#define CMO_FREE_HINT_DEFAULT 1
+static int cmo_free_hint_flag = CMO_FREE_HINT_DEFAULT;
+
+static int __init cmo_free_hint(char *str)
+{
+       char *parm;
+       parm = strstrip(str);
+
+       if (strcasecmp(parm, "no") == 0 || strcasecmp(parm, "off") == 0) {
+               printk(KERN_INFO "cmo_free_hint: CMO free page hinting is not active.\n");
+               cmo_free_hint_flag = 0;
+               return 1;
+       }
+
+       cmo_free_hint_flag = 1;
+       printk(KERN_INFO "cmo_free_hint: CMO free page hinting is active.\n");
+
+       if (strcasecmp(parm, "yes") == 0 || strcasecmp(parm, "on") == 0)
+               return 1;
+
+       return 0;
+}
+
+__setup("cmo_free_hint=", cmo_free_hint);
+
+static void pSeries_set_page_state(struct page *page, int order,
+                                  unsigned long state)
+{
+       int i, j;
+       unsigned long cmo_page_sz, addr;
+
+       cmo_page_sz = cmo_get_page_size();
+       addr = __pa((unsigned long)page_address(page));
+
+       for (i = 0; i < (1 << order); i++, addr += PAGE_SIZE) {
+               for (j = 0; j < PAGE_SIZE; j += cmo_page_sz)
+                       plpar_hcall_norets(H_PAGE_INIT, state, addr + j, 0);
+       }
+}
+
+void arch_free_page(struct page *page, int order)
+{
+       if (!cmo_free_hint_flag || !firmware_has_feature(FW_FEATURE_CMO))
+               return;
+
+       pSeries_set_page_state(page, order, H_PAGE_SET_UNUSED);
+}
+EXPORT_SYMBOL(arch_free_page);
+
+#endif