From eba5c2ffe5ffb1f50966b7990e2f5f71f09105ce Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Thu, 7 Feb 2019 15:21:19 -0600 Subject: Statically allocate work pages for PNOR Resource Provider Any time the PNOR Resource Provider loads in a page that is ECC protected it allocates 0x1200 bytes to hold the data while it is decoded. Continuously allocating 2 pages from the heap leads to a couple of potential issues: - fragmentation of memory due to constant new/delete of pages - extremely low memory situation could prevent new code from paging in The solution here is to place the working buffer inside the PNOR RP class itself. This means we will only do a single allocation of the memory early on in the boot and the memory is always available. Change-Id: I7faabb6be7cc89abdb8a8fb962e0623a2bcd5e99 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71546 Reviewed-by: Corey V. Swenson Reviewed-by: Nicholas E. Bofferding Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Michael Baiocchi Reviewed-by: Daniel M. Crowell --- src/usr/pnor/pnorrp.C | 23 +++++------------------ src/usr/pnor/pnorrp.H | 12 ++++++++++-- 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'src/usr/pnor') diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index c9a5e5336..af6ccf3fa 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* Contributors Listed Below - COPYRIGHT 2011,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -251,6 +251,7 @@ iv_TOC_used(TOC_0) ,iv_shutdown_pending(false) { TRACDCOMP(g_trac_pnor, "PnorRP::PnorRP> " ); + // setup everything in a separate function initDaemon(); @@ -1315,7 +1316,6 @@ errlHndl_t PnorRP::readFromDevice( uint64_t i_offset, { TRACUCOMP(g_trac_pnor, "PnorRP::readFromDevice> i_offset=0x%X, i_chip=%d", i_offset, i_chip ); errlHndl_t l_errhdl = NULL; - uint8_t* ecc_buffer = NULL; o_fatalError = 0; do @@ -1329,8 +1329,7 @@ errlHndl_t PnorRP::readFromDevice( uint64_t i_offset, // if we need to handle ECC we need to read more than 1 page if( i_ecc ) { - ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC](); - data_to_read = ecc_buffer; + data_to_read = iv_ecc_buffer; read_size = PAGESIZE_PLUS_ECC; } @@ -1408,11 +1407,6 @@ errlHndl_t PnorRP::readFromDevice( uint64_t i_offset, } } while(0); - if( ecc_buffer ) - { - delete[] ecc_buffer; - } - TRACUCOMP(g_trac_pnor, "< PnorRP::readFromDevice" ); return l_errhdl; } @@ -1427,7 +1421,6 @@ errlHndl_t PnorRP::writeToDevice( uint64_t i_offset, { TRACUCOMP(g_trac_pnor, "PnorRP::writeToDevice> i_offset=%X, i_chip=%d", i_offset, i_chip ); errlHndl_t l_errhdl = NULL; - uint8_t* ecc_buffer = NULL; do { @@ -1440,11 +1433,10 @@ errlHndl_t PnorRP::writeToDevice( uint64_t i_offset, // apply ECC to data if needed if( i_ecc ) { - ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC]; PNOR::ECC::injectECC( reinterpret_cast(i_src), PAGESIZE, - reinterpret_cast(ecc_buffer) ); - data_to_write = reinterpret_cast(ecc_buffer); + reinterpret_cast(iv_ecc_buffer) ); + data_to_write = reinterpret_cast(iv_ecc_buffer); write_size = PAGESIZE_PLUS_ECC; } @@ -1463,11 +1455,6 @@ errlHndl_t PnorRP::writeToDevice( uint64_t i_offset, } } while(0); - if( ecc_buffer ) - { - delete[] ecc_buffer; - } - TRACUCOMP(g_trac_pnor, "< PnorRP::writeToDevice" ); return l_errhdl; } diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H index 9ab654678..1fe3c088c 100644 --- a/src/usr/pnor/pnorrp.H +++ b/src/usr/pnor/pnorrp.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* Contributors Listed Below - COPYRIGHT 2011,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -35,6 +35,8 @@ #include "pnor_common.H" #include "ffs.h" #include +#include "pnor_utils.H" + /** * PNOR Resource Provider */ @@ -189,7 +191,7 @@ class PnorRP /** * sent when a shutdown message is sent, used to elimnate further writes - * to pnore during a shutdown process + * to pnor during a shutdown process */ bool iv_shutdown_pending; @@ -199,6 +201,12 @@ class PnorRP */ std::map iv_stats; + /** + * Create a permanent buffer to handle ECC translations rather than + * constantly allocating new pages every time. This is always 2 pages. + */ + uint8_t iv_ecc_buffer[PNOR::PAGESIZE_PLUS_ECC]; + /** * @brief Initialize the daemon, called by constructor */ -- cgit v1.2.1