summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot
diff options
context:
space:
mode:
authorIlya Smirnov <ismirno@us.ibm.com>2018-11-16 11:55:02 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-03-01 15:23:30 -0600
commit9ece0ede203d4165b5423bdbf677cd272b78d094 (patch)
tree5382b488101276693f6b10dd510b162814a9eb06 /src/usr/secureboot
parented35e3da7c2606f6fe0930725892deae85df33b7 (diff)
downloadtalos-hostboot-9ece0ede203d4165b5423bdbf677cd272b78d094.tar.gz
talos-hostboot-9ece0ede203d4165b5423bdbf677cd272b78d094.zip
SMF: Memory Distribution Logic Improvements
An improvement to the memory distribution logic was suggested in which the variable that keeps track of doubling the amount of memory per pass could be removed. This commit removes the variable and introduces a couple of other small changes. Change-Id: I35cae2d6c2beac2ce91d94f439fd0dec1f782afc Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68859 Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Matthew Raybuck <mraybuc@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot')
-rw-r--r--src/usr/secureboot/smf/README.md40
-rw-r--r--src/usr/secureboot/smf/smf.C40
2 files changed, 53 insertions, 27 deletions
diff --git a/src/usr/secureboot/smf/README.md b/src/usr/secureboot/smf/README.md
new file mode 100644
index 000000000..75796fc95
--- /dev/null
+++ b/src/usr/secureboot/smf/README.md
@@ -0,0 +1,40 @@
+# SMF Memory Allocation Algorithm
+
+### Introduction
+The amount of Secure SMF memory to distribute between the available procs on the system
+is a user-configurable petitboot setting. Hostboot reads this setting and distributes
+the requested amount of memory as evenly as possible between the available procs on the
+system.
+
+**NOTE:** We must operate in power-of-two multiples of 256MB to satisfy hardware limitations. That means that the end result of the amount of secure memory behind each proc needs to be a power-of-two multiple of 256MB.
+
+### The Algorithm
+* The function to distribute the memory receives the requested amount (in bytes) as a uint64.
+* A check is performed to see if the requested amount is 0 (do not allocate secure memory)
+ * SMF is turned off in that case
+* A structure of proc and memory associations is built
+ * Each member of the struct consists of the proc target, the total available memory behind that proc, the amount of secure memory to be allocated behind that proc (0 initially), and the flag indicating whether the proc can still fit secure memory
+ * 8GB is subtracted from the available memory pool of the master proc to make sure hostboot has space to run in
+* Start allocating the memory in chunks, starting with 256MB, and doubling the amount (where appropriate) every loop
+* In a loop:
+ * Check if we've allocated all requested memory (or more)
+ * Check if the current chunk is more than we can fit under the proc
+ * **TRUE**: Flag the proc as out of memory (it will not be considered anymore)
+ * **FALSE**: "Pre-allocate" the current chunk behind the proc
+ * If we were able to allocate the current chunk, calculate the remaining amt to allocate
+ * If we've allocated everything or ran out of procs to allocate the memory on, break out of the loop
+ * Double the chunk to allocate for the next loop
+* At the end of the loop two checks are performed:
+ * Check if we couldn't allocate any memory (the system is memory-starved) - return a predictive error
+ * Check if the actual allocated amount does not equal to the requested amount (there may have been rounding) - return an informational error
+
+### Visual Representation of the Allocation Process
+
+| Loop | Allocated on Proc 0 (MB) | Proc 1 | Proc 2|
+| -----|:------------------------:| :------:|:-----:|
+| 0 | 0 | 0 | 0 |
+| 1 | 256 | 256 | 256 |
+| 2 | 512 | 512 | 512 |
+| 3 | 1024 | 1024 | 1024 |
+| 4 | 2048 | 2048 | 2048 |
+... repeat until allocated or until there are no more remaining procs with memory
diff --git a/src/usr/secureboot/smf/smf.C b/src/usr/secureboot/smf/smf.C
index 62aad557e..d940660f3 100644
--- a/src/usr/secureboot/smf/smf.C
+++ b/src/usr/secureboot/smf/smf.C
@@ -130,7 +130,6 @@ errlHndl_t distributeSmfMem(const uint64_t i_requestedSmfMemAmtInBytes,
int64_t l_remainingAmtToAllocate = i_requestedSmfMemAmtInBytes;
uint64_t l_currChunkSize = MIN_SMF_MEMORY_AMT;
- bool l_doubleChunk = false;
uint64_t l_allocatedSoFar = 0;
uint64_t l_totalAllocated = 0;
@@ -161,9 +160,6 @@ errlHndl_t distributeSmfMem(const uint64_t i_requestedSmfMemAmtInBytes,
// The proc is out of memory; we can't use it any more
// in the allocation algorithm
l_member.useProc = false;
- // We still need to allocate the current chunk to some other
- // proc though, so don't increment the chunks for now.
- l_doubleChunk = false;
TRACDCOMP(SMF_TRACE::g_trac_smf, "distributeSmfMem: proc 0x%x ran out of memory.", TARGETING::get_huid(l_member.proc));
}
else
@@ -171,37 +167,27 @@ errlHndl_t distributeSmfMem(const uint64_t i_requestedSmfMemAmtInBytes,
// Can fit the current chunk.
l_member.memToAllocate = l_currChunkSize;
- // We were able to allocate; now double the next chunk
- l_doubleChunk = true;
- }
-
- // Tally up the total amt of memory allocated so far.
- // We need to check this on each allocation (after each proc)
- // because we may have to stop mid way through the proc loop
- // when we've allocated all requested mem.
- for(const auto& l_proc : i_procToMemVec)
- {
- l_allocatedSoFar += l_proc.memToAllocate;
- }
+ // Tally up the total amt of memory allocated so far.
+ // We need to check this on each allocation after each proc
+ // because we may have to stop mid way through the proc loop
+ // when we've allocated all requested mem.
+ for(const auto& l_proc : i_procToMemVec)
+ {
+ l_allocatedSoFar += l_proc.memToAllocate;
+ }
- if(l_doubleChunk)
- {
// Only calculate the remaining amt when we've successfully
- // allocated a chunk (which will force the boolean to
- // be true). If we could not allocate the chunk, then the
- // remaining amount didn't change.
+ // allocated a chunk. If we could not allocate the chunk,
+ // then the remaining amount didn't change.
l_remainingAmtToAllocate = i_requestedSmfMemAmtInBytes
- l_allocatedSoFar;
}
} // useProc
} // l_member
- if(l_doubleChunk)
- {
- // Double the amt of mem we will try to allocate on the next
- // iteration of the while loop.
- l_currChunkSize = l_currChunkSize << 1;
- }
+ // Double the amt of mem we will try to allocate on the next
+ // iteration of the while loop.
+ l_currChunkSize = l_currChunkSize << 1;
// Find out if we still have procs remaining. If not, then the
// user has requested too much memory to be allocated.
OpenPOWER on IntegriCloud