Skip to content

Commit

Permalink
powerpc/pseries: CMO unused page hinting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robert Jennings authored and Benjamin Herrenschmidt committed May 21, 2009
1 parent d69a78d commit 14f966e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions arch/powerpc/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
52 changes: 52 additions & 0 deletions arch/powerpc/platforms/pseries/lpar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 14f966e

Please sign in to comment.