From 5444c8342d7baee3cda12726925866c135474da1 Mon Sep 17 00:00:00 2001 From: Gu_Lihao Date: Wed, 30 Aug 2023 12:14:48 +0800 Subject: [PATCH] [Media Common] [VP] Fix OCA R2R crash issue for common dll separation Move buf handle map from common dll to DDI dll --- .../agnostic/common/os/mos_oca_interface.h | 29 +++++++ .../common/renderhal/hal_oca_interface_next.h | 3 - .../common/os/mos_oca_interface_specific.h | 31 +++++++ .../linux/common/os/mos_oca_specific.cpp | 82 +++++++++++++++++++ .../common/shared/hal_oca_interface_next.cpp | 50 ++--------- 5 files changed, 148 insertions(+), 47 deletions(-) diff --git a/media_common/agnostic/common/os/mos_oca_interface.h b/media_common/agnostic/common/os/mos_oca_interface.h index a2fc067af12..b99dc221ee6 100644 --- a/media_common/agnostic/common/os/mos_oca_interface.h +++ b/media_common/agnostic/common/os/mos_oca_interface.h @@ -249,6 +249,35 @@ class MosOcaInterface return nullptr; } + //! + //! \brief Insert OCA buffer handle into m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \param [in] handle + //! Oca buffer handle. + //! \return MOS_STATUS + //! Return MOS_STATUS_SUCCESS if insert successfully, otherwise insert failed. + //! + virtual MOS_STATUS InsertOcaBufHandleMap(uint32_t *key, MOS_OCA_BUFFER_HANDLE handle) = 0; + + //! + //! \brief Remove OCA buffer handle from m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \return MOS_STATUS + //! Return MOS_STATUS_SUCCESS if erase successfully, otherwise erase failed. + //! + virtual MOS_STATUS RemoveOcaBufHandleFromMap(uint32_t *key) = 0; + + //! + //! \brief Get OCA buffer handle from m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \return MOS_OCA_BUFFER_HANDLE + //! Return oca buffer handle. + //! + virtual MOS_OCA_BUFFER_HANDLE GetOcaBufHandleFromMap(uint32_t *key) = 0; + //! //! \brief Get OCA status. //! \return MOS_STATUS diff --git a/media_softlet/agnostic/common/renderhal/hal_oca_interface_next.h b/media_softlet/agnostic/common/renderhal/hal_oca_interface_next.h index b2bdb2e8a92..f0289d0be6c 100644 --- a/media_softlet/agnostic/common/renderhal/hal_oca_interface_next.h +++ b/media_softlet/agnostic/common/renderhal/hal_oca_interface_next.h @@ -358,9 +358,6 @@ class HalOcaInterfaceNext HalOcaInterfaceNext(HalOcaInterfaceNext &); HalOcaInterfaceNext& operator= (HalOcaInterfaceNext &); -protected: - static std::map s_hOcaMap; //!< Oca buffer handle map to current command - MEDIA_CLASS_DEFINE_END(HalOcaInterfaceNext) }; diff --git a/media_softlet/linux/common/os/mos_oca_interface_specific.h b/media_softlet/linux/common/os/mos_oca_interface_specific.h index 137a7da6a0e..e8028e23303 100644 --- a/media_softlet/linux/common/os/mos_oca_interface_specific.h +++ b/media_softlet/linux/common/os/mos_oca_interface_specific.h @@ -260,6 +260,35 @@ class MosOcaInterfaceSpecific : public MosOcaInterface return m_ocaMutex; } + //! + //! \brief Insert OCA buffer handle into m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \param [in] handle + //! Oca buffer handle. + //! \return MOS_STATUS + //! Return MOS_STATUS_SUCCESS if insert successfully, otherwise insert failed. + //! + virtual MOS_STATUS InsertOcaBufHandleMap(uint32_t *key, MOS_OCA_BUFFER_HANDLE handle); + + //! + //! \brief Remove OCA buffer handle from m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \return MOS_STATUS + //! Return MOS_STATUS_SUCCESS if erase successfully, otherwise erase failed. + //! + virtual MOS_STATUS RemoveOcaBufHandleFromMap(uint32_t *key); + + //! + //! \brief Get OCA buffer handle from m_hOcaMap + //! \param [in] key + //! The key of m_hOcaMap. + //! \return MOS_OCA_BUFFER_HANDLE + //! Return oca buffer handle. + //! + virtual MOS_OCA_BUFFER_HANDLE GetOcaBufHandleFromMap(uint32_t *key); + //! //! \brief Get OCA status //! \return MOS_STATUS @@ -368,6 +397,8 @@ class MosOcaInterfaceSpecific : public MosOcaInterface PMOS_MUTEX m_ocaMutex = nullptr; PMOS_MUTEX m_mutexForOcaBufPool = nullptr; + std::map m_hOcaMap; //!< Oca buffer handle map + bool m_isOcaEnabled = false; bool m_isInitialized = false; MOS_OCA_RESOURCE_INFO *m_resInfoPool = nullptr; diff --git a/media_softlet/linux/common/os/mos_oca_specific.cpp b/media_softlet/linux/common/os/mos_oca_specific.cpp index dba6106f14c..8df05cac476 100644 --- a/media_softlet/linux/common/os/mos_oca_specific.cpp +++ b/media_softlet/linux/common/os/mos_oca_specific.cpp @@ -82,6 +82,13 @@ bool MosOcaInterfaceSpecific::s_isDestroyed = false; //! MOS_OCA_BUFFER_HANDLE MosOcaInterfaceSpecific::LockOcaBufAvailable(PMOS_CONTEXT pMosContext, uint32_t CurrentGpuContextHandle) { + if (nullptr == m_ocaMutex) + { + MosOcaInterfaceSpecific::OnOcaError(pMosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__); + return MOS_OCA_INVALID_BUFFER_HANDLE; + } + + MosOcaAutoLock autoLock(m_ocaMutex); for (int i = m_indexOfNextOcaBufContext; i < MAX_NUM_OF_OCA_BUF_CONTEXT; ++i) { if (m_ocaBufContextList[i].inUse) @@ -826,6 +833,7 @@ void MosOcaInterfaceSpecific::Uninitialize() m_ocaBufContextList[i].logSection.resInfo.resInfoList = nullptr; } } + m_hOcaMap.clear(); m_isInitialized = false; s_bOcaStatusExistInReg = false; s_isDestroyed = false; @@ -862,3 +870,77 @@ void MosOcaInterfaceSpecific::UninitInterface() return; } +//! +//! \brief Insert OCA buffer handle into m_hOcaMap +//! \param [in] key +//! The key of m_hOcaMap. +//! \param [in] handle +//! Oca buffer handle. +//! \return MOS_STATUS +//! Return MOS_STATUS_SUCCESS if insert successfully, otherwise insert failed. +//! +MOS_STATUS MosOcaInterfaceSpecific::InsertOcaBufHandleMap(uint32_t *key, MOS_OCA_BUFFER_HANDLE handle) +{ + MOS_OS_CHK_NULL_RETURN(m_ocaMutex); + MOS_OS_CHK_NULL_RETURN(key); + + MosOcaAutoLock autoLock(m_ocaMutex); + auto success = m_hOcaMap.insert(std::make_pair(key, handle)); + if (!success.second) + { + // Should never come to here. + MOS_OS_ASSERTMESSAGE("OcaBufHandle has already been assigned to current cmdBuffer!"); + return MOS_STATUS_UNKNOWN; + } + return MOS_STATUS_SUCCESS; +} + +//! +//! \brief Remove OCA buffer handle from m_hOcaMap +//! \param [in] key +//! The key of m_hOcaMap. +//! \return MOS_STATUS +//! Return MOS_STATUS_SUCCESS if erase successfully, otherwise erase failed. +//! +MOS_STATUS MosOcaInterfaceSpecific::RemoveOcaBufHandleFromMap(uint32_t *key) +{ + MOS_OS_CHK_NULL_RETURN(m_ocaMutex); + + MosOcaAutoLock autoLock(m_ocaMutex); + auto it = m_hOcaMap.find(key); + if (it != m_hOcaMap.end()) + { + m_hOcaMap.erase(it); + } + return MOS_STATUS_SUCCESS; +} + +//! +//! \brief Get OCA buffer handle from m_hOcaMap +//! \param [in] key +//! The key of m_hOcaMap. +//! \return MOS_OCA_BUFFER_HANDLE +//! Return oca buffer handle. +//! +MOS_OCA_BUFFER_HANDLE MosOcaInterfaceSpecific::GetOcaBufHandleFromMap(uint32_t *key) +{ + if (nullptr == m_ocaMutex) + { + MOS_OS_ASSERTMESSAGE("m_ocaMutex is nullptr."); + return MOS_OCA_INVALID_BUFFER_HANDLE; + } + MosOcaAutoLock autoLock(m_ocaMutex); + auto it = m_hOcaMap.find(key); + if (it == m_hOcaMap.end()) + { + // May come here for workloads not enabling UMD_OCA. + return MOS_OCA_INVALID_BUFFER_HANDLE; + } + if (it->second >= MAX_NUM_OF_OCA_BUF_CONTEXT || it->second < 0) + { + MOS_OS_ASSERTMESSAGE("Get invalid OcaBufHandle: %d!", it->second); + return MOS_OCA_INVALID_BUFFER_HANDLE; + } + + return it->second; +} diff --git a/media_softlet/linux/common/shared/hal_oca_interface_next.cpp b/media_softlet/linux/common/shared/hal_oca_interface_next.cpp index 097b0a0a092..0eb97ca3f99 100644 --- a/media_softlet/linux/common/shared/hal_oca_interface_next.cpp +++ b/media_softlet/linux/common/shared/hal_oca_interface_next.cpp @@ -48,8 +48,6 @@ namespace mhw { namespace mi { class Itf; } } -std::map HalOcaInterfaceNext::s_hOcaMap; - /****************************************************************************************************/ /* HalOcaInterfaceNextNext */ /****************************************************************************************************/ @@ -603,24 +601,8 @@ MOS_OCA_BUFFER_HANDLE HalOcaInterfaceNext::GetOcaBufferHandle(MOS_COMMAND_BUFFER OnOcaError(mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__); return MOS_OCA_INVALID_BUFFER_HANDLE; } - PMOS_MUTEX mutex = pOcaInterface->GetMutex(); - if (mutex == nullptr) - { - return MOS_OCA_INVALID_BUFFER_HANDLE; - } - MosOcaAutoLock autoLock(mutex); - std::map::iterator it = s_hOcaMap.find(cmdBuffer.pCmdBase); - if (it == s_hOcaMap.end()) - { - // May come here for workloads not enabling UMD_OCA. - return MOS_OCA_INVALID_BUFFER_HANDLE; - } - if (it->second >= MAX_NUM_OF_OCA_BUF_CONTEXT || it->second < 0) - { - OnOcaError(mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__); - return MOS_OCA_INVALID_BUFFER_HANDLE; - } - return it->second; + + return pOcaInterface->GetOcaBufHandleFromMap(cmdBuffer.pCmdBase); } void HalOcaInterfaceNext::RemoveOcaBufferHandle(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT &mosContext) @@ -631,19 +613,7 @@ void HalOcaInterfaceNext::RemoveOcaBufferHandle(MOS_COMMAND_BUFFER &cmdBuffer, M OnOcaError(&mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__); return; } - PMOS_MUTEX mutex = pOcaInterface->GetMutex(); - if (mutex == nullptr) - { - OnOcaError(&mosContext, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__); - return; - } - MosOcaAutoLock autoLock(mutex); - std::map::iterator it = s_hOcaMap.find(cmdBuffer.pCmdBase); - if (it == s_hOcaMap.end()) - { - return; - } - s_hOcaMap.erase(it); + pOcaInterface->RemoveOcaBufHandleFromMap(cmdBuffer.pCmdBase); } //! @@ -670,12 +640,7 @@ void HalOcaInterfaceNext::On1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_C { return; } - PMOS_MUTEX mutex = pOcaInterface->GetMutex(); - if (mutex == nullptr) - { - OnOcaError(&mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__); - return; - } + ocaBufHandle = GetOcaBufferHandle(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext); if (ocaBufHandle != MOS_OCA_INVALID_BUFFER_HANDLE) { @@ -685,18 +650,15 @@ void HalOcaInterfaceNext::On1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_C } else { - MosOcaAutoLock autoLock(mutex); ocaBufHandle = pOcaInterface->LockOcaBufAvailable(&mosContext, gpuContextHandle); + if (MOS_OCA_INVALID_BUFFER_HANDLE == ocaBufHandle) { OnOcaError(&mosContext, MOS_STATUS_INVALID_HANDLE, __FUNCTION__, __LINE__); return; } - auto success = s_hOcaMap.insert(std::make_pair(cmdBuffer.pCmdBase, ocaBufHandle)); - if (!success.second) + if (MOS_FAILED(pOcaInterface->InsertOcaBufHandleMap(cmdBuffer.pCmdBase, ocaBufHandle))) { - // Should never come to here. - MOS_OS_ASSERTMESSAGE("ocaBufHandle has already been assigned to current cmdBuffer!"); OnOcaError(&mosContext, MOS_STATUS_INVALID_HANDLE, __FUNCTION__, __LINE__); return; }