Skip to content

Commit

Permalink
PRD: enable predictive dynamic memory deallocation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
zane131 committed Apr 10, 2018
1 parent ad8ec72 commit d026d31
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 52 deletions.
73 changes: 61 additions & 12 deletions src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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 );
Expand All @@ -537,17 +544,45 @@ 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",
chip->getHuid() );
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 "
Expand All @@ -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 )
{
Expand Down Expand Up @@ -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.
Expand All @@ -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] "
Expand Down
52 changes: 20 additions & 32 deletions src/usr/diag/prdf/plat/prdfPlatServices_rt.C
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}

//##############################################################################
Expand Down
25 changes: 17 additions & 8 deletions src/usr/diag/prdf/plat/prdfPlatServices_rt.H
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d026d31

Please sign in to comment.