From 046a2655125fa0b4efdafa460d7f60ac0719d669 Mon Sep 17 00:00:00 2001 From: Brian Bakke Date: Wed, 16 Aug 2017 15:56:02 -0500 Subject: [PATCH] Send "recollect dma buffers" message in TI path Change-Id: Ice352f333cc3cfca7393b335414958612834b3c8 RTC:170428 CQ:SW359697 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44706 Reviewed-by: Martin Gloff Tested-by: Jenkins Server Reviewed-by: Christian R. Geddes Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell --- src/include/usr/mbox/mboxif.H | 18 +- .../istep16/call_host_activate_master.C | 25 ++- src/usr/mbox/mailboxsp.C | 207 ++++++++++++++++-- src/usr/mbox/mailboxsp.H | 43 +++- src/usr/mbox/mbox_dma_buffer.C | 4 +- src/usr/mbox/mbox_dma_buffer.H | 30 ++- 6 files changed, 282 insertions(+), 45 deletions(-) diff --git a/src/include/usr/mbox/mboxif.H b/src/include/usr/mbox/mboxif.H index 497a22893f6..ae753429aa9 100644 --- a/src/include/usr/mbox/mboxif.H +++ b/src/include/usr/mbox/mboxif.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -59,7 +59,7 @@ namespace MBOX * Send message asynchronously * @param[in] i_q_id id, of the FSP message queue to send the msg to. * @param[in] i_msg. The message to send. - * @param[in] i_node The destination node [0-7] for IPC messages, + * @param[in] i_node The destination node [0-7] for IPC messages, * otherwise the default is FSP * * @return errlHndl_t on error. @@ -71,8 +71,8 @@ namespace MBOX * @pre For FSP mbox messages, i_msg->extra_data must be NULL If there is * no payload associated with the message. * - * @pre For FSP mbox messages, - * i_msg->extra_data = malloc(size); i_msg->data[1] = size; + * @pre For FSP mbox messages, + * i_msg->extra_data = malloc(size); i_msg->data[1] = size; * Any extra data associated with i_msg was obtained from the heap * using malloc and i_msg->data[1] contains the length of that data. * @@ -93,7 +93,7 @@ namespace MBOX * @pre io_msg->extra_data == NULL If there is no extra data is associated * with the message. * - * @pre io_msg->extra_data = malloc(size); io_msg->data[1] = size; + * @pre io_msg->extra_data = malloc(size); io_msg->data[1] = size; * Any extra data associated with io_msg was obtained from the heap * using malloc and io_msg->data[1] contains the length of that data. * @@ -114,7 +114,7 @@ namespace MBOX bool mailbox_enabled(); /** - * Suspend the mailbox. + * Suspend the mailbox. * * @param[in] i_disable_hw_int, disable interrupts from hw along * with SW suspend. Defaults to SW suspend only @@ -162,6 +162,12 @@ namespace MBOX */ void deallocate(void * i_ptr); + /** + * Reclaim any DMA buffers owned by the FSP + * @return errlHndl_t on error + */ + errlHndl_t reclaimDmaBfrsFromFsp( void ); + }; // end namespace MBOX #endif diff --git a/src/usr/isteps/istep16/call_host_activate_master.C b/src/usr/isteps/istep16/call_host_activate_master.C index a061ba96c7b..40e0d0538f4 100644 --- a/src/usr/isteps/istep16/call_host_activate_master.C +++ b/src/usr/isteps/istep16/call_host_activate_master.C @@ -166,9 +166,28 @@ void* call_host_activate_master (void *io_pArgs) //Because of a bug in how the SBE injects the IPI used to wake //up the master core, need to ensure no mailbox traffic //or even an interrupt in the interrupt presenter - // 1) suspend the mailbox with interrupt disable - // 2) tell the SBE to start the deadman timer - // 3) ensure that interrupt presenter is drained + // 1) Reclaim all DMA bfrs from the FSP + // 2) suspend the mailbox with interrupt disable + // 3) tell the SBE to start the deadman timer + // 4) ensure that interrupt presenter is drained + l_errl = MBOX::reclaimDmaBfrsFromFsp(); + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_activate_master ERROR : " + "MBOX::reclaimDmaBfrsFromFsp"); + + // if it not complete then thats okay, but we want to store the + // log away somewhere. Since we didn't get all the DMA buffers + // back its not a big deal to commit a log, even if we lose a + // DMA buffer because of it it doesn't matter that much. + // this will generate more traffic to the FSP + l_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); + errlCommit( l_errl, HWPF_COMP_ID ); + + // (do not break. keep going to suspend) + } + l_errl = MBOX::suspend(true, true); if (l_errl) { diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C index 4a968ed2706..355d5a4e3ec 100644 --- a/src/usr/mbox/mailboxsp.C +++ b/src/usr/mbox/mailboxsp.C @@ -49,6 +49,7 @@ #include #include #include +#include // Local functions namespace MBOX @@ -90,7 +91,9 @@ MailboxSp::MailboxSp() iv_allow_blk_resp(false), iv_sum_alloc(0), iv_pend_alloc(), - iv_allocAddrs() + iv_allocAddrs(), + iv_reclaim_sent_cnt(0), + iv_reclaim_rsp_cnt(0) { // mailbox target TARGETING::targetService().masterProcChipTargetHandle(iv_trgt); @@ -280,27 +283,55 @@ void MailboxSp::msgHandler() crit_assert(0); } + // note : an outstanding req dma bfrs msg + // will cause quiesce to be false if(iv_shutdown_msg && quiesced()) { - // If all DMA buffers still not owned - // try once to get them all back. - if(!iv_dmaBuffer.ownsAllBlocks() && - !iv_dmaBuffer.shutdownDmaRequestSent()) + if // all DMA buffers have been reclaimed + ( iv_dmaBuffer.ownsAllBlocks() ) { - iv_dmaBuffer.setShutdownDmaRequestSent(true); - mbox_msg_t dma_request_msg; - dma_request_msg.msg_queue_id = FSP_MAILBOX_MSGQ; - dma_request_msg.msg_payload.type = - MSG_REQUEST_DMA_BUFFERS; - dma_request_msg.msg_payload.__reserved__async = 1; - - send_msg(&dma_request_msg); + // continue with shutdown + TRACFCOMP(g_trac_mbox, + INFO_MRK"MBOXSP DMA bfrs reclaimed " + "on shutdown"); + + handleShutdown(); + } + + else if // a "reclaim bfr" msg is outstanding + ( isDmaReqBfrMsgOutstanding() ) + { + // (need to wait for the msg(s) to complete + // before sending another msg) + TRACFCOMP(g_trac_mbox, + INFO_MRK + "MailboxSp::msgHandler - " + "Wait for Reclaim Msg Completion"); } + + else if // more "reclaim bfr" msgs can be sent + ( iv_dmaBuffer.maxShutdownDmaRequestSent() == false ) + { + TRACFCOMP(g_trac_mbox, + INFO_MRK + "MailboxSp::msgHandler - " + "Send Reclaim Msg to FSP"); + + // send a "reclaim bfr" msg + iv_dmaBuffer.incrementShutdownDmaRequestSentCnt(); + sendReclaimDmaBfrsMsg(); + } + else { + // continue with shutdown + TRACFCOMP(g_trac_mbox, + INFO_MRK"MBOXSP DMA bfrs not reclaimed " + "on shutdown"); + handleShutdown(); } - } + } // end shutdown msg & quiesced if(iv_suspended && quiesced()) { @@ -364,15 +395,11 @@ void MailboxSp::msgHandler() // is not pending, but may not get them all back // at this time. // - if(!iv_dmaBuffer.ownsAllBlocks() && !iv_dma_pend) + if( !iv_dmaBuffer.ownsAllBlocks() && + !iv_dma_pend && + !isDmaReqBfrMsgOutstanding() ) { - mbox_msg_t dma_request_msg; - dma_request_msg.msg_queue_id = FSP_MAILBOX_MSGQ; - dma_request_msg.msg_payload.type = - MSG_REQUEST_DMA_BUFFERS; - dma_request_msg.msg_payload.__reserved__async = 1; - - send_msg(&dma_request_msg); + sendReclaimDmaBfrsMsg(); } if(quiesced()) //already in shutdown state @@ -1146,6 +1173,9 @@ void MailboxSp::handle_hbmbox_resp(mbox_msg_t & i_mbox_msg) iv_dmaBuffer.addBuffers (i_mbox_msg.msg_payload.data[0]); + // track response received + iv_reclaim_rsp_cnt++; + iv_dma_pend = false; send_msg(); // send next message, if there is one @@ -1241,6 +1271,121 @@ errlHndl_t MailboxSp::send(queue_id_t i_q_id, return err; } +/** + * Reclaim any DMA buffers owned by the FSP + */ +errlHndl_t MailboxSp::reclaimDmaBfrsFromFsp( void ) +{ + errlHndl_t err = NULL; + + // locate the FSP mailbox + MailboxSp & fspMbox = Singleton::instance(); + + // reclaim the dma bfrs + err = fspMbox._reclaimDmaBfrsFromFsp(); + + return( err ); +} + +errlHndl_t MailboxSp::_reclaimDmaBfrsFromFsp( void ) +{ + errlHndl_t err = NULL; + int msgSentCnt = 0; + int maxDmaBfrs = iv_dmaBuffer.maxDmaBfrs(); + + TRACFBIN(g_trac_mbox, + INFO_MRK + "MailboxSp::_reclaimDmaBfrsFromFsp - Start." + " DmaBuffer = ", + &iv_dmaBuffer, + sizeof(iv_dmaBuffer) ); + + while // bfrs still need to be reclaimed + ( iv_dmaBuffer.ownsAllBlocks() == false ) + { + if // request dma bfrs msg is outstanding + ( isDmaReqBfrMsgOutstanding() == true ) + { + // (wait for msg to complete) + nanosleep( 0, 1000000 ); // 1ms to avoid tight busy loop + task_yield(); + } + + else if // can send another request dma bfrs msg + (msgSentCnt < maxDmaBfrs) + { + // send the message + msgSentCnt++; + sendReclaimDmaBfrsMsg(); + } + + else + { + // (sent max number of reclaims and bfrs still not free) + // (something real bad is happening, exit so we don't hang) + + // create a snapshot of DMA buffer control object for tracing + char dmyArray[sizeof(iv_dmaBuffer)]; + memcpy( &dmyArray[0], + (void *)&iv_dmaBuffer, + sizeof(dmyArray) ); + + TRACFBIN(g_trac_mbox, + ERR_MRK + "MailboxSp::_reclaimDmaBfrsFromFsp -" + "Reclaim Did Not Complete. " + "DmaBuffer = ", + &dmyArray[0], + sizeof(dmyArray) ); + + break; + } + } // end wait for bfrs to be reclaimed + + return( err ); +} + + +void MailboxSp::sendReclaimDmaBfrsMsg( void ) +{ + // allocate local msg bfr on the stack + mbox_msg_t local_msg_bfr; + + sendReclaimDmaBfrsMsg( local_msg_bfr ); + + return; +} + + +void MailboxSp::sendReclaimDmaBfrsMsg( mbox_msg_t & i_mbox_msg ) +{ + // isolate all occurrences of this message to this routine + // so the total number of outstanding Request DMA Bfr + // messages can be tracked in one place. This allows + // a mechanism to determine if any of these messages are + // on either the message Q or have been sent on HW to FSP. + // iv_dma_pend only tracks the msg from load on HW to + // response received. Does not consider Queue. + TRACFCOMP(g_trac_mbox, + INFO_MRK + "MailboxSp::sendReclaimDmaBfrsMsg - " + "Send Reclaim Msg to FSP"); + + // send a request dma bfrs msg to reclaim from fsp + new (&i_mbox_msg) mbox_msg_t(); + + i_mbox_msg.msg_queue_id = FSP_MAILBOX_MSGQ; + i_mbox_msg.msg_payload.type = MSG_REQUEST_DMA_BUFFERS; + i_mbox_msg.msg_payload.__reserved__async = 1; + + // track the msg until completion; + iv_reclaim_sent_cnt++; + + send_msg(&i_mbox_msg); + + return; +} + errlHndl_t MailboxSp::msgq_register(queue_id_t i_queue_id, msg_q_t i_msgQ) { @@ -2279,3 +2424,21 @@ void MBOX::deallocate(void * i_ptr) } } +errlHndl_t MBOX::reclaimDmaBfrsFromFsp( void ) +{ + errlHndl_t err = NULL; + + msg_q_t mboxQ = msg_q_resolve(VFS_ROOT_MSG_MBOX); + if(mboxQ) + { + // reclaim the dma bfrs + err = MailboxSp::reclaimDmaBfrsFromFsp(); + } + else + { + TRACFCOMP(g_trac_mbox, ERR_MRK"MBOX::reclaimDmaBfrsFromFsp - " + "Mailbox Service not available"); + } + + return( err ); +} diff --git a/src/usr/mbox/mailboxsp.H b/src/usr/mbox/mailboxsp.H index 4075aa30e8f..7702183429e 100644 --- a/src/usr/mbox/mailboxsp.H +++ b/src/usr/mbox/mailboxsp.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -91,6 +91,13 @@ namespace MBOX msg_t * io_msg, msgq_msg_t i_mbox_msg_type); + /** + * Reclaim any DMA buffers owned by the FSP + * @return errlHndl_t on error + */ + static errlHndl_t reclaimDmaBfrsFromFsp( void ); + + protected: /** @@ -200,7 +207,7 @@ namespace MBOX /** * Handle interrupt from Intr presenter - * @param[in] i_msg, The message + * @param[in] i_msg, The message */ errlHndl_t handleInterrupt(); @@ -285,6 +292,33 @@ namespace MBOX */ bool quiesced(); + /** + * Reclaim any DMA buffers owned by the FSP + * @return errlHndl_t on error + */ + errlHndl_t _reclaimDmaBfrsFromFsp( void ); + + /** + * Send a Reclaim DMA Buffers message to FSP + * @param[in] i_mbox_msg. Message Buffer to use, + */ + void sendReclaimDmaBfrsMsg(mbox_msg_t & i_mbox_msg); + + /** + * Send a Reclaim DMA Buffers message to FSP + */ + void sendReclaimDmaBfrsMsg( void ); + + /** + * Determine if a Reclaim Bfr message is outstanding + * @return [true - Msg active | false - no msg active] + */ + ALWAYS_INLINE + bool isDmaReqBfrMsgOutstanding( void ) const + { + return ( iv_reclaim_sent_cnt > iv_reclaim_rsp_cnt) ; + } + enum { @@ -337,7 +371,8 @@ namespace MBOX msg_t * iv_shutdown_msg;//!< Message to shutdown mbox msg_t * iv_suspend_msg; //!< Message to suspend mbox bool iv_rts; //!< ready to send flag - bool iv_dma_pend; //!< Request pending for more DMA bufs + bool iv_dma_pend; //!< Request pending (on Hw) + //!< for more DMA bufs bool iv_disabled; //!< Mailboxsp shut off (rejects new) bool iv_suspended; //!< Mailbox is suspended (queues new) bool iv_suspend_intr;//!< Disable HW interrupts on suspend @@ -345,6 +380,8 @@ namespace MBOX uint64_t iv_sum_alloc; //!< Total extra_data storage allocated msg_list_t iv_pend_alloc; //!< Pending memory allocations addr_list_t iv_allocAddrs; //!< memory addresses allocated by mbox + int iv_reclaim_sent_cnt;//!< num of reclaim bfr msgs sent + int iv_reclaim_rsp_cnt; //!< num of reclaim responses rcvd }; }; diff --git a/src/usr/mbox/mbox_dma_buffer.C b/src/usr/mbox/mbox_dma_buffer.C index 7a8cc4d2c70..78a4d1f6a5f 100644 --- a/src/usr/mbox/mbox_dma_buffer.C +++ b/src/usr/mbox/mbox_dma_buffer.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,7 +43,7 @@ extern trace_desc_t * g_trac_mbox; DmaBuffer::DmaBuffer() : iv_head(NULL), iv_dir(makeMask(VmmManager::MBOX_DMA_PAGES)), - iv_dma_req_sent(false) + iv_dma_req_sent_cnt(0) { iv_head = malloc(VmmManager::MBOX_DMA_SIZE); diff --git a/src/usr/mbox/mbox_dma_buffer.H b/src/usr/mbox/mbox_dma_buffer.H index acb18df1fe3..7ae9c92194a 100644 --- a/src/usr/mbox/mbox_dma_buffer.H +++ b/src/usr/mbox/mbox_dma_buffer.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -139,23 +139,34 @@ namespace MBOX } /** - * Set the state of shutdown dma request sent - * @param[in] The state to set [true|false] + * Increment the count of shutdown dma request sent */ ALWAYS_INLINE - void setShutdownDmaRequestSent(bool i_state) + void incrementShutdownDmaRequestSentCnt( void ) { - iv_dma_req_sent = i_state; + iv_dma_req_sent_cnt++; } /** - * Query if the shutdown DMA request has been sent + * Query the max number of DMA bfrs + * @return [max number of DMA bfrs] + */ + ALWAYS_INLINE + int maxDmaBfrs( void ) + { + // max dma bfrs since tracked by a bit mask variable + return( sizeof(iv_dir) * 8 ); + } + + /** + * Query if the max number of shutdown DMA request has been sent * @return state [true|false] */ ALWAYS_INLINE - bool shutdownDmaRequestSent() + bool maxShutdownDmaRequestSent( void ) { - return iv_dma_req_sent; + // max of max number of bfrs since min released is 1 at a time + return( iv_dma_req_sent_cnt >= maxDmaBfrs() ); } private: @@ -177,7 +188,8 @@ namespace MBOX void * iv_head; //!< Start of DMA memory uint64_t iv_phys_head; //!< Physical translation of iv_head uint64_t iv_dir; //!< 1 bit per 1k buffer, 1 = available - bool iv_dma_req_sent; //!< Request sent to retrieve all buffers + int iv_dma_req_sent_cnt; //!< number of Requests sent to + // retrieve all buffers }; }; // namespace