summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-04-02 20:58:21 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-10 11:08:30 -0400
commitd026d31c923e7756586b64c123632d9d7dad8489 (patch)
tree4be448e22be953e3b17ba37255ae051e2fc6ab78
parentad8ec727bc7f5c641c92e274829cc89f6e0e7f1f (diff)
downloadtalos-hostboot-d026d31c923e7756586b64c123632d9d7dad8489.tar.gz
talos-hostboot-d026d31c923e7756586b64c123632d9d7dad8489.zip
PRD: enable predictive dynamic memory deallocation
Change-Id: I54fc3058c2a62efc36deea89b08b3ea1e08a742f Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56613 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56891 CI-Ready: Zane C. Shelley <zshelle@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> Tested-by: Zane C. Shelley <zshelle@us.ibm.com>
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C73
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_rt.C52
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_rt.H25
3 files changed, 98 insertions, 52 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
index b7c76874c..d50980cfb 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
@@ -410,6 +410,8 @@ int32_t page( ExtensibleChip * i_chip, MemAddr i_addr )
}
template int32_t page<TYPE_MCA>( ExtensibleChip * i_chip, MemAddr i_addr );
+//------------------------------------------------------------------------------
+
template<TYPE T>
int32_t rank( ExtensibleChip * i_chip, MemRank i_rank )
{
@@ -457,6 +459,8 @@ int32_t rank( ExtensibleChip * i_chip, MemRank i_rank )
}
template int32_t rank<TYPE_MCA>( ExtensibleChip * i_chip, MemRank i_rank );
+//------------------------------------------------------------------------------
+
template<TYPE T>
int32_t port( ExtensibleChip * i_chip )
{
@@ -503,17 +507,20 @@ int32_t port( ExtensibleChip * i_chip )
}
template int32_t port<TYPE_MCA>( ExtensibleChip * i_chip );
+//------------------------------------------------------------------------------
+
template <TYPE T>
-int32_t dimmSlct( TargetHandle_t i_dimm )
+int32_t __getDimmRange( TargetHandle_t i_dimm,
+ uint64_t & o_ssAddr, uint64_t & o_seAddr )
{
- #define PRDF_FUNC "[MemDealloc::dimmSlct] "
+ #define PRDF_FUNC "[MemDealloc::__getDimmRange] "
int32_t o_rc = SUCCESS;
+ o_ssAddr = o_seAddr = 0;
+
do
{
- if ( !isEnabled() ) break; // nothing to do
-
// Get the MCA, MBA, etc. connected to this DIMM.
TargetHandle_t trgt = getConnectedParent( i_dimm, T );
ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip( trgt );
@@ -537,10 +544,8 @@ int32_t dimmSlct( TargetHandle_t i_dimm )
}
// Get the system addresses.
- uint64_t ssAddr = 0;
- uint64_t seAddr = 0;
- o_rc = getSystemAddr<T>( chip, startAddr, ssAddr );
- o_rc |= getSystemAddr<T>( chip, endAddr, seAddr );
+ o_rc = getSystemAddr<T>( chip, startAddr, o_ssAddr );
+ o_rc |= getSystemAddr<T>( chip, endAddr, o_seAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getSystemAddr(0x%08x) failed",
@@ -548,6 +553,36 @@ int32_t dimmSlct( TargetHandle_t i_dimm )
break;
}
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template <TYPE T>
+int32_t dimmSlct( TargetHandle_t i_dimm )
+{
+ #define PRDF_FUNC "[MemDealloc::dimmSlct] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ if ( !isEnabled() ) break; // nothing to do
+
+ // Get the system addresses.
+ uint64_t ssAddr = 0, seAddr = 0;
+ o_rc = __getDimmRange<T>( i_dimm, ssAddr, seAddr );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__getDimmRange(0x%08x) failed",
+ getHuid(i_dimm) );
+ break;
+ }
+
// Send the address range to the hypervisor.
sendDynMemDeallocRequest( ssAddr, seAddr );
PRDF_TRAC( PRDF_FUNC "DIMM Slct dealloc for Start Addr: 0x%016llx "
@@ -560,6 +595,8 @@ int32_t dimmSlct( TargetHandle_t i_dimm )
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
+
template <TYPE T>
bool isDimmPair( TargetHandle_t i_dimm1, TargetHandle_t i_dimm2 )
{
@@ -601,11 +638,13 @@ bool compareDimms( TargetHandle_t i_dimm1, TargetHandle_t i_dimm2 )
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
template <TYPE T>
int32_t dimmList( TargetHandleList & i_dimmList )
{
#define PRDF_FUNC "[MemDealloc::dimmList] "
+
int32_t o_rc = SUCCESS;
// Find unique dimm slct.
@@ -617,17 +656,27 @@ int32_t dimmList( TargetHandleList & i_dimmList )
for( TargetHandleList::iterator it = i_dimmList.begin();
it != uniqueDimmEndIt; it++ )
{
- int32_t l_rc = dimmSlct<T>( *it );
- if( SUCCESS != l_rc )
+ // Get the system addresses.
+ uint64_t ssAddr = 0, seAddr = 0;
+ if ( SUCCESS != __getDimmRange<T>(*it, ssAddr, seAddr) )
{
- PRDF_ERR(PRDF_FUNC "Failed for DIMM 0x:%08X", getHuid( *it ) );
- o_rc |= l_rc;
+ PRDF_ERR( PRDF_FUNC "__getDimmRange(0x%08x) failed", getHuid(*it) );
+ o_rc = FAIL; continue; // Continue to the next DIMM.
}
+
+ // Send the address range to the hypervisor.
+ sendPredDeallocRequest( ssAddr, seAddr );
+ PRDF_TRAC( PRDF_FUNC "Predictive dealloc for start addr: 0x%016llx "
+ "end addr: 0x%016llx", ssAddr, seAddr );
}
+
return o_rc;
+
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
+
int32_t dimmList( TargetHandleList & i_dimmList )
{
#define PRDF_FUNC "[MemDealloc::dimmList] "
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
index 6e78e3052..6d1528a23 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
@@ -63,56 +63,44 @@ namespace PlatServices
//## Memory specific functions
//##############################################################################
-void sendPageGardRequest( uint64_t i_systemAddress )
+void __dyndealloc( uint64_t i_saddr, uint64_t i_eaddr, MemoryError_t i_type )
{
- #define PRDF_FUNC "[PlatServices::sendPageGardRequest] "
+ #define PRDF_FUNC "[PlatServices::__dyndealloc] "
do
{
- if( !g_hostInterfaces || !g_hostInterfaces->memory_error )
+ if ( !g_hostInterfaces || !g_hostInterfaces->memory_error )
{
- PRDF_ERR(PRDF_FUNC " memory_error() interface is not defined");
+ PRDF_ERR( PRDF_FUNC "memory_error() interface is not defined" );
break;
}
- int32_t rc = g_hostInterfaces->memory_error( i_systemAddress,
- i_systemAddress,
- MEMORY_ERROR_CE );
- if( SUCCESS != rc )
+ int32_t rc = g_hostInterfaces->memory_error( i_saddr, i_eaddr, i_type );
+ if ( SUCCESS != rc )
{
- PRDF_ERR(PRDF_FUNC " memory_error() failed");
+ PRDF_ERR( PRDF_FUNC "memory_error() failed" );
break;
}
- }while(0);
+
+ } while (0);
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
-
-void sendDynMemDeallocRequest( uint64_t i_startAddr, uint64_t i_endAddr )
+void sendPageGardRequest( uint64_t i_saddr )
{
- #define PRDF_FUNC "[PlatServices::sendDynMemDeallocRequest] "
-
- do
- {
- if( !g_hostInterfaces || !g_hostInterfaces->memory_error )
- {
- PRDF_ERR(PRDF_FUNC " memory_error() interface is not defined");
- break;
- }
+ // Note that both addresses will be the same for a page gard.
+ __dyndealloc( i_saddr, i_saddr, MEMORY_ERROR_CE );
+}
- int32_t rc = g_hostInterfaces->memory_error( i_startAddr,
- i_endAddr,
- MEMORY_ERROR_UE );
- if( SUCCESS != rc )
- {
- PRDF_ERR(PRDF_FUNC " memory_error() failed");
- break;
- }
- }while(0);
+void sendDynMemDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr )
+{
+ __dyndealloc( i_saddr, i_eaddr, MEMORY_ERROR_UE );
+}
- #undef PRDF_FUNC
+void sendPredDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr )
+{
+ __dyndealloc( i_saddr, i_eaddr, MEMORY_ERROR_PREDICTIVE );
}
//##############################################################################
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_rt.H b/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
index 157e4cb25..17f8be9e1 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
@@ -42,18 +42,27 @@ namespace PlatServices
//##############################################################################
/**
- * @brief Communicates a page gard request to the hypervisor.
- * @param i_systemAddress Any address in the target page.
+ * @brief Sends a page gard request to the hypervisor.
+ * @param i_addr Any address in the target page.
*/
-void sendPageGardRequest( uint64_t i_systemAddress );
+void sendPageGardRequest( uint64_t i_addr );
/**
- * @brief Communicates to the hypervisor a range of address to remove from the
- * available memory space.
- * @param i_startAddr First address in the range.
- * @param i_endAddr Last address in the range.
+ * @brief Sends a dynamic memory deallocation message to the hypervisor. This
+ * message is intended for memory UEs, channel/port failures, etc.
+ * @param i_saddr The first address in the range.
+ * @param i_eaddr The last address in the range.
*/
-void sendDynMemDeallocRequest( uint64_t i_startAddr, uint64_t i_endAddr );
+void sendDynMemDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr );
+
+/**
+ * @brief Sends a predictive dynamic memory deallocation message to the
+ * hypervisor. This message is intended to be send whenever there is a
+ * predictive callout of any part in the memory subsystem.
+ * @param i_saddr The first address in the range.
+ * @param i_eaddr The last address in the range.
+ */
+void sendPredDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr );
//##############################################################################
//## Nimbus/Centaur Maintenance Command wrappers
OpenPOWER on IntegriCloud