Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ee820fa authored by Brian King's avatar Brian King Committed by Benjamin Herrenschmidt
Browse files

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: default avatarBrian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 7707e411
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#define FW_FEATURE_BEAT		ASM_CONST(0x0000000001000000)
#define FW_FEATURE_CMO		ASM_CONST(0x0000000002000000)
#define FW_FEATURE_VPHN		ASM_CONST(0x0000000004000000)
#define FW_FEATURE_XCMO		ASM_CONST(0x0000000008000000)

#ifndef __ASSEMBLY__

@@ -60,7 +61,7 @@ enum {
		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
		FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
		FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
		FW_FEATURE_CMO | FW_FEATURE_VPHN,
		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO,
	FW_FEATURE_PSERIES_ALWAYS = 0,
	FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
	FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
+12 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@
#define H_ANDCOND		(1UL<<(63-33))
#define H_ICACHE_INVALIDATE	(1UL<<(63-40))	/* icbi, etc.  (ignored for IO pages) */
#define H_ICACHE_SYNCHRONIZE	(1UL<<(63-41))	/* dcbst, icbi, etc (ignored for IO pages */
#define H_COALESCE_CAND	(1UL<<(63-42))	/* page is a good candidate for coalescing */
#define H_ZERO_PAGE		(1UL<<(63-48))	/* zero the page before mapping (ignored for IO pages) */
#define H_COPY_PAGE		(1UL<<(63-49))
#define H_N			(1UL<<(63-61))
@@ -234,6 +235,7 @@
#define H_GET_MPP		0x2D4
#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
#define H_BEST_ENERGY		0x2F4
#define H_GET_MPP_X		0x314
#define MAX_HCALL_OPCODE	H_BEST_ENERGY

#ifndef __ASSEMBLY__
@@ -312,6 +314,16 @@ struct hvcall_mpp_data {

int h_get_mpp(struct hvcall_mpp_data *);

struct hvcall_mpp_x_data {
	unsigned long coalesced_bytes;
	unsigned long pool_coalesced_bytes;
	unsigned long pool_purr_cycles;
	unsigned long pool_spurr_cycles;
	unsigned long reserved[3];
};

int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data);

#ifdef CONFIG_PPC_PSERIES
extern int CMO_PrPSP;
extern int CMO_SecPSP;
+5 −0
Original line number Diff line number Diff line
@@ -18,13 +18,18 @@
extern int pSeries_reconfig_notifier_register(struct notifier_block *);
extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
extern struct blocking_notifier_head pSeries_reconfig_chain;
/* Not the best place to put this, will be fixed when we move some
 * of the rtas suspend-me stuff to pseries */
extern void pSeries_coalesce_init(void);
#else /* !CONFIG_PPC_PSERIES */
static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
{
	return 0;
}
static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
static inline void pSeries_coalesce_init(void) { }
#endif /* CONFIG_PPC_PSERIES */


#endif /* __KERNEL__ */
#endif /* _PPC64_PSERIES_RECONFIG_H */
+25 −28
Original line number Diff line number Diff line
@@ -132,34 +132,6 @@ static int iseries_lparcfg_data(struct seq_file *m, void *v)
/*
 * Methods used to fetch LPAR data when running on a pSeries platform.
 */
/**
 * h_get_mpp
 * H_GET_MPP hcall returns info in 7 parms
 */
int h_get_mpp(struct hvcall_mpp_data *mpp_data)
{
	int rc;
	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];

	rc = plpar_hcall9(H_GET_MPP, retbuf);

	mpp_data->entitled_mem = retbuf[0];
	mpp_data->mapped_mem = retbuf[1];

	mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
	mpp_data->pool_num = retbuf[2] & 0xffff;

	mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
	mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
	mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;

	mpp_data->pool_size = retbuf[4];
	mpp_data->loan_request = retbuf[5];
	mpp_data->backing_mem = retbuf[6];

	return rc;
}
EXPORT_SYMBOL(h_get_mpp);

struct hvcall_ppp_data {
	u64	entitlement;
@@ -345,6 +317,30 @@ static void parse_mpp_data(struct seq_file *m)
	seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
}

/**
 * parse_mpp_x_data
 * Parse out data returned from h_get_mpp_x
 */
static void parse_mpp_x_data(struct seq_file *m)
{
	struct hvcall_mpp_x_data mpp_x_data;

	if (!firmware_has_feature(FW_FEATURE_XCMO))
		return;
	if (h_get_mpp_x(&mpp_x_data))
		return;

	seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes);

	if (mpp_x_data.pool_coalesced_bytes)
		seq_printf(m, "pool_coalesced_bytes=%ld\n",
			   mpp_x_data.pool_coalesced_bytes);
	if (mpp_x_data.pool_purr_cycles)
		seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles);
	if (mpp_x_data.pool_spurr_cycles)
		seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
}

#define SPLPAR_CHARACTERISTICS_TOKEN 20
#define SPLPAR_MAXLENGTH 1026*(sizeof(char))

@@ -520,6 +516,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
		parse_system_parameter_string(m);
		parse_ppp_data(m);
		parse_mpp_data(m);
		parse_mpp_x_data(m);
		pseries_cmo_data(m);
		splpar_dispatch_data(m);

+3 −1
Original line number Diff line number Diff line
@@ -700,8 +700,10 @@ static void __init early_cmdline_parse(void)
#endif /* CONFIG_PCI_MSI */
#ifdef CONFIG_PPC_SMLPAR
#define OV5_CMO			0x80	/* Cooperative Memory Overcommitment */
#define OV5_XCMO			0x40	/* Page Coalescing */
#else
#define OV5_CMO			0x00
#define OV5_XCMO			0x00
#endif
#define OV5_TYPE1_AFFINITY	0x80	/* Type 1 NUMA affinity */

@@ -756,7 +758,7 @@ static unsigned char ibm_architecture_vec[] = {
	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
	OV5_DONATE_DEDICATE_CPU | OV5_MSI,
	0,
	OV5_CMO,
	OV5_CMO | OV5_XCMO,
	OV5_TYPE1_AFFINITY,
	0,
	0,
Loading