Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1456884 > unrolled thread

[PATCH 2/2] powerpc/pseries: Dynamically increase RMA size

Started bySukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
First post2016-08-05 08:20 +0200
Last post2016-08-09 19:20 +0200
Articles 5 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> - 2016-08-05 08:20 +0200
    Re: [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size kbuild test robot <lkp@intel.com> - 2016-08-05 15:40 +0200
    Re: [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> - 2016-08-05 20:40 +0200
      Re: [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size Paul Clarke <pc@us.ibm.com> - 2016-08-05 21:10 +0200
        Re: [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> - 2016-08-09 19:20 +0200

#1456884 — [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size

FromSukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date2016-08-05 08:20 +0200
Subject[PATCH 2/2] powerpc/pseries: Dynamically increase RMA size
Message-ID<s2GEa-3O1-3@gated-at.bofh.it>
From ddce2a5f439111f08969d66ccc0c7b4d9196b69d Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 23:13:37 -0400
Subject: [PATCH 2/2] powerpc/pseries: Dynamically increase RMA size

When booting a very large system with a large initrd we run out of space
for the flattened device tree (FDT). To fix this we must increase the
space allocated for the RMA region.

The RMA size is hard-coded in the 'ibm_architecture_vec[]' and increasing
the size there will apply to all systems, large and small, so we want to
increase the RMA region only when necessary.

When we run out of room for the FDT, set a new OF property, 'ibm,new-rma-size'
to the new RMA size (512MB) and issue a client-architecture-support (CAS)
call to the firmware. This will initiate a system reboot. Upon reboot we
notice the new property and update the RMA size accordingly.

The CAS call we issue would end up being a second CAS call in the boot
sequence. Use a static variable, 'fixup_nr_cores_done', to detect this
second CAS and avoid fixing up nr_cores or hitting the WARNING again.

Fix suggested by Michael Ellerman.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/prom_init.c | 86 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index f612a99..407cbb9 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -679,6 +679,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffffffff),			/* virt_base */
 	W(0xffffffff),			/* virt_size */
 	W(0xffffffff),			/* load_base */
+#define IBM_ARCH_VEC_MIN_RMA_OFFSET	108
 	W(256),				/* 256MB min RMA */
 	W(0xffffffff),			/* full client load */
 	0,				/* min RMA percentage of total RAM */
@@ -867,6 +868,10 @@ static void fixup_nr_cores(void)
 {
 	u32 cores;
 	unsigned char *ptcores;
+	static bool fixup_nr_cores_done = false;
+
+	if (fixup_nr_cores_done)
+		return;
 
 	/* We need to tell the FW about the number of cores we support.
 	 *
@@ -898,6 +903,41 @@ static void fixup_nr_cores(void)
 		ptcores[1] = (cores >> 16) & 0xff;
 		ptcores[2] = (cores >> 8) & 0xff;
 		ptcores[3] = cores & 0xff;
+		fixup_nr_cores_done = true;
+	}
+}
+
+static void __init fixup_rma_size(void)
+{
+	int rc;
+	u64 size;
+	unsigned char *min_rmap;
+	phandle optnode;
+	char str[64];
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If a prior boot specified a new RMA size, use that size in
+	 * ibm_architecture_vec[]. See also increase_rma_size().
+	 */
+	size = 0ULL;
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
+	if (rc <= 0)
+		return;
+
+	size = prom_strtoul(str, NULL);
+	min_rmap = &ibm_architecture_vec[IBM_ARCH_VEC_MIN_RMA_OFFSET];
+
+	if (size) {
+		prom_printf("Using RMA size %lu from ibm,new-rma-size.\n", size);
+		min_rmap[0] = (size >> 24) & 0xff;
+		min_rmap[1] = (size >> 16) & 0xff;
+		min_rmap[2] = (size >> 8) & 0xff;
+		min_rmap[3] = size & 0xff;
 	}
 }
 
@@ -911,6 +951,8 @@ static void __init prom_send_capabilities(void)
 
 		fixup_nr_cores();
 
+		fixup_rma_size();
+
 		/* try calling the ibm,client-architecture-support method */
 		prom_printf("Calling ibm,client-architecture-support...");
 		if (call_prom_ret("call-method", 3, 2, &ret,
@@ -946,6 +988,46 @@ static void __init prom_send_capabilities(void)
 	}
 #endif /* __BIG_ENDIAN__ */
 }
+
+static void __init increase_rma_size(void)
+{
+	int rc;
+	u64 size;
+	char str[64];
+	phandle optnode;
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If we already increased the RMA size, return.
+	 */
+	size = 0ULL;
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
+
+	size = prom_strtoul(str, NULL);
+	if (size == 512ULL) {
+		prom_printf("RMA size already at %lu.\n", size);
+		return;
+	}
+	/*
+	 * Otherwise, set the ibm,new-rma-size property and initiate a CAS
+	 * reboot so the RMA size can take effect. See also init_rma_size().
+	 */
+	memset(str, 0, 4);
+	memcpy(str, "512", 3);
+	prom_printf("Setting ibm,new-rma-size property to %s\n", str);
+	rc = prom_setprop(optnode, "/options", "ibm,new-rma-size", &str,
+					strlen(str)+1);
+
+	/* Force a reboot. Will work only if ibm,fw-override-cas==false */
+	prom_send_capabilities();
+
+	prom_printf("No CAS initiated reboot? Try setting ibm,fw-override-cas to 'false' in Open Firmware\n");
+}
+
 #endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 
 /*
@@ -2027,9 +2109,11 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
 		room = alloc_top - alloc_bottom;
 		if (room > DEVTREE_CHUNK_SIZE)
 			room = DEVTREE_CHUNK_SIZE;
-		if (room < PAGE_SIZE)
+		if (room < PAGE_SIZE) {
+			increase_rma_size();
 			prom_panic("No memory for flatten_device_tree "
 				   "(no room)\n");
+		}
 		chunk = alloc_up(room, 0);
 		if (chunk == 0)
 			prom_panic("No memory for flatten_device_tree "
-- 
1.8.3.1

[toc] | [next] | [standalone]


#1457097

Fromkbuild test robot <lkp@intel.com>
Date2016-08-05 15:40 +0200
Message-ID<s2NvX-89z-5@gated-at.bofh.it>
In reply to#1456884

[Multipart message — attachments visible in raw view] — view raw

Hi Sukadev,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.7 next-20160805]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Sukadev-Bhattiprolu/powerpc-pseries-Use-a-helper-to-fixup-nr_cores/20160805-141813
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-kmeter1_defconfig (attached as .config)
compiler: powerpc-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/prom_init.c: In function 'make_room':
>> arch/powerpc/kernel/prom_init.c:2113:4: error: implicit declaration of function 'increase_rma_size' [-Werror=implicit-function-declaration]
       increase_rma_size();
       ^
   cc1: all warnings being treated as errors

vim +/increase_rma_size +2113 arch/powerpc/kernel/prom_init.c

  2107			prom_debug("Chunk exhausted, claiming more at %x...\n",
  2108				   alloc_bottom);
  2109			room = alloc_top - alloc_bottom;
  2110			if (room > DEVTREE_CHUNK_SIZE)
  2111				room = DEVTREE_CHUNK_SIZE;
  2112			if (room < PAGE_SIZE) {
> 2113				increase_rma_size();
  2114				prom_panic("No memory for flatten_device_tree "
  2115					   "(no room)\n");
  2116			}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [next] | [standalone]


#1457239

FromSukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date2016-08-05 20:40 +0200
Message-ID<s2Sci-2Ir-21@gated-at.bofh.it>
In reply to#1456884
Here is an updated patch to fix the build when CONFIG_PPC_PSERIES=n.
---
From d4f77a6ca7b6ea83f6588e7d541cc70bf001ae85 Mon Sep 17 00:00:00 2001
From: root <sukadev@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 23:13:37 -0400
Subject: [PATCH 2/2] powerpc/pseries: Dynamically grow RMA size

When booting a very large system with a larg initrd we run out of space
for the flattened device tree (FDT). To fix this we must increase the
space allocated for the RMA region.

The RMA size is hard-coded in the 'ibm_architecture_vec[]' and increasing
the size there will apply to all systems, small and large, so we want to
increase the RMA region only when necessary.

When we run out of room for the FDT, set a new OF property, 'ibm,new-rma-size'
to the new RMA size (512MB) and issue a client-architecture-support (CAS)
call to the firmware. This will initiate a system reboot. Upon reboot we
notice the new property and update the RMA size accordingly.

Fix suggested by Michael Ellerman.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---

[v2]:	- Add a comment in code regarding 'fixup_nr_cores_done'
	- Fix build break when CONFIG_PPC_PSERIES=n
---
 arch/powerpc/kernel/prom_init.c | 96 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index f612a99..cbd5387 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -679,6 +679,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffffffff),			/* virt_base */
 	W(0xffffffff),			/* virt_size */
 	W(0xffffffff),			/* load_base */
+#define IBM_ARCH_VEC_MIN_RMA_OFFSET	108
 	W(256),				/* 256MB min RMA */
 	W(0xffffffff),			/* full client load */
 	0,				/* min RMA percentage of total RAM */
@@ -867,6 +868,14 @@ static void fixup_nr_cores(void)
 {
 	u32 cores;
 	unsigned char *ptcores;
+	static bool fixup_nr_cores_done = false;
+
+	/*
+	 * If this is a second CAS call in the same boot sequence, (see
+	 * increase_rma_size()), we don't need to do the fixup again.
+	 */
+	if (fixup_nr_cores_done)
+		return;
 
 	/* We need to tell the FW about the number of cores we support.
 	 *
@@ -898,6 +907,41 @@ static void fixup_nr_cores(void)
 		ptcores[1] = (cores >> 16) & 0xff;
 		ptcores[2] = (cores >> 8) & 0xff;
 		ptcores[3] = cores & 0xff;
+		fixup_nr_cores_done = true;
+	}
+}
+
+static void __init fixup_rma_size(void)
+{
+	int rc;
+	u64 size;
+	unsigned char *min_rmap;
+	phandle optnode;
+	char str[64];
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If a prior boot specified a new RMA size, use that size in
+	 * ibm_architecture_vec[]. See also increase_rma_size().
+	 */
+	size = 0ULL;
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
+	if (rc <= 0)
+		return;
+
+	size = prom_strtoul(str, NULL);
+	min_rmap = &ibm_architecture_vec[IBM_ARCH_VEC_MIN_RMA_OFFSET];
+
+	if (size) {
+		prom_printf("Using RMA size %lu from ibm,new-rma-size.\n", size);
+		min_rmap[0] = (size >> 24) & 0xff;
+		min_rmap[1] = (size >> 16) & 0xff;
+		min_rmap[2] = (size >> 8) & 0xff;
+		min_rmap[3] = size & 0xff;
 	}
 }
 
@@ -911,6 +955,8 @@ static void __init prom_send_capabilities(void)
 
 		fixup_nr_cores();
 
+		fixup_rma_size();
+
 		/* try calling the ibm,client-architecture-support method */
 		prom_printf("Calling ibm,client-architecture-support...");
 		if (call_prom_ret("call-method", 3, 2, &ret,
@@ -946,6 +992,52 @@ static void __init prom_send_capabilities(void)
 	}
 #endif /* __BIG_ENDIAN__ */
 }
+
+static void __init increase_rma_size(void)
+{
+	int rc;
+	u64 size;
+	char str[64];
+	phandle optnode;
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If we already increased the RMA size, return.
+	 */
+	size = 0ULL;
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
+
+	size = prom_strtoul(str, NULL);
+	if (size == 512ULL) {
+		prom_printf("RMA size already at %lu.\n", size);
+		return;
+	}
+	/*
+	 * Otherwise, set the ibm,new-rma-size property and initiate a CAS
+	 * reboot so the RMA size can take effect. See also init_rma_size().
+	 */
+	memset(str, 0, 4);
+	memcpy(str, "512", 3);
+	prom_printf("Setting ibm,new-rma-size property to %s\n", str);
+	rc = prom_setprop(optnode, "/options", "ibm,new-rma-size", &str,
+					strlen(str)+1);
+
+	/* Force a reboot. Will work only if ibm,fw-override-cas==false */
+	prom_send_capabilities();
+
+	prom_printf("No CAS initiated reboot? Try setting ibm,fw-override-cas to 'false' in Open Firmware\n");
+}
+
+#else
+
+static void __init increase_rma_size(void)
+{
+}
+
 #endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 
 /*
@@ -2027,9 +2119,11 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
 		room = alloc_top - alloc_bottom;
 		if (room > DEVTREE_CHUNK_SIZE)
 			room = DEVTREE_CHUNK_SIZE;
-		if (room < PAGE_SIZE)
+		if (room < PAGE_SIZE) {
+			increase_rma_size();
 			prom_panic("No memory for flatten_device_tree "
 				   "(no room)\n");
+		}
 		chunk = alloc_up(room, 0);
 		if (chunk == 0)
 			prom_panic("No memory for flatten_device_tree "
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1457251

FromPaul Clarke <pc@us.ibm.com>
Date2016-08-05 21:10 +0200
Message-ID<s2SFj-3aN-1@gated-at.bofh.it>
In reply to#1457239
Only nits from me...(see below)

On 08/05/2016 01:30 PM, Sukadev Bhattiprolu wrote:
> Here is an updated patch to fix the build when CONFIG_PPC_PSERIES=n.
> ---
> From d4f77a6ca7b6ea83f6588e7d541cc70bf001ae85 Mon Sep 17 00:00:00 2001
> From: root <sukadev@linux.vnet.ibm.com>
> Date: Thu, 4 Aug 2016 23:13:37 -0400
> Subject: [PATCH 2/2] powerpc/pseries: Dynamically grow RMA size
>
> When booting a very large system with a larg initrd we run out of space
> for the flattened device tree (FDT). To fix this we must increase the
> space allocated for the RMA region.
>
> The RMA size is hard-coded in the 'ibm_architecture_vec[]' and increasing
> the size there will apply to all systems, small and large, so we want to
> increase the RMA region only when necessary.
>
> When we run out of room for the FDT, set a new OF property, 'ibm,new-rma-size'
> to the new RMA size (512MB) and issue a client-architecture-support (CAS)
> call to the firmware. This will initiate a system reboot. Upon reboot we
> notice the new property and update the RMA size accordingly.
>
> Fix suggested by Michael Ellerman.
>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
>
> [v2]:	- Add a comment in code regarding 'fixup_nr_cores_done'
> 	- Fix build break when CONFIG_PPC_PSERIES=n
> ---
>  arch/powerpc/kernel/prom_init.c | 96 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index f612a99..cbd5387 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -679,6 +679,7 @@ unsigned char ibm_architecture_vec[] = {
>  	W(0xffffffff),			/* virt_base */
>  	W(0xffffffff),			/* virt_size */
>  	W(0xffffffff),			/* load_base */
> +#define IBM_ARCH_VEC_MIN_RMA_OFFSET	108
>  	W(256),				/* 256MB min RMA */
>  	W(0xffffffff),			/* full client load */
>  	0,				/* min RMA percentage of total RAM */
> @@ -867,6 +868,14 @@ static void fixup_nr_cores(void)
>  {
>  	u32 cores;
>  	unsigned char *ptcores;
> +	static bool fixup_nr_cores_done = false;
> +
> +	/*
> +	 * If this is a second CAS call in the same boot sequence, (see
> +	 * increase_rma_size()), we don't need to do the fixup again.
> +	 */
> +	if (fixup_nr_cores_done)
> +		return;
>
>  	/* We need to tell the FW about the number of cores we support.
>  	 *
> @@ -898,6 +907,41 @@ static void fixup_nr_cores(void)
>  		ptcores[1] = (cores >> 16) & 0xff;
>  		ptcores[2] = (cores >> 8) & 0xff;
>  		ptcores[3] = cores & 0xff;
> +		fixup_nr_cores_done = true;
> +	}
> +}
> +
> +static void __init fixup_rma_size(void)
> +{
> +	int rc;
> +	u64 size;
> +	unsigned char *min_rmap;
> +	phandle optnode;
> +	char str[64];
> +
> +	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
> +	if (!PHANDLE_VALID(optnode))
> +		prom_panic("Cannot find /options");
> +
> +	/*
> +	 * If a prior boot specified a new RMA size, use that size in
> +	 * ibm_architecture_vec[]. See also increase_rma_size().
> +	 */
> +	size = 0ULL;
> +	memset(str, 0, sizeof(str));
> +	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
> +	if (rc <= 0)
> +		return;
> +
> +	size = prom_strtoul(str, NULL);
> +	min_rmap = &ibm_architecture_vec[IBM_ARCH_VEC_MIN_RMA_OFFSET];
> +
> +	if (size) {
> +		prom_printf("Using RMA size %lu from ibm,new-rma-size.\n", size);
> +		min_rmap[0] = (size >> 24) & 0xff;
> +		min_rmap[1] = (size >> 16) & 0xff;
> +		min_rmap[2] = (size >> 8) & 0xff;
> +		min_rmap[3] = size & 0xff;
>  	}
>  }
>
> @@ -911,6 +955,8 @@ static void __init prom_send_capabilities(void)
>
>  		fixup_nr_cores();
>
> +		fixup_rma_size();
> +
>  		/* try calling the ibm,client-architecture-support method */
>  		prom_printf("Calling ibm,client-architecture-support...");
>  		if (call_prom_ret("call-method", 3, 2, &ret,
> @@ -946,6 +992,52 @@ static void __init prom_send_capabilities(void)
>  	}
>  #endif /* __BIG_ENDIAN__ */
>  }
> +
> +static void __init increase_rma_size(void)
> +{
> +	int rc;
> +	u64 size;
> +	char str[64];
> +	phandle optnode;
> +
> +	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
> +	if (!PHANDLE_VALID(optnode))
> +		prom_panic("Cannot find /options");
> +
> +	/*
> +	 * If we already increased the RMA size, return.
> +	 */
> +	size = 0ULL;
> +	memset(str, 0, sizeof(str));
> +	rc = prom_getprop(optnode, "ibm,new-rma-size", &str, sizeof(str));
> +
> +	size = prom_strtoul(str, NULL);
> +	if (size == 512ULL) {

Is this preferred over strncmp?  Using a string also helps with my suggestion below...

> +		prom_printf("RMA size already at %lu.\n", size);
> +		return;
> +	}
> +	/*
> +	 * Otherwise, set the ibm,new-rma-size property and initiate a CAS
> +	 * reboot so the RMA size can take effect. See also init_rma_size().
> +	 */
> +	memset(str, 0, 4);
> +	memcpy(str, "512", 3);

There's a "512" here and a few lines above.  Would it be better to define the magic value once somewhere, then use that common name as needed?

The string "ibm,new-rma-size" is used in a number of places, too.  (I'm just saying that if it changes, you'd need to go back and find them all.)

Also, instead of memset/memcpy, why not:
memcpy(str, "512", 4);

> +	prom_printf("Setting ibm,new-rma-size property to %s\n", str);
> +	rc = prom_setprop(optnode, "/options", "ibm,new-rma-size", &str,
> +					strlen(str)+1);
> +
> +	/* Force a reboot. Will work only if ibm,fw-override-cas==false */
> +	prom_send_capabilities();
> +
> +	prom_printf("No CAS initiated reboot? Try setting ibm,fw-override-cas to 'false' in Open Firmware\n");
> +}
> +
> +#else
> +
> +static void __init increase_rma_size(void)
> +{
> +}
> +
>  #endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
>
>  /*
> @@ -2027,9 +2119,11 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
>  		room = alloc_top - alloc_bottom;
>  		if (room > DEVTREE_CHUNK_SIZE)
>  			room = DEVTREE_CHUNK_SIZE;
> -		if (room < PAGE_SIZE)
> +		if (room < PAGE_SIZE) {
> +			increase_rma_size();
>  			prom_panic("No memory for flatten_device_tree "
>  				   "(no room)\n");
> +		}
>  		chunk = alloc_up(room, 0);
>  		if (chunk == 0)
>  			prom_panic("No memory for flatten_device_tree "
>
--
PC

[toc] | [prev] | [next] | [standalone]


#1459010

FromSukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date2016-08-09 19:20 +0200
Message-ID<s4iR4-24N-23@gated-at.bofh.it>
In reply to#1457251
Paul Clarke [pc@us.ibm.com] wrote:
> Only nits from me...(see below)

Paul,

I agree with your comments and fixed them. Here is the updated patch.

---

From f9e9e8460206bc3fa7eaa741b9a2bde22870b9e0 Mon Sep 17 00:00:00 2001
From: root <sukadev@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 23:13:37 -0400
Subject: [PATCH 2/2] powerpc/pseries: Dynamically grow RMA size

When booting a very large system with a large initrd we run out of space
for the flattened device tree (FDT). To fix this we must increase the
space allocated for the RMA region.

The RMA size is hard-coded in the 'ibm_architecture_vec[]' and increasing
the size there will apply to all systems, large and small, so we want to
increase the RMA region only when necessary.

When we run out of room for the FDT, set a new OF property, 'ibm,new-rma-size'
to the new RMA size (512MB) and issue a client-architecture-support (CAS)
call to the firmware. This will initiate a system reboot. Upon reboot we
notice the new property and update the RMA size accordingly.

Fix suggested by Michael Ellerman.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---

[v3]:	- [Paul Clarke] Fix a few nits.

[v2]:	- Add a comment in code regarding 'fixup_nr_cores_done'
	- Fix build break when CONFIG_PPC_PSERIES=n
---
 arch/powerpc/kernel/prom_init.c | 97 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index f612a99..d1aaeda 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -87,6 +87,9 @@
 int of_workarounds;
 #endif
 
+#define IBM_NEW_RMA_SIZE_PROP	"ibm,new-rma-size"
+#define IBM_NEW_RMA_SIZE_STR	"512"
+
 #define OF_WA_CLAIM	1	/* do phys/virt claim separately, then map */
 #define OF_WA_LONGTRAIL	2	/* work around longtrail bugs */
 
@@ -679,6 +682,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffffffff),			/* virt_base */
 	W(0xffffffff),			/* virt_size */
 	W(0xffffffff),			/* load_base */
+#define IBM_ARCH_VEC_MIN_RMA_OFFSET	108
 	W(256),				/* 256MB min RMA */
 	W(0xffffffff),			/* full client load */
 	0,				/* min RMA percentage of total RAM */
@@ -867,6 +871,14 @@ static void fixup_nr_cores(void)
 {
 	u32 cores;
 	unsigned char *ptcores;
+	static bool fixup_nr_cores_done = false;
+
+	/*
+	 * If this is a second CAS call in the same boot sequence, (see
+	 * increase_rma_size()), we don't need to do the fixup again.
+	 */
+	if (fixup_nr_cores_done)
+		return;
 
 	/* We need to tell the FW about the number of cores we support.
 	 *
@@ -898,6 +910,42 @@ static void fixup_nr_cores(void)
 		ptcores[1] = (cores >> 16) & 0xff;
 		ptcores[2] = (cores >> 8) & 0xff;
 		ptcores[3] = cores & 0xff;
+		fixup_nr_cores_done = true;
+	}
+}
+
+static void __init fixup_rma_size(void)
+{
+	int rc;
+	u64 size;
+	unsigned char *min_rmap;
+	phandle optnode;
+	char str[64];
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If a prior boot specified a new RMA size, use that size in
+	 * ibm_architecture_vec[]. See also increase_rma_size().
+	 */
+	size = 0ULL;
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, IBM_NEW_RMA_SIZE_PROP, &str, sizeof(str));
+	if (rc <= 0)
+		return;
+
+	size = prom_strtoul(str, NULL);
+	min_rmap = &ibm_architecture_vec[IBM_ARCH_VEC_MIN_RMA_OFFSET];
+
+	if (size) {
+		prom_printf("Using RMA size %lu from %s.\n", size,
+						IBM_NEW_RMA_SIZE_PROP);
+		min_rmap[0] = (size >> 24) & 0xff;
+		min_rmap[1] = (size >> 16) & 0xff;
+		min_rmap[2] = (size >> 8) & 0xff;
+		min_rmap[3] = size & 0xff;
 	}
 }
 
@@ -911,6 +959,8 @@ static void __init prom_send_capabilities(void)
 
 		fixup_nr_cores();
 
+		fixup_rma_size();
+
 		/* try calling the ibm,client-architecture-support method */
 		prom_printf("Calling ibm,client-architecture-support...");
 		if (call_prom_ret("call-method", 3, 2, &ret,
@@ -946,6 +996,49 @@ static void __init prom_send_capabilities(void)
 	}
 #endif /* __BIG_ENDIAN__ */
 }
+
+static void __init increase_rma_size(void)
+{
+	int rc, len;
+	char str[64];
+	phandle optnode;
+
+	optnode = call_prom("finddevice", 1, 1, ADDR("/options"));
+	if (!PHANDLE_VALID(optnode))
+		prom_panic("Cannot find /options");
+
+	/*
+	 * If we already increased the RMA size, return.
+	 */
+	memset(str, 0, sizeof(str));
+	rc = prom_getprop(optnode, IBM_NEW_RMA_SIZE_PROP, &str, sizeof(str));
+
+	if (!strcmp(str, IBM_NEW_RMA_SIZE_STR)) {
+		prom_printf("RMA size already at %.3s.\n", str);
+		return;
+	}
+	/*
+	 * Otherwise, set the ibm,new-rma-size property and initiate a CAS
+	 * reboot so the RMA size can take effect. See also init_rma_size().
+	 */
+	len = strlen(IBM_NEW_RMA_SIZE_STR) + 1;
+	memcpy(str, IBM_NEW_RMA_SIZE_STR, len);
+
+	prom_printf("Setting %s property to %s\n", IBM_NEW_RMA_SIZE_PROP, str);
+	rc = prom_setprop(optnode, "/options", IBM_NEW_RMA_SIZE_PROP, str, len);
+
+	/* Force a reboot. Will work only if ibm,fw-override-cas==false */
+	prom_send_capabilities();
+
+	prom_printf("No CAS initiated reboot? Try setting ibm,fw-override-cas to 'false' in Open Firmware\n");
+}
+
+#else
+
+static void __init increase_rma_size(void)
+{
+}
+
 #endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 
 /*
@@ -2027,9 +2120,11 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
 		room = alloc_top - alloc_bottom;
 		if (room > DEVTREE_CHUNK_SIZE)
 			room = DEVTREE_CHUNK_SIZE;
-		if (room < PAGE_SIZE)
+		if (room < PAGE_SIZE) {
+			increase_rma_size();
 			prom_panic("No memory for flatten_device_tree "
 				   "(no room)\n");
+		}
 		chunk = alloc_up(room, 0);
 		if (chunk == 0)
 			prom_panic("No memory for flatten_device_tree "
-- 
1.8.3.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web