From d545103be504fc8ec6a23c4ad5ff08297b6fc1fa Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Thu, 29 Mar 2012 10:01:24 -0500 Subject: Fix FSI FFDC collection thread bug Fixing a possible multi-threading issue in how the FSI driver collects FFDC. I am keeping track of the Task that hit the error to avoid hitting the mutex twice. Change-Id: Ic48cc046e1a23c67df84802c51307be645a06a8d RTC: 35287 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/806 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/usr/fsi/fsidd.C | 19 +++++++++++-------- src/usr/fsi/fsidd.H | 6 ++++-- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C index 94423c3da..59d4f8438 100644 --- a/src/usr/fsi/fsidd.C +++ b/src/usr/fsi/fsidd.C @@ -626,6 +626,7 @@ errlHndl_t FsiDD::initializeHardware() */ FsiDD::FsiDD() :iv_master(NULL) +,iv_ffdcTask(0) { TRACFCOMP(g_trac_fsi, "FsiDD::FsiDD()>"); @@ -714,10 +715,10 @@ errlHndl_t FsiDD::read(const FsiAddrInfo_t& i_addrInfo, // atomic section >> l_mutex - = (i_addrInfo.opbTarg)->getHbMutexAttr(); + = (i_addrInfo.opbTarg)->getHbMutexAttr(); - // skip the mutex lock if we're already inside a previous operation - if( !iv_ffdcCollection ) + if( (iv_ffdcTask != 0) // performance hack for typical case + && (iv_ffdcTask != task_gettid()) ) { mutex_lock(l_mutex); need_unlock = true; @@ -794,8 +795,8 @@ errlHndl_t FsiDD::write(const FsiAddrInfo_t& i_addrInfo, l_mutex = (i_addrInfo.opbTarg)->getHbMutexAttr(); - // skip the mutex lock if we're already inside a previous operation - if( !iv_ffdcCollection ) + if( (iv_ffdcTask != 0) // performance hack for typical case + && (iv_ffdcTask != task_gettid()) ) { mutex_lock(l_mutex); need_unlock = true; @@ -870,9 +871,10 @@ errlHndl_t FsiDD::handleOpbErrors(const FsiAddrInfo_t& i_addrInfo, TWO_UINT32_TO_UINT64(i_opbStatReg,0)); // Collect some FFDC but avoid an infinite loop - if( !iv_ffdcCollection ) + if( iv_ffdcTask != 0 ) { - iv_ffdcCollection = true; + iv_ffdcTask = task_gettid(); + uint32_t data = 0; errlHndl_t l_err2 = NULL; @@ -917,7 +919,8 @@ errlHndl_t FsiDD::handleOpbErrors(const FsiAddrInfo_t& i_addrInfo, } //MAGIC_INSTRUCTION(MAGIC_BREAK); - iv_ffdcCollection = false; + + iv_ffdcTask = 0; } l_err->collectTrace("FSI"); diff --git a/src/usr/fsi/fsidd.H b/src/usr/fsi/fsidd.H index 69060544e..51dad9f54 100644 --- a/src/usr/fsi/fsidd.H +++ b/src/usr/fsi/fsidd.H @@ -29,6 +29,7 @@ #include #include #include +#include /** @file fsidd.H @@ -245,6 +246,7 @@ class FsiDD * * @param[in] i_addrInfo FSI addressing information * @param[in] i_opbStatReg OPB Status bits (OPB_REG_STAT[0:31]) + * @param[in] i_relFsiAddr Relative FSI Address that was being accessed * * @return errlHndl_t NULL on success */ @@ -458,9 +460,9 @@ class FsiDD TARGETING::Target* iv_master; /** - * Flag to avoid infinite recursion + * Non-zero if a Task is currently collecting FFDC */ - bool iv_ffdcCollection; + tid_t iv_ffdcTask; private: -- cgit v1.2.1