Patchwork [03/15,PS3] Add region 1 memory early

login
register
mail settings
Submitter Andre Heider
Date Aug. 1, 2011, 8:02 p.m.
Message ID <1312228986-32307-4-git-send-email-a.heider@gmail.com>
Download mbox | patch
Permalink /patch/107801/
State Superseded
Headers show

Comments

Andre Heider - Aug. 1, 2011, 8:02 p.m.
From: Hector Martin <hector@marcansoft.com>

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/mm.c |   62 +++++++--------------------------------
 1 files changed, 11 insertions(+), 51 deletions(-)
Geoff Levand - Aug. 3, 2011, 10:32 p.m.
On 08/01/2011 01:02 PM, Andre Heider wrote:
> From: Hector Martin <hector@marcansoft.com>

We need an explanation of this change.

> Signed-off-by: Hector Martin <hector@marcansoft.com>
> [a.heider: Various cleanups to make checkpatch.pl happy]
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/mm.c |   62 +++++++--------------------------------
>  1 files changed, 11 insertions(+), 51 deletions(-)
Hector Martin - Aug. 4, 2011, 12:08 a.m.
On 08/04/2011 12:32 AM, Geoff Levand wrote:
> We need an explanation of this change.

I actually have a hard time understanding the reason for the existing
behavior of hot-adding memory halfway through the boot process. Maybe
you can shed some light on this?

The reason for the change is that under the default GameOS LPAR, real
mode memory is 16MB which is already tight for a kernel (under certain
conditions) and runs out quickly as memory is allocated during kernel
startup. Having region1 available sooner fixes this.

Though, reviewing the code, I think I found a bug (that should already
have a chance of happening as things stand now, though this patch might
make it more likely): if storage bounce buffers or the ps3fb xdr happen
to straddle the boundary between the regions, bad things will happen
since they're not actually contiguous in LPAR space. This won't happen
right now for ps3flash or ps3fb since those are allocated early out of
bootmem, but it can currently happen for the other buffers (ps3disk,
ps3vram, etc.) AFAICT.

Maybe we should introduce a reserved or nonexistent page gap at the
beginning of region1 to ensure that nothing will ever allocate
contiguous memory across the boundary. That will probably prevent
bootmem from grabbing region1 due to the gap, so early on memory will be
tight. Can we get rid of the ps3flash and ps3fb preallocations to save
bootmem and just allocate them during device init like the other drivers
do? What is the reason for preallocating these?
Geert Uytterhoeven - Aug. 4, 2011, 7:05 a.m.
On Thu, Aug 4, 2011 at 02:08, Hector Martin <hector@marcansoft.com> wrote:
> tight. Can we get rid of the ps3flash and ps3fb preallocations to save
> bootmem and just allocate them during device init like the other drivers
> do? What is the reason for preallocating these?

The reason for that is to make sure the allocations will succeed.
Chances are very
slim you can allocate a contiguous 9 MiB buffer at any arbitrary time.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Hector Martin - Aug. 4, 2011, 11:13 a.m.
On 08/04/2011 09:05 AM, Geert Uytterhoeven wrote:
> The reason for that is to make sure the allocations will succeed.
> Chances are very
> slim you can allocate a contiguous 9 MiB buffer at any arbitrary time.

Fair enough, but then they don't need to happen as early as they do now;
any time during kernel startup should work (as long as they aren't freed
with the drivers if they're unloaded). How about switching to
__get_free_pages and doing the allocation inside an arch_initcall or
similar?
Geoff Levand - Aug. 4, 2011, 3:57 p.m.
Hi Hector,

On 08/03/2011 05:08 PM, Hector Martin wrote:
> On 08/04/2011 12:32 AM, Geoff Levand wrote:
>> We need an explanation of this change.

Sorry for such a terse request.  What I meant was that
this is a significant change to how high mem is managed,
so the patch needs a comment explaining the change.

> I actually have a hard time understanding the reason for the existing
> behavior of hot-adding memory halfway through the boot process. Maybe
> you can shed some light on this?

LV1 was intended to be a generic hypervisor for the Cell
processor.  It was imagined that it could be used on machines
which could be running many lpars.  Around the same time I
was doing the high mem support the hot plug memory support was
being developed.  I thought at some point there would be
hot-unplug, which could be used to move memory between lpars.

At the present time this change make sense, since it is simpler
and more flexible.

-Geoff

Patch

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 30bb096..15876d6 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -331,57 +331,6 @@  static int ps3_mm_get_devtree_highmem(struct mem_region *r)
 	}
 }
 
-/**
- * ps3_mm_add_memory - hot add memory
- */
-
-static int __init ps3_mm_add_memory(void)
-{
-	int result;
-	unsigned long start_addr;
-	unsigned long start_pfn;
-	unsigned long nr_pages;
-
-	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
-		return -ENODEV;
-
-	BUG_ON(!mem_init_done);
-
-	if (!map.r1.size) {
-		DBG("%s:%d: no region 1, not adding memory\n",
-		    __func__, __LINE__);
-		return 0;
-	}
-
-	start_addr = map.rm.size;
-	start_pfn = start_addr >> PAGE_SHIFT;
-	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-	DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n",
-		__func__, __LINE__, start_addr, start_pfn, nr_pages);
-
-	result = add_memory(0, start_addr, map.r1.size);
-
-	if (result) {
-		pr_err("%s:%d: add_memory failed: (%d)\n",
-			__func__, __LINE__, result);
-		return result;
-	}
-
-	memblock_add(start_addr, map.r1.size);
-	memblock_analyze();
-
-	result = online_pages(start_pfn, nr_pages);
-
-	if (result)
-		pr_err("%s:%d: online_pages failed: (%d)\n",
-			__func__, __LINE__, result);
-
-	return result;
-}
-
-device_initcall(ps3_mm_add_memory);
-
 /*============================================================================*/
 /* dma routines                                                               */
 /*============================================================================*/
@@ -1280,6 +1229,17 @@  void __init ps3_mm_init(void)
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
 
+	if (!map.r1.size) {
+		DBG("%s:%d: no region 1, not adding memory\n",
+			__func__, __LINE__);
+	} else {
+		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
+			__func__, __LINE__, map.rm.size, map.r1.size);
+
+		memblock_add(map.rm.size, map.r1.size);
+		memblock_analyze();
+	}
+
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }