HPT resizing option - KVM only

Signed-off-by: Jeff Scheel <scheel@us.ibm.com>
pull/2/head
Jeff Scheel 4 years ago
parent c0f254843c
commit 04e5da1a6b

@ -3396,7 +3396,7 @@
<para>7</para>
</entry>
<entry>
<para>Reserved for Expansion</para>
<para>Enable Hash Page Table Resize Option</para>
</entry>
</row>
<row>

@ -2551,6 +2551,21 @@ ELSE
architecture introduced in POWER ISA 3.0</para>
</entry>
</row>
<row>
<entry>
<para>Hash Page Table Resize Option</para>
</entry>
<entry>
<para>O</para>
</entry>
<entry>
<para>O</para>
</entry>
<entry>
<para>Allows partitions to resize their HPT. See
<xref linkend="LoPAR.Virtualization"/>.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>

@ -1595,6 +1595,26 @@ xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en" xml:id="dbdo
<para>Manage the virtual address translation mode including registration of a process table.</para>
</entry>
</row>
<row>
<entry>
<para>
<xref linkend="sec_resize_hpt_prepare" xrefstyle="select: title nopage" /> / <xref linkend="sec_resize_hpt_prepare" xrefstyle="select: labelnumber nopage" />
</para>
</entry>
<entry>
<para>Prepares for resizing the partition's HPT</para>
</entry>
</row>
<row>
<entry>
<para>
<xref linkend="sec_resize_hpt_commit" xrefstyle="select: title nopage" /> / <xref linkend="sec_resize_hpt_commit" xrefstyle="select: labelnumber nopage" />
</para>
</entry>
<entry>
<para>Changes the partition's HPT to a new size</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
@ -3977,7 +3997,7 @@ xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en" xml:id="dbdo
<para>Reserved</para>
</entry>
<entry>
<para>0x35C-0x370</para>
<para>0x35C-0x368</para>
</entry>
<entry>
<para>&#160;</para>
@ -3989,6 +4009,44 @@ xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en" xml:id="dbdo
<para>&#160;</para>
</entry>
</row>
<row>
<entry>
<para>
<xref linkend="sec_resize_hpt_prepare" xrefstyle="select: title nopage" /> / <xref linkend="sec_resize_hpt_prepare" xrefstyle="select: labelnumber nopage" />
</para>
</entry>
<entry>
<para>0x36C</para>
</entry>
<entry>
<para>Normal</para>
</entry>
<entry>
<para>If the platform supports the Hash Page Table Resize Option</para>
</entry>
<entry>
<para>hcall-hpt-resize</para>
</entry>
</row>
<row>
<entry>
<para>
<xref linkend="sec_resize_hpt_commit" xrefstyle="select: title nopage" /> / <xref linkend="sec_resize_hpt_commit" xrefstyle="select: labelnumber nopage" />
</para>
</entry>
<entry>
<para>0x370</para>
</entry>
<entry>
<para>Normal</para>
</entry>
<entry>
<para>If the platform supports the Hash Page Table Resize Option</para>
</entry>
<entry>
<para>hcall-hpt-resize</para>
</entry>
</row>
<row>
<entry>
<para>
@ -7676,6 +7734,260 @@ hcall ( const int64 H_BLOCK_REMOVE, /* Function Code */
</simplesect>
</section>

<section xml:id="sec_hash_page_table_resize_option">
<title>Hash Page Table Resize Option</title>

<para>The hash page table (HPT) for an operating system needs to be
sized depending on the size of the partition's memory. The usual rule of
thumb is that the HPT should be 1/64th of the size of memory (although
Linux will typically work well with 1/128th or even less depending on
available page sizes). An HPT which is too small will lead to poor performance,
or even crashes, if the OS is unable to fit necessary bolted mappings into
the table. An HPT which is too large wastes memory and leads to slower
TLB misses due to increased cache misses on table walks.</para>

<para>With the size of the HPT fixed at boot, a partition allowing memory
reconfiguration must size the HPT according to the partition's maximum
possible memory size. If the partition has a very large potential maximum
memory size, but is un- likely to reach that in practice, this can lead to
significant wastage of resources in the oversized hash table. By allowing
a partition to change its HPT size at runtime, it can start with an HPT
sized just for its initial memory, and change it if necessary when more
memory is added dynamically.</para>

<para>If the platform supports the Hash Page Table Resize Option, then it supports
the two hcalls defined in this section, which allow an OS to request that its
HPT should be resized. The resize operation is performed in two phases, the
“pre- pare” phase and the “commit” phase. The prepare phase may take place
concurrently with normal guest operation. The commit phase requires that the
guest perform no concurrent updates or accesses to the HPT (which in practice
requires no non-real mode memory accesses).</para>

<para>
During operation a partition may have a “Pending HPT”, a block of platform
memory organized as a Power hash page table which may become the partition's
HPT in future. The following data are associated with a Pending HPT:
<itemizedlist>
<listitem>
<para>Does a Pending HPT currently exist?</para>
</listitem>
<listitem>
<para>The Pending HPT's size</para>
</listitem>
<listitem>
<para>Flags associated with the Pending HPT (this is for future
extension, no flags are currently defined)</para>
</listitem>
<listitem>
<para>Whether the Pending HPT is fully prepared or not</para>
</listitem>
</itemizedlist>
</para>

<para>In order to prevent a partition from tying up platform resources
indefinitely with a Pending HPT, the platform is per- mitted to discard a
Pending HPT at any time. Operating systems should be prepared to deal
with a failure of either hcall because of this.</para>

<para>The platform is permitted to start a partition with its HPT sized
for the current memory allocation, rather than the max- imum memory for
the partition, provided that if the OS indicates via the
ibm,client-architecture-support call that it does not support HPT resizing,
the platform must then resize the HPT according to the partition's maximum
memory, using a reconfiguration reboot if necessary.</para>

<section xml:id="sec_resize_hpt_prepare">
<title>H_RESIZE_HPT_PREPARE</title>

<para>This hcall controls the prepare phase of HPT resizing. After
successful completion of this hcall, the partition has a Pending
HPT which can be made the partition's current HPT.</para>

<simplesect>
<title>Syntax:</title>
<programlisting><![CDATA[int64 /* H_Success: Expected Return code */
/* H_AUTHORITY: partition may not resize its */
/* HPT H_PARAMETER, one or more parameters */
/* in error H_RESOURCE, insufficient resources */
/* H_PTEG_FULL: two or more bolted HPTEs need the same slot */
/* H_LONG_BUSY_*: operation in progress but not complete. */
hcall ( const int64 H_RESIZE_HPT_PREPARE, /* Function Code */
uint64 flags, /* Special function indications */
int32 shift ); /* Log base 2 of new HPT size */]]></programlisting>

</simplesect>

<simplesect>
<title>Parameters:</title>

<itemizedlist>
<listitem>
<para>flags: 0, as no flags are currently defined.</para>
</listitem>
<listitem>
<para>shift: Log base 2 of the total size in bytes of the
requested new HPT, either 0 (used to discard a Pending HPT)
or else between 18 and 46.</para>
</listitem>
</itemizedlist>
</simplesect>

<simplesect>
<title>Semantics:</title>

<itemizedlist>
<listitem>
<para>Check that the partition is permitted to resize its HPT, else
return H_AUTHORITY.</para>
</listitem>
<listitem>
<para>Check if there is a Pending HPT; if there is, then:
<itemizedlist>
<listitem>
<para>If the Pending HPT size and flags match the parameters requested in this call, then:
<itemizedlist>
<listitem>
<para>If the Pending HPT is not fully prepared, return
H_LONG_BUSY_xxx with an estimate of the time remaining
to complete preparation of the Pending HPT</para>
</listitem>
<listitem>
<para>If preparation of the Pending HPT has terminated
due to two bolted HPTEs needing to occupy the same
slot of the same HPTEG, then return H_PTEG_FULL</para>
</listitem>
<listitem>
<para>Else return H_SUCCESS</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>Else discard the Pending HPT and continue</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>If the flags parameter is non-zero, then return H_PARAMETER</para>
</listitem>
<listitem>
<para>If shift is zero, then return H_SUCCESS</para>
</listitem>
<listitem>
<para>If (shift &lt; 18) or (shift &gt; 46), then return H_PARAMETER</para>
</listitem>
<listitem>
<para>Check that the partition is permitted to have an HPT of 2shift
bytes; if not, return H_RESOURCE</para>
</listitem>
<listitem>
<para>Create a new Pending HPT of size 2shift bytes. Preparation of
the new HPT may continue asynchronously.</para>
</listitem>
<listitem>
<para>If the Pending HPT is not fully prepared, return
H_LONG_BUSY_xxx with an estimate of the time remaining to
complete preparation.</para>
</listitem>
<listitem>
<para>Else return H_SUCCESS.</para>
</listitem>
</itemizedlist>
</simplesect>
</section>

<section xml:id="sec_resize_hpt_commit">
<title>H_RESIZE_HPT_COMMIT</title>

<para>This hcall executes the commit phase of HPT resizing, making the
Pending HPT the partition's current HPT. The caller must ensure that
while it is executing, none of the partition's virtual CPU threads
will update or access the HPT; that is, all threads must be executing
in real mode, or stopped.</para>

<simplesect>
<title>Syntax:</title>
<programlisting><![CDATA[int64 /* H_Success: Expected Return code */
/* H_AUTHORITY: partition is not permitted to resize its */
/* HPT */
/* H_CLOSED: there is no suitable pending HPT */
/* H_PTEG_FULL: two or more bolted HPTEs need the same slot */
/* H_BUSY: preparation of the Pending HPT has not */
/* completed */
hcall ( const int64 H_RESIZE_HPT_COMMIT, /* Function Code */
uint64 flags, /* Special function indications */
int32 shift ); /* Log base 2 of new HPT size */]]></programlisting>

</simplesect>

<simplesect>
<title>Parameters:</title>

<itemizedlist>
<listitem>
<para>flags: 0, as no flags are currently defined.</para>
</listitem>
<listitem>
<para>shift: Log base 2 of the total size in bytes of the
requested new HPT, between 18 and 46.</para>
</listitem>
</itemizedlist>
</simplesect>

<simplesect>
<title>Semantics:</title>

<itemizedlist>
<listitem>
<para>Check that the partition is permitted to resize its HPT,
else return H_AUTHORITY.</para>
</listitem>
<listitem>
<para>Check if there is a Pending HPT; if there is not, then
return H_CLOSED.</para>
</listitem>
<listitem>
<para>Check that the flags parameter is zero and the shift
parameter matches the size of the Pending HPT; if not, then
re- turn H_CLOSED.</para>
</listitem>
<listitem>
<para>Check that the Pending HPT is fully prepared; if not,
return H_BUSY.</para>
</listitem>
<listitem>
<para>If preparation of the Pending HPT was terminated due to finding
two bolted HPTEs that need to occupy the same
slot of the same HPTEG, then return H_PTEG_FULL.</para>
</listitem>
<listitem>
<para>Ensure that all bolted HPTEs from the partition's existing HPT
also exist, correctly hashed, in the Pending HPT. HPTEs transferred
from the existing HPT must have the same slot within their HPTEG in
the Pending HPT as they did in the existing HPT. If the Pending HPT
is smaller than the existing HPT, it is possible that two bolted HPTEs
that are in the same slot of two separate HPTEGs in the existing HPT
need to be put into the same HPTEG in the Pending HPT. If this occurs,
return H_PTEG_FULL.</para>
</listitem>
<listitem>
<para>Discard the partition's existing HPT.</para>
</listitem>
<listitem>
<para>Make the Pending HPT be the partition's current HPT.</para>
</listitem>
<listitem>
<para>Mark the partition as having no Pending HPT.</para>
</listitem>
<listitem>
<para>Return H_Success.</para>
</listitem>
</itemizedlist>
</simplesect>
</section>
</section>

</section>

<section>

Loading…
Cancel
Save