[PATCH 0/3] powerpc: cmo fix page loaning and add info to lparcfg
From: Robert Jennings <hidden>
Date: 2008-08-15 20:09:02
Subsystems: linux for powerpc (32-bit and 64-bit), the rest · Maintainers: Madhavan Srinivasan, Linus Torvalds
Series: 3 patches touching 4 files
6 messages, 2 authors, 2008-08-18 · open the first message on its own page
From: Robert Jennings <hidden>
Date: 2008-08-15 20:09:02
We need to correct a problem found where the kernel is using 64k pages but the firmware pages size is 4k. In this case we were not properly marking pages as 'loaned' to firmware. To fix this I exposed some data pulled from rtas during early setup. I also made these values available via /proc/ppc64/lparcfg in the second patch. The first patch makes the data available and the other two patches (unrelated to each other) depend on the first. Regards, Robert Jennings
From: Robert Jennings <hidden>
Date: 2008-08-15 20:17:37
During platform setup, save off the primary/secondary paging space pool IDs and the page size. Added accessors in hvcall.h for these variables. Submitted-by: Robert Jennings [off-list ref] --- arch/powerpc/include/asm/hvcall.h | 21 +++++++++++++++++++++ arch/powerpc/platforms/pseries/setup.c | 28 ++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 8 deletions(-) Index: b/arch/powerpc/include/asm/hvcall.h ===================================================================
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h@@ -292,6 +292,27 @@ struct hvcall_mpp_data { int h_get_mpp(struct hvcall_mpp_data *); +#ifdef CONFIG_PPC_PSERIES +extern int CMO_PrPSP; +extern int CMO_SecPSP; +extern unsigned long CMO_PageSize; + +static inline int cmo_get_primary_psp(void) +{ + return CMO_PrPSP; +} + +static inline int cmo_get_secondary_psp(void) +{ + return CMO_SecPSP; +} + +static inline unsigned long cmo_get_page_size(void) +{ + return CMO_PageSize; +} +#endif /* CONFIG_PPC_PSERIES */ + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */
Index: b/arch/powerpc/platforms/pseries/setup.c ===================================================================
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c@@ -68,6 +68,9 @@ #include "plpar_wrappers.h" #include "pseries.h" +int CMO_PrPSP = -1; +int CMO_SecPSP = -1; +unsigned long CMO_PageSize = (ASM_CONST(1) << IOMMU_PAGE_SHIFT); int fwnmi_active; /* TRUE if an FWNMI handler is present */
@@ -325,8 +328,7 @@ void pSeries_cmo_feature_init(void) { char *ptr, *key, *value, *end; int call_status; - int PrPSP = -1; - int SecPSP = -1; + int page_order = IOMMU_PAGE_SHIFT; pr_debug(" -> fw_cmo_feature_init()\n"); spin_lock(&rtas_data_buf_lock);
@@ -365,21 +367,31 @@ void pSeries_cmo_feature_init(void) break; } - if (0 == strcmp(key, "PrPSP")) - PrPSP = simple_strtol(value, NULL, 10); + if (0 == strcmp(key, "CMOPageSize")) + page_order = simple_strtol(value, NULL, 10); + else if (0 == strcmp(key, "PrPSP")) + CMO_PrPSP = simple_strtol(value, NULL, 10); else if (0 == strcmp(key, "SecPSP")) - SecPSP = simple_strtol(value, NULL, 10); + CMO_SecPSP = simple_strtol(value, NULL, 10); value = key = ptr + 1; } ptr++; } - if (PrPSP != -1 || SecPSP != -1) { + /* Page size is returned as the power of 2 of the page size, + * convert to the page size in bytes before returning + */ + CMO_PageSize = 1 << page_order; + pr_debug("CMO_PageSize = %lu\n", CMO_PageSize); + + if (CMO_PrPSP != -1 || CMO_SecPSP != -1) { pr_info("CMO enabled\n"); - pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); powerpc_firmware_features |= FW_FEATURE_CMO; } else - pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); spin_unlock(&rtas_data_buf_lock); pr_debug(" <- fw_cmo_feature_init()\n"); }
From: Robert Jennings <hidden>
Date: 2008-08-15 20:18:24
=46rom: Brian King [off-list ref] If the firmware page size used for collaborative memory overcommit is 4k, but the kernel is using 64k pages, the page loaning is currently broken as it only marks the first 4k page of each 64k page as loaned. This fixes this to iterate through each 4k page and mark them all as loaned/active. Signed-off-by: Brian King <redacted> Signed-off-by: Robert Jennings <redacted> --- arch/powerpc/platforms/pseries/plpar_wrappers.h | 27 +++++++++++++++++++= +++-- 1 file changed, 25 insertions(+), 2 deletions(-) Index: b/arch/powerpc/platforms/pseries/plpar_wrappers.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h@@ -2,6 +2,7 @@ #define _PSERIES_PLPAR_WRAPPERS_H
=20
#include <asm/hvcall.h>
+#include <asm/page.h>
=20
static inline long poll_pending(void)
{@@ -44,12 +45,34 @@ static inline long register_slb_shadow(u=20
static inline long plpar_page_set_loaned(unsigned long vpa)
{
- return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa, 0);
+ unsigned long cmo_page_sz =3D cmo_get_page_size();
+ long rc =3D 0;
+ int i;
+
+ for (i =3D 0; !rc && i < PAGE_SIZE; i +=3D cmo_page_sz)
+ rc =3D plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
+
+ for (i -=3D cmo_page_sz; rc && i !=3D 0; i -=3D cmo_page_sz)
+ plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
+ vpa + i - cmo_page_sz, 0);
+
+ return rc;
}
=20
static inline long plpar_page_set_active(unsigned long vpa)
{
- return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa, 0);
+ unsigned long cmo_page_sz =3D cmo_get_page_size();
+ long rc =3D 0;
+ int i;
+
+ for (i =3D 0; !rc && i < PAGE_SIZE; i +=3D cmo_page_sz)
+ rc =3D plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
+
+ for (i -=3D cmo_page_sz; rc && i !=3D 0; i -=3D cmo_page_sz)
+ plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
+ vpa + i - cmo_page_sz, 0);
+
+ return rc;
}
=20
extern void vpa_init(int cpu);
From: Robert Jennings <hidden>
Date: 2008-08-15 20:21:53
Add a field in lparcfg output to indicate whether the kernel is running on a dedicated or shared memory lpar. Added fields to show the paging space pool IDs and the CMO page size. Submitted-by: Robert Jennings [off-list ref] --- arch/powerpc/kernel/lparcfg.c | 5 +++++ 1 file changed, 5 insertions(+) Index: b/arch/powerpc/kernel/lparcfg.c ===================================================================
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c@@ -416,6 +416,8 @@ static void pseries_cmo_data(struct seq_ unsigned long cmo_faults = 0; unsigned long cmo_fault_time = 0; + seq_printf(m, "cmo_enabled=%d\n", firmware_has_feature(FW_FEATURE_CMO)); + if (!firmware_has_feature(FW_FEATURE_CMO)) return;
@@ -427,6 +429,9 @@ static void pseries_cmo_data(struct seq_ seq_printf(m, "cmo_faults=%lu\n", cmo_faults); seq_printf(m, "cmo_fault_time_usec=%lu\n", cmo_fault_time / tb_ticks_per_usec); + seq_printf(m, "cmo_primary_psp=%d\n", cmo_get_primary_psp()); + seq_printf(m, "cmo_secondary_psp=%d\n", cmo_get_secondary_psp()); + seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size()); } static int pseries_lparcfg_data(struct seq_file *m, void *v)
From: Paul Mackerras <hidden>
Date: 2008-08-18 00:18:05
Robert Jennings writes:
During platform setup, save off the primary/secondary paging space pool IDs and the page size. Added accessors in hvcall.h for these variables. Submitted-by: Robert Jennings [off-list ref]
What's this "Submitted-by"? Did you mean to type "Signed-off-by"? Paul.
From: Robert Jennings <hidden>
Date: 2008-08-18 14:40:34
During platform setup, save off the primary/secondary paging space pool IDs and the page size. Added accessors in hvcall.h for these variables. Signed-off-by: Robert Jennings <redacted> --- I wrote "Submitted-by" on the last patch for some strange reason, that't the only thing changed here. --- arch/powerpc/include/asm/hvcall.h | 21 +++++++++++++++++++++ arch/powerpc/platforms/pseries/setup.c | 28 ++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 8 deletions(-) Index: b/arch/powerpc/include/asm/hvcall.h ===================================================================
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h@@ -292,6 +292,27 @@ struct hvcall_mpp_data { int h_get_mpp(struct hvcall_mpp_data *); +#ifdef CONFIG_PPC_PSERIES +extern int CMO_PrPSP; +extern int CMO_SecPSP; +extern unsigned long CMO_PageSize; + +static inline int cmo_get_primary_psp(void) +{ + return CMO_PrPSP; +} + +static inline int cmo_get_secondary_psp(void) +{ + return CMO_SecPSP; +} + +static inline unsigned long cmo_get_page_size(void) +{ + return CMO_PageSize; +} +#endif /* CONFIG_PPC_PSERIES */ + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */
Index: b/arch/powerpc/platforms/pseries/setup.c ===================================================================
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c@@ -68,6 +68,9 @@ #include "plpar_wrappers.h" #include "pseries.h" +int CMO_PrPSP = -1; +int CMO_SecPSP = -1; +unsigned long CMO_PageSize = (ASM_CONST(1) << IOMMU_PAGE_SHIFT); int fwnmi_active; /* TRUE if an FWNMI handler is present */
@@ -325,8 +328,7 @@ void pSeries_cmo_feature_init(void) { char *ptr, *key, *value, *end; int call_status; - int PrPSP = -1; - int SecPSP = -1; + int page_order = IOMMU_PAGE_SHIFT; pr_debug(" -> fw_cmo_feature_init()\n"); spin_lock(&rtas_data_buf_lock);
@@ -365,21 +367,31 @@ void pSeries_cmo_feature_init(void) break; } - if (0 == strcmp(key, "PrPSP")) - PrPSP = simple_strtol(value, NULL, 10); + if (0 == strcmp(key, "CMOPageSize")) + page_order = simple_strtol(value, NULL, 10); + else if (0 == strcmp(key, "PrPSP")) + CMO_PrPSP = simple_strtol(value, NULL, 10); else if (0 == strcmp(key, "SecPSP")) - SecPSP = simple_strtol(value, NULL, 10); + CMO_SecPSP = simple_strtol(value, NULL, 10); value = key = ptr + 1; } ptr++; } - if (PrPSP != -1 || SecPSP != -1) { + /* Page size is returned as the power of 2 of the page size, + * convert to the page size in bytes before returning + */ + CMO_PageSize = 1 << page_order; + pr_debug("CMO_PageSize = %lu\n", CMO_PageSize); + + if (CMO_PrPSP != -1 || CMO_SecPSP != -1) { pr_info("CMO enabled\n"); - pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); powerpc_firmware_features |= FW_FEATURE_CMO; } else - pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); spin_unlock(&rtas_data_buf_lock); pr_debug(" <- fw_cmo_feature_init()\n"); } ----- End forwarded message -----