summaryrefslogtreecommitdiffstats
path: root/src/usr/mbox/mailboxsp.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/mbox/mailboxsp.C')
-rw-r--r--src/usr/mbox/mailboxsp.C96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 7bd1ccde5..926dcdc2d 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -44,6 +44,7 @@
#include <arch/ppc.H>
#include <errl/errlmanager.H>
#include <sys/misc.h>
+#include <util/misc.H>
#include <errl/errludprintk.H>
#include <errno.h>
#include <kernel/console.H>
@@ -82,6 +83,7 @@ MailboxSp::MailboxSp()
iv_sendq(),
iv_respondq(),
iv_dmaBuffer(),
+ iv_dmaRequestWatchdog(0),
iv_trgt(NULL),
iv_shutdown_msg(NULL),
iv_rts(true),
@@ -832,6 +834,17 @@ void MailboxSp::send_msg(mbox_msg_t * i_msg)
&iv_msg_to_send,
mbox_msg_len,
DeviceFW::MAILBOX);
+
+ // Create a watchdog task that will run for 60 seconds
+ // if there is no response in 60 seconds then dbg info will
+ // be printed in the slow trace buffer
+ if(iv_msg_to_send.msg_payload.type == MSG_REQUEST_DMA_BUFFERS
+ && !Util::isSimicsRunning()
+ && !iv_dmaRequestWatchdog)
+ {
+ iv_dmaRequestWatchdog = task_create(&watchdogTimeoutTask, this);
+ assert (iv_dmaRequestWatchdog > 0 );
+ }
}
if(err)
@@ -1448,6 +1461,89 @@ void MailboxSp::sendReclaimDmaBfrsMsg( mbox_msg_t & i_mbox_msg )
return;
}
+void * MailboxSp::watchdogTimeoutTask(void * i_mailboxSp)
+{
+ // We don't want this to be a zombie because parent keeps going
+ task_detach();
+
+ // create a task which we can wait, this way we can print
+ // an error message if the taskWorker crashes
+ tid_t l_tid = task_create( &watchdogTimeoutTaskWorker, i_mailboxSp);
+ assert (l_tid > 0 );
+
+ int l_status = 0;
+ void* l_rc = nullptr;
+
+ tid_t l_tidRc = task_wait_tid(l_tid, &l_status, &l_rc);
+
+ if(l_status == TASK_STATUS_CRASHED)
+ {
+ TRACFCOMP(g_trac_mbox,
+ ERR_MRK
+ "MailboxSp::watchdogTimeoutTask - "
+ "Watchdog timeout crashed!! %lx", l_tidRc);
+ }
+
+ return nullptr;
+}
+
+void * MailboxSp::watchdogTimeoutTaskWorker(void * i_mailboxSp)
+{
+
+ uint64_t MAX_TIMEOUT = 200000000000; // nanoseconds
+ uint64_t POLL_RATE = 1000000; // nanoseconds
+ uint64_t cur_timeout = 0; // nanoseconds
+ errlHndl_t err = nullptr;
+
+ assert(i_mailboxSp != nullptr, "nullptr was passed to watchdogTimeoutTaskWorker");
+
+ MailboxSp & mboxSp = *static_cast<MailboxSp *>(i_mailboxSp);
+
+ while(cur_timeout < MAX_TIMEOUT)
+ {
+ if( !mboxSp.iv_dma_pend )
+ {
+ TRACFCOMP(g_trac_mbox,
+ INFO_MRK
+ "Breaking out of watchdog because FSP responded to DMA request");
+ break;
+ }
+ // sleep for 1 ms
+ nanosleep(0, POLL_RATE);
+ cur_timeout += POLL_RATE;
+ }
+
+ if(cur_timeout >= MAX_TIMEOUT)
+ {
+ TRACFCOMP(g_trac_mbox,
+ INFO_MRK
+ "Hang during DMA request detected, dumping state information");
+ err = dumpMboxRegs();
+ if(err)
+ {
+ TRACFCOMP(g_trac_mbox,
+ INFO_MRK
+ "Error occured while dumping MBOX information");
+ err->collectTrace(MBOX_COMP_NAME);
+ errlCommit(err,MBOX_COMP_ID);
+ }
+ err = INTR::printInterruptInfo();
+ if(err)
+ {
+ TRACFCOMP(g_trac_mbox,
+ INFO_MRK
+ "Error occured while dumping INTR information");
+ err->collectTrace(INTR_COMP_NAME);
+ errlCommit(err,MBOX_COMP_ID);
+ }
+ }
+
+ //Zero out the TID so another watchdog task can be created if needed
+ mboxSp.iv_dmaRequestWatchdog = 0;
+ return nullptr;
+
+}
+
errlHndl_t MailboxSp::msgq_register(queue_id_t i_queue_id, msg_q_t i_msgQ)
{
OpenPOWER on IntegriCloud