summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2014-03-26 13:12:57 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-04-04 10:56:27 -0500
commit214b4da81b98c19c5dd8eb30b56b3b4d5d38e1c8 (patch)
tree5698b5251695fe1bc406610c3e3a2f8ed746085f /src
parent1be9762f6c1112555176ba474fe9a294c2ff1d95 (diff)
downloadtalos-hostboot-214b4da81b98c19c5dd8eb30b56b3b4d5d38e1c8.tar.gz
talos-hostboot-214b4da81b98c19c5dd8eb30b56b3b4d5d38e1c8.zip
Deconfigure targets by checking presence related targets
Centaurs behind a non-present processor are not being deconfigured Change-Id: I2574d75d76d7b7c1f4a0089193a2f361b7ac7e13 RTC: 99406 CQ: SW253452 Backport: release-fips810 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/9921 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/hwas/common/deconfigGard.H6
-rw-r--r--src/include/usr/hwas/common/hwas.H48
-rw-r--r--src/include/usr/targeting/common/entitypath.H25
-rw-r--r--src/include/usr/targeting/common/utilFilter.H21
-rw-r--r--src/usr/hwas/common/deconfigGard.C6
-rw-r--r--src/usr/hwas/common/hwas.C449
-rw-r--r--src/usr/hwas/test/hwasGardTest.H309
-rw-r--r--src/usr/targeting/common/entitypath.C31
-rw-r--r--src/usr/targeting/common/utilFilter.C8
9 files changed, 742 insertions, 161 deletions
diff --git a/src/include/usr/hwas/common/deconfigGard.H b/src/include/usr/hwas/common/deconfigGard.H
index 82519b6c1..52693a48a 100644
--- a/src/include/usr/hwas/common/deconfigGard.H
+++ b/src/include/usr/hwas/common/deconfigGard.H
@@ -134,6 +134,12 @@ public:
// are found connected to a non-functional Centaur
DECONFIGURED_BY_NO_PARENT_MEMBUF, // BASE | 0x09
+ // set by presentByAssoc() when a MEMBUF has no DIMMs
+ DECONFIGURED_BY_NO_CHILD_DIMM, // BASE | 0x0A
+
+ // set by presentByAssoc() when a MEMBUF has no MCS
+ DECONFIGURED_BY_NO_PARENT_MCS, // BASE | 0x0B
+
// mask - these bits mean it's a PLID and not an enum
DECONFIGURED_BY_PLID_MASK = 0xFFFF0000,
};
diff --git a/src/include/usr/hwas/common/hwas.H b/src/include/usr/hwas/common/hwas.H
index 45418f568..3862ca9e7 100644
--- a/src/include/usr/hwas/common/hwas.H
+++ b/src/include/usr/hwas/common/hwas.H
@@ -40,6 +40,7 @@
/******************************************************************************/
#include <stdint.h>
#include <targeting/common/commontargeting.H>
+#include <hwas/common/deconfigGard.H>
#include <hwas/common/hwasError.H>
namespace HWAS
@@ -124,6 +125,53 @@ errlHndl_t restrictEXunits(
errlHndl_t checkMinimumHardware(
const TARGETING::ConstTargetHandle_t i_node = NULL);
+/**
+ * @brief Struct representing a particular target. Used by
+ * invokePresentByAssoc to populate a vector of TargetInfo's for subsequent
+ * use by deconfigPresentByAssoc
+ */
+struct TargetInfo
+{
+ TARGETING::ATTR_AFFINITY_PATH_type affinityPath;
+ TARGETING::Target * pThisTarget;
+ TARGETING::ATTR_HUID_type huid;
+ TARGETING::ATTR_TYPE_type type;
+ HWAS::DeconfigGard::DeconfiguredByReason reason;
+ bool functional;
+};
+
+// Structure populated in invokePresentByAssoc() for use in presentByAssoc()
+typedef std::vector<TargetInfo> TargetInfoVector;
+
+/**
+ * @brief Invokes presentByAssoc
+ *
+ * Called by discoverTargets(). This function queries the system and populates
+ * a vector of structs representing functional MCS, MEMBUFS, DIMMS.
+ * This vector is then passed to presentByAssoc() which systematically adds
+ * targets to another vector to be deconfigured based on their related targets
+ * Upon completion of presentByAssoc(), this function iterates
+ * through the returned vector and deconfigures any targets marked
+ * for deconfiguration.
+ */
+void invokePresentByAssoc();
+
+/**
+ * @brief Algorithm to check if a MCS has a MEMBUF, a MEMBUF has a MCS and DIMM,
+ * and a DIMM has a MEMBUF.
+ *
+ * The vector o_funcTargets is sorted by affinity path to allow a single pass
+ * with some backtracking to check every scenario more efficiently.
+ * These checks are needed because of scenarios where targets are non-present
+ * and their related targets are not marked as deconfigured
+ *
+ * @param[in/out] o_funcTargets A vector of functional MCS, MEMBUFS, DIMMS
+ * @param[in/out] o_targToDeconfig A vector of targets to deconfigure, done
+ * this way to allow unit tests
+ */
+void presentByAssoc(TargetInfoVector& o_funcTargets,
+ TargetInfoVector& o_targToDeconfig);
+
}; // end namespace
#endif
diff --git a/src/include/usr/targeting/common/entitypath.H b/src/include/usr/targeting/common/entitypath.H
index cee5422cc..13fa86d39 100644
--- a/src/include/usr/targeting/common/entitypath.H
+++ b/src/include/usr/targeting/common/entitypath.H
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* COPYRIGHT International Business Machines Corp. 2011,2014 */
/* */
/* p1 */
/* */
@@ -255,6 +255,29 @@ class EntityPath
const EntityPath& i_rhs) const;
/**
+ * @brief Returns whether an entity path is logically less than
+ * another entity path (lexicographical order)
+ *
+ * Returns whether an entity path is logically less than another.
+ * This determination takes into account the entity path type, the
+ * number of path elements, and the values of the path elements
+ * themselves.
+ *
+ * @param[in] i_rhs Const reference to entity path to compare
+ *
+ * @pre N/A
+ *
+ * @post Equality returned to caller
+ *
+ * @return bool indicating whether an entity path is logically less
+ * than another entity path
+ *
+ * @retval true The lhs entity path is logically less than rhs
+ * @retval false The lhs entity path is logically greater than rhs
+ */
+ bool operator<(const EntityPath& i_rhs) const;
+
+ /**
* @brief Returns whether two entity paths are logically equal, but
* only for the specified number of path elements
*
diff --git a/src/include/usr/targeting/common/utilFilter.H b/src/include/usr/targeting/common/utilFilter.H
index 0e381286d..021dceb74 100644
--- a/src/include/usr/targeting/common/utilFilter.H
+++ b/src/include/usr/targeting/common/utilFilter.H
@@ -34,7 +34,6 @@
#include <targeting/common/iterators/targetiterator.H>
#include <targeting/common/iterators/rangefilter.H>
-
namespace TARGETING
{
@@ -59,7 +58,25 @@ namespace TARGETING
*
* @return bool, true if t1 HUID < t2 HUID, false otherwise
*/
-bool compareTargetHuid(TargetHandle_t t1, TargetHandle_t t2);
+inline bool compareTargetHuid(TargetHandle_t t1, TargetHandle_t t2)
+{
+ return (t1->getAttr<ATTR_HUID>() < t2->getAttr<ATTR_HUID>());
+}
+
+/**
+ * @brief Predicate function to sort by Affinity path (lexicographical order)
+ *
+ * @parm[in] t1, Target 1 for AffinityPath comparison against target 2
+ * @parm[in] t2, Target 2 for AffinityPath comparison against target 1
+ *
+ * @return bool, true if t1 AffinityPath < t2 AffinityPath, false otherwise
+ */
+inline bool compareAffinity(TargetHandle_t t1, TargetHandle_t t2)
+{
+ EntityPath t1_Affinity = t1->getAttr<ATTR_AFFINITY_PATH>();
+ EntityPath t2_Affinity = t2->getAttr<ATTR_AFFINITY_PATH>();
+ return t1_Affinity < t2_Affinity;
+}
/**
* @brief Populate the o_vector with target chip pointers based on the
diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C
index a89f186ed..b188192a6 100644
--- a/src/usr/hwas/common/deconfigGard.C
+++ b/src/usr/hwas/common/deconfigGard.C
@@ -344,12 +344,6 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl(
} // deconfigureTargetsFromGardRecordsForIpl
//******************************************************************************
-bool compareTargetHuid(TargetHandle_t t1, TargetHandle_t t2)
-{
- return (t1->getAttr<ATTR_HUID>() < t2->getAttr<ATTR_HUID>());
-}
-
-//******************************************************************************
errlHndl_t DeconfigGard::processFieldCoreOverride()
{
HWAS_DBG("Process Field Core Override FCO");
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index a74518faf..7dc95ff1b 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -45,7 +45,6 @@
#include <hwas/common/deconfigGard.H>
#include <hwas/common/hwas_reasoncodes.H>
#include <targeting/common/utilFilter.H>
-#include <hwas/common/deconfigGard.H>
namespace HWAS
{
@@ -66,10 +65,6 @@ TRAC_INIT(&g_trac_imp_hwas, "HWAS_I", 1024 );
#endif
// SORT functions that we'll use for PR keyword processing
-bool compareTargetHUID(TargetHandle_t t1, TargetHandle_t t2)
-{
- return (t1->getAttr<ATTR_HUID>() < t2->getAttr<ATTR_HUID>());
-}
bool compareProcGroup(procRestrict_t t1, procRestrict_t t2)
{
if (t1.group == t2.group)
@@ -80,6 +75,11 @@ bool compareProcGroup(procRestrict_t t1, procRestrict_t t2)
return (t1.group < t2.group);
}
+bool compareAffinity(const TargetInfo t1, const TargetInfo t2)
+{
+ return t1.affinityPath < t2.affinityPath;
+}
+
/**
* @brief simple helper fn to get and set hwas state to poweredOn,
* present, functional
@@ -183,7 +183,8 @@ errlHndl_t discoverTargets()
// sort the list by ATTR_HUID to ensure that we
// start at the same place each time
std::sort(pCheckPres.begin(), pCheckPres.end(),
- compareTargetHUID);
+ compareTargetHuid);
+
for (TargetHandleList::const_iterator pTarget_it = pCheckPres.begin();
pTarget_it != pCheckPres.end();
++pTarget_it
@@ -472,143 +473,10 @@ errlHndl_t discoverTargets()
break;
}
- HWAS_INF("discoverTargets:Find functional MCSs"
- " which should be non-functional ");
-
- //get the membufs
- TargetHandleList l_funcMembufTargetList;
- getAllChips(l_funcMembufTargetList, TYPE_MEMBUF, true );
-
- //get the mcss
- TargetHandleList l_funcMCSTargetList;
- getAllChiplets(l_funcMCSTargetList, TYPE_MCS, true );
-
- TargetHandleList::iterator pMCSTarget_it = l_funcMCSTargetList.begin();
- while (pMCSTarget_it != l_funcMCSTargetList.end())
- {
- TargetHandle_t l_MCSTarget = *pMCSTarget_it;
- EntityPath l_MCSAffinityPath =
- l_MCSTarget->getAttr<ATTR_AFFINITY_PATH>();
-
- bool l_functMembufFound = false;
- HWAS_DBG("discoverTargets: MCS %.8X is functional",
- l_MCSTarget->getAttr<ATTR_HUID>());
-
- for (TargetHandleList::iterator
- pMembufTarget_it = l_funcMembufTargetList.begin();
- pMembufTarget_it != l_funcMembufTargetList.end();
- ++pMembufTarget_it)
- {
- TargetHandle_t l_MembufTarget = *pMembufTarget_it;
- EntityPath l_MembufAffinityPath =
- l_MembufTarget->getAttr<ATTR_AFFINITY_PATH>();
-
- l_functMembufFound =
- l_MCSAffinityPath.equals(l_MembufAffinityPath,
- l_MCSAffinityPath.size());
- if (l_functMembufFound == true)
- {
- //found a functional membuf so don't need to look further
- //can also remove the membuf from the list since a membuf
- //should not match two MCSs
- pMembufTarget_it=
- l_funcMembufTargetList.erase(pMembufTarget_it);
- HWAS_DBG("discoverTargets: MEMBUF %.8X is "
- "functional, assoicated with MCS %.8X",
- l_MembufTarget->getAttr<ATTR_HUID>(),
- l_MCSTarget->getAttr<ATTR_HUID>());
- break;
- }
-
- }
- if (l_functMembufFound)
- {
- //remove functional MCS associated with functional membufs from
- //the list of functional MCS
- pMCSTarget_it=l_funcMCSTargetList.erase(pMCSTarget_it);
- }
- else
- {
- ++pMCSTarget_it;
- }
- }
-
- //should now have a list of functional MCS that have no functional
- //membufs
- for (TargetHandleList::const_iterator
- pMCSTarget_it = l_funcMCSTargetList.begin();
- pMCSTarget_it != l_funcMCSTargetList.end();
- ++pMCSTarget_it)
- {
- TargetHandle_t l_MCSTarget = *pMCSTarget_it;
- //indicate that the MCS should be disabled because there is a
- //non functional membuf or no membufs associated with this MCS
- enableHwasState(l_MCSTarget,true,false,
- HWAS::DeconfigGard::DECONFIGURED_BY_NO_CHILD_MEMBUF);
-
-
-
- HWAS_INF("discoverTargets: MCS %.8X mark as present, not functional",
- l_MCSTarget->getAttr<ATTR_HUID>() );
- }
-
- // Get list of non-functional Centaurs
- TargetHandleList l_nonFuncCentaurs;
- getChipResources(l_nonFuncCentaurs, TYPE_MEMBUF,
- UTIL_FILTER_NON_FUNCTIONAL);
-
- // Some common variables used below
- TargetHandleList pChildList;
- PredicateIsFunctional isFunctional;
-
- // Iterate through list of non-functional Centaurs, and
- // set all children as non-functional
- for (TargetHandleList::const_iterator
- pCenTarget_it = l_nonFuncCentaurs.begin();
- pCenTarget_it != l_nonFuncCentaurs.end();
- ++pCenTarget_it)
- {
- // Cache current target
- TargetHandle_t l_cenTarget = *pCenTarget_it;
-
- // find all CHILD matches for this target and deconfigure them
- targetService().getAssociated(pChildList, l_cenTarget,
- TargetService::CHILD, TargetService::ALL, &isFunctional);
- for (TargetHandleList::iterator pChild_it = pChildList.begin();
- pChild_it != pChildList.end();
- ++pChild_it)
- {
- TargetHandle_t l_childTarget = *pChild_it;
- //non functional membuf or no membufs associated with this MCS
- enableHwasState(l_childTarget,true,false,
- HWAS::DeconfigGard::DECONFIGURED_BY_NO_PARENT_MEMBUF);
- HWAS_INF("discoverTargets: Target %.8X mark as present"
- ", not functional due to non-functional parent"
- " Centaur",
- l_childTarget->getAttr<ATTR_HUID>() );
- }
-
- // find all CHILD_BY_AFFINITY matches for this target and
- // deconfigure them
- targetService().getAssociated(pChildList, l_cenTarget,
- TargetService::CHILD_BY_AFFINITY, TargetService::ALL,
- &isFunctional);
- for (TargetHandleList::iterator pChild_it = pChildList.begin();
- pChild_it != pChildList.end();
- ++pChild_it)
- {
- TargetHandle_t l_affinityTarget = *pChild_it;
- //non functional membuf or no membufs associated with this MCS
- enableHwasState(l_affinityTarget,true,false,
- HWAS::DeconfigGard::DECONFIGURED_BY_NO_PARENT_MEMBUF);
- HWAS_INF("discoverTargets: Target %.8X mark as present"
- ", not functional due to non-functional parent"
- " Centaur",
- l_affinityTarget->getAttr<ATTR_HUID>() );
- }
- }
-
-
+ // call invokePresentByAssoc() to obtain functional MCS's, MEMBUFs, and
+ // DIMM's, call algorithm function presentByAssoc() to determine
+ // targets that need to be deconfigured
+ invokePresentByAssoc();
} while (0);
@@ -688,7 +556,7 @@ errlHndl_t restrictEXunits(
// sort the list by ATTR_HUID to ensure that we
// start at the same place each time
std::sort(pEXList[i].begin(), pEXList[i].end(),
- compareTargetHUID);
+ compareTargetHuid);
// keep a pointer into that list
pEX_it[i] = pEXList[i].begin();
@@ -1077,5 +945,298 @@ errlHndl_t checkMinimumHardware(const TARGETING::ConstTargetHandle_t i_node)
return l_errl ;
} // checkMinimumHardware
+/**
+ * @brief Checks if both targets have the same paths up to a certain number
+ * of path elements, determined by the smaller affinity path.
+ *
+ * @param[in] i_t1 TargetInfo containing the first target's affinity path
+ * @param[in] i_t2 TargetInfo containing the second target's affinity path
+ */
+bool isSameSubPath(TargetInfo i_t1, TargetInfo i_t2)
+{
+ size_t l_size = std::min(i_t1.affinityPath.size(),
+ i_t2.affinityPath.size());
+ return i_t1.affinityPath.equals(i_t2.affinityPath, l_size);
+}
+
+/**
+ * @brief Deconfigures a target based on type
+ *
+ * Called by invokePresentByAssoc() after presentByAssoc() is called
+ *
+ * @param[in] i_targInfo TargetInfo for the target to be deconfigured
+ */
+void deconfigPresentByAssoc(TargetInfo i_targInfo)
+{
+ TargetHandleList pChildList;
+
+ // find all CHILD matches for this target and deconfigure them
+ getChildChiplets(pChildList, i_targInfo.pThisTarget, TYPE_NA);
+
+ for (TargetHandleList::iterator pChild_it = pChildList.begin();
+ pChild_it != pChildList.end();
+ ++pChild_it)
+ {
+ TargetHandle_t l_childTarget = *pChild_it;
+ enableHwasState(l_childTarget, true, false, i_targInfo.reason);
+ HWAS_INF("deconfigPresentByAssoc: Target %.8X mark as present"
+ ", not functional due to non-functional parent"
+ " Centaur",
+ l_childTarget->getAttr<ATTR_HUID>() );
+ }
+
+ // find all CHILD_BY_AFFINITY matches for this target and deconfigure them
+ getChildAffinityTargets(pChildList, i_targInfo.pThisTarget,
+ CLASS_NA ,TYPE_NA);
+
+ for (TargetHandleList::iterator pChild_it = pChildList.begin();
+ pChild_it != pChildList.end();
+ ++pChild_it)
+ {
+ TargetHandle_t l_affinityTarget = *pChild_it;
+ enableHwasState(l_affinityTarget,true,false, i_targInfo.reason);
+ HWAS_INF("deconfigPresentByAssoc: Target %.8X mark as present"
+ ", not functional due to non-functional parent"
+ " Centaur",
+ l_affinityTarget->getAttr<ATTR_HUID>() );
+ }
+
+ // deconfigure the target itself
+ enableHwasState(i_targInfo.pThisTarget,true,false,i_targInfo.reason);
+ HWAS_INF("deconfigPresentByAssoc: Target %.8X mark as present, not functional",
+ i_targInfo.huid );
+
+}
+
+void invokePresentByAssoc()
+{
+ HWAS_INF("invokePresentByAssoc enter");
+
+ // make one list
+ TargetHandleList l_funcTargetList;
+
+ // get the mcss
+ TargetHandleList l_funcMCSTargetList;
+ getAllChiplets(l_funcMCSTargetList, TYPE_MCS, true );
+ l_funcTargetList.insert(l_funcTargetList.begin(),
+ l_funcMCSTargetList.begin(),
+ l_funcMCSTargetList.end());
+
+ // get the membufs
+ TargetHandleList l_funcMembufTargetList;
+ getAllChips(l_funcMembufTargetList, TYPE_MEMBUF, true );
+ l_funcTargetList.insert(l_funcTargetList.begin(),
+ l_funcMembufTargetList.begin(),
+ l_funcMembufTargetList.end());
+
+ // get the dimms
+ TargetHandleList l_funcDIMMTargetList;
+ getAllLogicalCards(l_funcDIMMTargetList, TYPE_DIMM, true );
+ l_funcTargetList.insert(l_funcTargetList.begin(),
+ l_funcDIMMTargetList.begin(),
+ l_funcDIMMTargetList.end());
+
+ // Define vectors of TargetInfo structs to be used in presentByAssoc
+ TargetInfoVector l_targInfo;
+ TargetInfoVector l_targToDeconfig;
+ do
+ {
+ // Iterate through targets and populate l_targInfo vector
+ for (TargetHandleList::const_iterator
+ l_targIter = l_funcTargetList.begin();
+ l_targIter != l_funcTargetList.end();
+ ++l_targIter)
+ {
+ TargetInfo l_TargetInfo;
+ l_TargetInfo.pThisTarget =
+ *l_targIter;
+ l_TargetInfo.affinityPath =
+ (*l_targIter)->getAttr<ATTR_AFFINITY_PATH>();
+ l_TargetInfo.huid =
+ (*l_targIter)->getAttr<ATTR_HUID>();
+ l_TargetInfo.type =
+ (*l_targIter)->getAttr<ATTR_TYPE>();
+ l_TargetInfo.functional = true;
+ l_targInfo.push_back(l_TargetInfo);
+ }
+
+ // Call presentByAssoc to take the functional targets in l_targInfo
+ // and determine which ones need to be deconfigured
+ presentByAssoc(l_targInfo, l_targToDeconfig);
+
+ // Deconfigure targets in l_targToDeconfig
+ for (TargetInfoVector::const_iterator
+ l_targIter = l_targToDeconfig.begin();
+ l_targIter != l_targToDeconfig.end();
+ ++l_targIter)
+ {
+ deconfigPresentByAssoc(*l_targIter);
+ }
+
+ } while(0);
+}
+
+void presentByAssoc(TargetInfoVector& o_funcTargets,
+ TargetInfoVector& o_targToDeconfig)
+{
+ HWAS_INF("presentByAssoc entry");
+
+ // Sort entire vector by affinity path. This provides the algorithm with
+ // an ordered vector of targets, making it easy to check if a MCS has a
+ // MEMBUF, a MEMBUF has a MCS and DIMM, and a DIMM has a MEMBUF.
+ std::sort(o_funcTargets.begin(), o_funcTargets.end(),
+ compareAffinity);
+
+ // Keep track of the most recently seen MCS and MEMBUF. This allows the
+ // algorithm to quickly check if targets share a MCS or MEMBUF and used
+ // for backtracking after deleting a target from the vector
+ size_t l_MCSIndex = __INT_MAX__;
+ size_t l_MEMBUFIndex = __INT_MAX__;
+ size_t i = 0;
+
+ // Perform presentByAssoc algorithm
+ while ( i < o_funcTargets.size() )
+ {
+ // INIT STEPS:
+ // Reset iterator, check functional state, check if the next taget in
+ // the vector is valid or even needed
+
+ // Get iterator to erase elements from vector when needed
+ std::vector<TargetInfo>::iterator it = o_funcTargets.begin();
+ std::advance(it,i);
+
+ // If target is already marked non-functional, delete from vector and
+ // move on.
+ TargetInfo& l_curTargetInfo = *it;
+ if (!l_curTargetInfo.functional)
+ {
+ o_funcTargets.erase(it);
+ continue;
+ }
+
+ // Check if there is a next target and set it
+ // Don't need to check next target with a DIMM
+ TargetInfo* l_nextTargetInfo = NULL;
+ if ( (i + 1) < o_funcTargets.size() &&
+ l_curTargetInfo.type != TYPE_DIMM )
+ {
+ l_nextTargetInfo = it + 1;
+ }
+
+ // CASE MCS
+ if ( l_curTargetInfo.type == TYPE_MCS )
+ {
+ // No Child MEMBUFs
+ // If next is not a MEMBUF sharing the same MCS, deconfig MCS
+ if ( l_nextTargetInfo == NULL ||
+ l_nextTargetInfo->type != TYPE_MEMBUF ||
+ !isSameSubPath(l_curTargetInfo, *l_nextTargetInfo) )
+ {
+ // Disable MCS - NO_CHILD_MEMBUF
+ l_curTargetInfo.reason =
+ HWAS::DeconfigGard::DECONFIGURED_BY_NO_CHILD_MEMBUF;
+
+ // Add target to Deconfig vector to be deconfigured later
+ o_targToDeconfig.push_back(l_curTargetInfo);
+ // Remove target from funcTargets
+ o_funcTargets.erase(it);
+ }
+ // Update MCS Index
+ else
+ {
+ l_MCSIndex = i;
+ i++;
+ }
+ }
+
+ // CASE MEMBUF
+ else if ( l_curTargetInfo.type == TYPE_MEMBUF )
+ {
+ // No Child DIMMs
+ // If next is not a DIMM sharing the same MEMBUF, deconfig MEMBUF
+ if ( l_nextTargetInfo == NULL ||
+ l_nextTargetInfo->type != TYPE_DIMM ||
+ !isSameSubPath(l_curTargetInfo, *l_nextTargetInfo) )
+ {
+ // Disable MEMBUF - NO_CHILD_DIMM
+ l_curTargetInfo.reason =
+ HWAS::DeconfigGard::DECONFIGURED_BY_NO_CHILD_DIMM;
+ }
+ // No Parent MCS
+ // If MEMBUF doesn't share the same MCS as MCSIndex, deconfig MEMBUF
+ else if ( l_MCSIndex == __INT_MAX__ ||
+ !isSameSubPath(l_curTargetInfo, o_funcTargets[l_MCSIndex]))
+ {
+ // Disable MEMBUF - NO_PARENT_MCS
+ l_curTargetInfo.reason =
+ HWAS::DeconfigGard::DECONFIGURED_BY_NO_PARENT_MCS;
+ }
+ // Update MEMBUF Index
+ else
+ {
+ l_MEMBUFIndex = i;
+ i++;
+ continue;
+ }
+
+ // Add target to deconfig vector to be deconfigured later
+ o_targToDeconfig.push_back(l_curTargetInfo);
+ // Remove target from funcTargets
+ o_funcTargets.erase(it);
+
+ // Backtrack to last MCS
+ if ( l_MCSIndex != __INT_MAX__ )
+ {
+ i = l_MCSIndex;
+ }
+ // Backtrack to beginning if no MCS has been seen yet
+ else
+ {
+ i = 0;
+ }
+ }
+
+ // CASE DIMM
+ else if ( l_curTargetInfo.type == TYPE_DIMM )
+ {
+ // No Parent MEMBUF
+ // If DIMM does not share the same MEMBUF as MEMBUFIndex,
+ // deconfig DIMM
+ if ( l_MEMBUFIndex == __INT_MAX__ ||
+ !isSameSubPath(l_curTargetInfo, o_funcTargets[l_MEMBUFIndex]))
+ {
+ // Disable DIMM
+ l_curTargetInfo.reason =
+ HWAS::DeconfigGard::DECONFIGURED_BY_NO_PARENT_MEMBUF;
+
+ // Add target to deconfig vector to be deconfigured later
+ o_targToDeconfig.push_back(l_curTargetInfo);
+ // Remove target from funcTargets
+ o_funcTargets.erase(it);
+
+ // Backtrack to last MEMBUF
+ if ( l_MEMBUFIndex != __INT_MAX__ )
+ {
+ i = l_MEMBUFIndex;
+ }
+ // Backtrack to last MCS if no MEMBUF has been seen yet
+ else if ( l_MCSIndex != __INT_MAX__)
+ {
+ i = l_MCSIndex;
+ }
+ // Backtrack to beginning if no MCS has been seen yet
+ else
+ {
+ i = 0;
+ }
+ }
+ else
+ {
+ i++;
+ }
+ }
+ } // presentByAssoc algorithm
+}
+
}; // end namespace
diff --git a/src/usr/hwas/test/hwasGardTest.H b/src/usr/hwas/test/hwasGardTest.H
index 5ed0c50a9..952c9e968 100644
--- a/src/usr/hwas/test/hwasGardTest.H
+++ b/src/usr/hwas/test/hwasGardTest.H
@@ -2855,6 +2855,315 @@ public:
TS_FAIL("testDeconfigureAssocProc8: incorrect configuration returned");
}
}
+
+ /**
+ * @brief Test Deconfig Present Association 1
+ */
+ void testdeconfigPresentByAssoc1()
+ {
+ TS_TRACE(INFO_MRK "testDeconfigureAssocProc1: Started");
+ // This tests the scenario where there is one mcs, membuff, and dimm
+ // This is done to ensure that the algorithm works on each edge case
+
+ TargetInfoVector l_targInfo;
+ TargetInfoVector l_targToDeconfig;
+ TargetInfo l_TargetInfo;
+
+ l_TargetInfo.pThisTarget = NULL;
+ EntityPath l_ep(TARGETING::EntityPath::PATH_AFFINITY);
+ l_TargetInfo.functional = 1;
+
+ // MCS only
+ l_ep.addLast(TYPE_MCS, 0);
+ l_TargetInfo.affinityPath = l_ep;
+ l_TargetInfo.huid = 0;
+ l_TargetInfo.type = TYPE_MCS;
+
+ l_targInfo.push_back(l_TargetInfo);
+
+ presentByAssoc(l_targInfo, l_targToDeconfig);
+
+ // MEMBUF only
+ l_ep.addLast(TYPE_MEMBUF, 0);
+ l_TargetInfo.affinityPath = l_ep;
+ l_TargetInfo.huid = 1;
+ l_TargetInfo.type = TYPE_MEMBUF;
+ l_targInfo.push_back(l_TargetInfo);
+
+ presentByAssoc(l_targInfo, l_targToDeconfig);
+
+ // DIMM only
+ l_ep.addLast(TYPE_DIMM, 0);
+ l_TargetInfo.affinityPath = l_ep;
+ l_TargetInfo.huid = 2;
+ l_TargetInfo.type = TYPE_DIMM;
+ l_targInfo.push_back(l_TargetInfo);
+
+ presentByAssoc(l_targInfo, l_targToDeconfig);
+
+ // Check result
+ if (l_targToDeconfig.size() == 3 &&
+ l_targToDeconfig[0].huid == 0 &&
+ l_targToDeconfig[1].huid == 1 &&
+ l_targToDeconfig[2].huid == 2 )
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc1: Success");
+ }
+ else
+ {
+ TS_FAIL("testdeconfigPresentByAssoc1: incorrect configuration returned");
+ }
+ }
+
+ /**
+ * @brief Test Deconfig Present Association 2
+ */
+ void testdeconfigPresentByAssoc2()
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc2: Started");
+ // This test the scenario where MCS Group 0 does not have a membuf and
+ // is marked for deconfigure.
+
+ // User-defined number of targets
+ size_t NUM_TARGS = 4;
+
+ // Input target vector
+ TargetInfoVector l_targets;
+ TargetInfo l_TargInfo;
+ EntityPath l_ep(TARGETING::EntityPath::PATH_AFFINITY);
+ l_TargInfo.affinityPath = l_ep;
+ l_targets.insert(l_targets.begin(), NUM_TARGS, l_TargInfo);
+ // Output target vector
+ TargetInfoVector l_targToDeconfig;
+
+ // Add MCS Group 0
+ l_targets[0].pThisTarget = NULL;
+ l_targets[0].functional = 1;
+ l_targets[0].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[0].huid = 0;
+ l_targets[0].type = TYPE_MCS;
+
+ // Add MEMBUF Group 1
+ l_targets[1].pThisTarget = NULL;
+ l_targets[1].functional = 1;
+ l_targets[1].affinityPath.addLast(TYPE_MCS, 1);
+ l_targets[1].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[1].huid = 1;
+ l_targets[1].type = TYPE_MEMBUF;
+
+ // Add DIMM Group 1
+ l_targets[2].pThisTarget = NULL;
+ l_targets[2].functional = 1;
+ l_targets[2].affinityPath.addLast(TYPE_MCS, 1);
+ l_targets[2].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[2].affinityPath.addLast(TYPE_DIMM, 0);
+ l_targets[2].huid = 2;
+ l_targets[2].type = TYPE_DIMM;
+
+ // Add MCS Group 1
+ l_targets[3].pThisTarget = NULL;
+ l_targets[3].functional = 1;
+ l_targets[3].affinityPath.addLast(TYPE_MCS, 1);
+ l_targets[3].huid = 3;
+ l_targets[3].type = TYPE_MCS;
+
+ presentByAssoc(l_targets, l_targToDeconfig);
+
+ // Check result
+ if (l_targToDeconfig.size() == 1 &&
+ l_targToDeconfig[0].huid == 0 )
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc2: Success");
+ }
+ else
+ {
+ TS_FAIL("testdeconfigPresentByAssoc2: incorrect configuration returned");
+ }
+ }
+
+ /**
+ * @brief Test Deconfig Present Association 3
+ */
+ void testdeconfigPresentByAssoc3()
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc3: Started");
+ // This test the scenario where MEMBUF Group 1 has no MCS and then
+ // DIMM Group 1 has no MEMBUF because MEMBUF 1 will be marked for
+ // deconfigure
+
+ // User-defined number of targets
+ size_t NUM_TARGS = 5;
+
+ // Input target vector
+ TargetInfoVector l_targets;
+ TargetInfo l_TargInfo;
+ EntityPath l_ep(TARGETING::EntityPath::PATH_AFFINITY);
+ l_TargInfo.affinityPath = l_ep;
+ l_targets.insert(l_targets.begin(), NUM_TARGS, l_TargInfo);
+ // Output target vector
+ TargetInfoVector l_targToDeconfig;
+
+ // Add MCS Group 0
+ l_targets[0].pThisTarget = NULL;
+ l_targets[0].functional = 1;
+ l_targets[0].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[0].huid = 0;
+ l_targets[0].type = TYPE_MCS;
+
+ // Add MEMBUF Group 0
+ l_targets[1].pThisTarget = NULL;
+ l_targets[1].functional = 1;
+ l_targets[1].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[1].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[1].huid = 1;
+ l_targets[1].type = TYPE_MEMBUF;
+
+ // Add MEMBUF Group 1
+ l_targets[2].pThisTarget = NULL;
+ l_targets[2].functional = 1;
+ l_targets[2].affinityPath.addLast(TYPE_MCS, 1);
+ l_targets[2].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[2].huid = 2;
+ l_targets[2].type = TYPE_MEMBUF;
+
+
+ // Add DIMM Group 0
+ l_targets[3].pThisTarget = NULL;
+ l_targets[3].functional = 1;
+ l_targets[3].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[3].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[3].affinityPath.addLast(TYPE_DIMM, 0);
+ l_targets[3].huid = 3;
+ l_targets[3].type = TYPE_DIMM;
+
+ // Add DIMM Group 1
+ l_targets[4].pThisTarget = NULL;
+ l_targets[4].functional = 1;
+ l_targets[4].affinityPath.addLast(TYPE_MCS, 1);
+ l_targets[4].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[4].affinityPath.addLast(TYPE_DIMM, 0);
+ l_targets[4].huid = 4;
+ l_targets[4].type = TYPE_DIMM;
+
+ presentByAssoc(l_targets, l_targToDeconfig);
+
+ // Check result
+ if (l_targToDeconfig.size() == 2 &&
+ l_targToDeconfig[0].huid == 2 &&
+ l_targToDeconfig[1].huid == 4 )
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc3: Success");
+ }
+ else
+ {
+ TS_FAIL("testdeconfigPresentByAssoc3: incorrect configuration returned");
+ }
+ }
+
+ /**
+ * @brief Test Deconfig Present Association 4
+ */
+ void testdeconfigPresentByAssoc4()
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc4: Started");
+ // This test the scenario where MEMBUF Group 0 has no DIMMs causing
+ // MCS Group 0 to also be deconfigured.
+
+ // User-defined number of targets
+ size_t NUM_TARGS = 2;
+
+ // Input target vector
+ TargetInfoVector l_targets;
+ TargetInfo l_TargInfo;
+ EntityPath l_ep(TARGETING::EntityPath::PATH_AFFINITY);
+ l_TargInfo.affinityPath = l_ep;
+ l_targets.insert(l_targets.begin(), NUM_TARGS, l_TargInfo);
+ // Output target vector
+ TargetInfoVector l_targToDeconfig;
+
+ // Add MCS Group 0
+ l_targets[0].pThisTarget = NULL;
+ l_targets[0].functional = 1;
+ l_targets[0].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[0].huid = 0;
+ l_targets[0].type = TYPE_MCS;
+
+ // Add MEMBUF Group 0
+ l_targets[1].pThisTarget = NULL;
+ l_targets[1].functional = 1;
+ l_targets[1].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[1].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[1].huid = 1;
+ l_targets[1].type = TYPE_MEMBUF;
+
+ presentByAssoc(l_targets, l_targToDeconfig);
+
+ // Check result
+ if (l_targToDeconfig.size() == 2 &&
+ l_targToDeconfig[0].huid == 1 &&
+ l_targToDeconfig[1].huid == 0 )
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc4: Success");
+ }
+ else
+ {
+ TS_FAIL("testdeconfigPresentByAssoc4: incorrect configuration returned");
+ }
+ }
+
+ /**
+ * @brief Test Deconfig Present Association 5
+ */
+ void testdeconfigPresentByAssoc5()
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc5: Started");
+ // This test the scenario where MEMBUF Group 0 and DIMM Group 0 having
+ // no MCS. This tests the MCSINDEX edge case because one never existed
+
+ // User-defined number of targets
+ size_t NUM_TARGS = 2;
+
+ // Input target vector
+ TargetInfoVector l_targets;
+ TargetInfo l_TargInfo;
+ EntityPath l_ep(TARGETING::EntityPath::PATH_AFFINITY);
+ l_TargInfo.affinityPath = l_ep;
+ l_targets.insert(l_targets.begin(), NUM_TARGS, l_TargInfo);
+ // Output target vector
+ TargetInfoVector l_targToDeconfig;
+
+ // Add MEMBUF Group 0
+ l_targets[0].pThisTarget = NULL;
+ l_targets[0].functional = 1;
+ l_targets[0].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[0].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[0].huid = 0;
+ l_targets[0].type = TYPE_MEMBUF;
+
+ // Add DIMM Group 0
+ l_targets[1].pThisTarget = NULL;
+ l_targets[1].functional = 1;
+ l_targets[1].affinityPath.addLast(TYPE_MCS, 0);
+ l_targets[1].affinityPath.addLast(TYPE_MEMBUF, 0);
+ l_targets[1].affinityPath.addLast(TYPE_DIMM, 0);
+ l_targets[1].huid = 1;
+ l_targets[1].type = TYPE_DIMM;
+
+ presentByAssoc(l_targets, l_targToDeconfig);
+
+ // Check result
+ if (l_targToDeconfig.size() == 2 &&
+ l_targToDeconfig[0].huid == 0 &&
+ l_targToDeconfig[1].huid == 1 )
+ {
+ TS_TRACE(INFO_MRK "testdeconfigPresentByAssoc5: Success");
+ }
+ else
+ {
+ TS_FAIL("testdeconfigPresentByAssoc5: incorrect configuration returned");
+ }
+ }
+
};
#endif
diff --git a/src/usr/targeting/common/entitypath.C b/src/usr/targeting/common/entitypath.C
index 6a58331a0..b670422a8 100644
--- a/src/usr/targeting/common/entitypath.C
+++ b/src/usr/targeting/common/entitypath.C
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <algorithm>
// This component
#include <attributeenums.H>
@@ -187,6 +188,36 @@ bool EntityPath::operator==(
}
//******************************************************************************
+// EntityPath::operator<
+//******************************************************************************
+
+bool EntityPath::operator<(const EntityPath &i_rhs) const
+{
+ #define TARG_FN "operator<(...)"
+
+ if (iv_type != i_rhs.iv_type)
+ {
+ return iv_type < i_rhs.iv_type;
+ }
+
+ size_t size = std::min(iv_size,i_rhs.iv_size)*sizeof(PathElement);
+ int result = memcmp(&iv_pathElement[0], &i_rhs.iv_pathElement[0], size);
+
+ // lhs == rhs
+ if ( result == 0 )
+ {
+ return iv_size < i_rhs.iv_size;
+ }
+ else
+ {
+ return ( result < 0 );
+ }
+
+ #undef TARG_FN
+}
+
+
+//******************************************************************************
// EntityPath::equals
//******************************************************************************
diff --git a/src/usr/targeting/common/utilFilter.C b/src/usr/targeting/common/utilFilter.C
index f460ff93b..6e3986ddb 100644
--- a/src/usr/targeting/common/utilFilter.C
+++ b/src/usr/targeting/common/utilFilter.C
@@ -46,14 +46,6 @@ namespace TARGETING
#define TARG_CLASS ""
-
-// Predicate function for sorting by HUID
-bool compareTargetHuid(TargetHandle_t t1, TargetHandle_t t2)
-{
- return (t1->getAttr<ATTR_HUID>() < t2->getAttr<ATTR_HUID>());
-}
-
-
/**
* @brief Populate the o_vector with target object pointers based on the
* requested class, type, and functional state.
OpenPOWER on IntegriCloud