Thread (1 message) 1 message, 1 author, 2011-02-08

Re: devicetree: Musings on reserved regions

From: David Gibson <hidden>
Date: 2011-02-08 12:24:52

On Mon, Feb 07, 2011 at 01:59:53PM -0700, Grant Likely wrote:
As part of the process of bringing dt support up on non-powerpc
platforms, I've been thinking about the usage mode of the reserved
regions section in the flattened device tree structure.  First, for
reference, here is the description of reserved regions from ePAPR
1.0:
quoted
7.3 Memory Reservation Block
7.3.1 Purpose
The memory reservation block provides the client program with
a list of areas in physical memory which are reserved; that
is, which shall not be used for general memory allocations. It
is used to protect vital data structures from being
overwritten by the client program. For example, on some
systems with an IOMMU, the TCE (translation control entry)
tables initialized by an ePAPR boot program would need to be
protected in this manner. Likewise, any boot program code or
data used during the client program’s runtime would need to be
reserved (e.g., RTAS on Open Firmware platforms). The ePAPR
does not require the boot program to provide any such runtime
components, but it does not prohibit implementations from
doing so as an extension.

More specifically, a client program shall not access memory in
a reserved region unless other information provided by the
boot program explicitly indicates that it shall do so. The
client program may then access the indicated section of the
reserved memory in the indicated manner. Methods by which the
boot program can indicate to the client program specific uses
for reserved memory may appear in this document, in optional
extensions to it, or in platform-specific documentation.

The reserved regions supplied by a boot program may, but are
not required to, encompass the device tree blob itself. The
client program shall ensure that it does not overwrite this
data structure before it is used, whether or not it is in the
reserved areas.
The problem that I'm having, is that the lifecycle for reserved
regions is not defined and the client program has no mechanism to
determine what each reserved region is intended for.  This issue has
been raised before in the context of kexec from one Linux instance to
another[1].  When going from one kernel to the next, kexec needs to
populate a valid set of reserved regions, but it isn't easy to figure
out what the new set should be because there isn't a reliable way to
figure out which regions from the previous boot need to be preserved
(ie. runtime firmware or framebuffers) vs regions that are obsolete
(original initrd and dtb regions).
Hrm, I agree that the fact that the reserved sections meaning and
lifetime may not be known is awkward, but I'm not yet convinced that
we need something like this.

Here's how I envisaged this working under the current spec, which the
text is meant to convey (but maybe needs work):

So, you start with the reserved regions from the special block.  It
wants to be here, rather than built into the tree, because you need to
parse this before doing *any* memory allocation, and doing tree
parsing and tracking the regions that early, without memory allocation
is painful.

Absent other information, those regions must remain untouched
*forever*.  The client program must not read or right them, and it
must pass those regions onto subsequent things to run - that could be
kexec(), or the real OS if this client is a second stage loader.

However other parts of the spec may desribe things giving a specific
use of part of the reserved area, for example, the initrd-start/end
properties and the spin-table entries.

The binding that describes some use of reserved memory may also bound
that reservation's lifetime.  So, once you've processed the initrd
properties, you may excise the initrd area from the reserved sections.
There is no guarantee the initrd reservation maps to exactly one entry
in the reserve map, so yes, this may mean some fairly involved extent
intersection type code to do.

Likewise the spin-table means that once you have brought a secondary
cpu out of spin with that method, you may reclaim the 16 (?) bytes of
its spin table entry (and no more).

Now, that's pretty ad-hoc, but the point is that you *must* understand
the use of a section of reserved memory before de-reserving it anyway,
and there is no guarantee that a reserved area can *ever* be freed.

Furthermore, I don't think we should require the boot program to bind
each reserve entry to exactly one purpose.  It seems to be a obvious
scheme for a boot program would be to lay out all the things it needs
to sequentially in RAM, and put in just one reserve entry for the
whole block.  For one thing, that means it will never need to resize /
memmove() the dt blob even if what things it needs to reserve vary.

Remember that all else being equal client program complexity is
preferable to boot program complexity.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help