diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/common/hsa_table_interface.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/common/hsa_table_interface.cpp index 85da28adce..c24c5ec865 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/common/hsa_table_interface.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/common/hsa_table_interface.cpp @@ -1097,10 +1097,8 @@ hsa_status_t HSA_API hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handl // Mirrors Amd Extension Apis hsa_status_t HSA_API hsa_amd_register_system_event_handler( - hsa_amd_event_t type, - hsa_status_t (*callback)(const void* event_specific_data, void* data), - void* data) { - return amdExtTable->hsa_amd_register_system_event_handler_fn(type, callback, data); + hsa_amd_system_event_callback_t callback, void* data) { + return amdExtTable->hsa_amd_register_system_event_handler_fn(callback, data); } // Mirrors Amd Extension Apis diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/exceptions.h b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/exceptions.h index 52233f37d4..c119f645f2 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/exceptions.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/exceptions.h @@ -73,7 +73,7 @@ template class callback_t { // Should not be marked explicit. callback_t(func_t function_ptr) : function(function_ptr) {} - callback_t& operator=(func_t function_ptr) { function = function_ptr; } + callback_t& operator=(func_t function_ptr) { function = function_ptr; return *this; } // Allows common function pointer idioms, such as if( func != nullptr )... // without allowing silent reversion to the original function pointer type. diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/hsa_ext_amd_impl.h b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/hsa_ext_amd_impl.h index a8066710af..440a397bf2 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/hsa_ext_amd_impl.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/hsa_ext_amd_impl.h @@ -212,9 +212,7 @@ hsa_status_t hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handle, hsa_s // Mirrors Amd Extension Apis hsa_status_t hsa_amd_register_system_event_handler( - hsa_amd_event_t type, - hsa_status_t (*callback)(const void* event_specific_data, void* data), - void* data); + hsa_amd_system_event_callback_t callback, void* data); } // end of AMD namespace diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h index d1aed4e26c..9721f9c9a6 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h @@ -53,6 +53,7 @@ #include "core/inc/hsa_ext_amd_impl.h" #include "core/inc/agent.h" +#include "core/inc/exceptions.h" #include "core/inc/memory_region.h" #include "core/inc/signal.h" #include "core/util/flag.h" @@ -318,9 +319,14 @@ class Runtime { ExtensionEntryPoints extensions_; - hsa_status_t SetCustomVMFaultHandler(hsa_status_t (*callback)(const void* event_specific_data, - void* data), - void* data); + hsa_status_t SetCustomSystemEventHandler(hsa_amd_system_event_callback_t callback, + void* data); + + void* GetCustomSystemEventData() { return system_event_handler_user_data_; } + + AMD::callback_t GetCustomSystemEventHandler() { + return system_event_handler_; + } protected: static void AsyncEventsLoop(void*); @@ -504,10 +510,10 @@ class Runtime { // @brief HSA signal to contain the VM fault event. Signal* vm_fault_signal_; - // custom VM fault handler. - hsa_status_t (*vm_fault_handler_custom_)(const void* event_specific_data, - void* data); - void* vm_fault_handler_user_data_; + // Custom system event handler. + AMD::callback_t system_event_handler_; + + void* system_event_handler_user_data_; // Holds reference count to runtime object. std::atomic ref_count_; diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp index 0a70f03087..b0bf5a19d3 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp @@ -844,18 +844,11 @@ hsa_status_t hsa_amd_queue_intercept_register(hsa_queue_t* queue, CATCH; } -hsa_status_t hsa_amd_register_system_event_handler( - hsa_amd_event_t type, - hsa_status_t (*callback)(const void* event_specific_data, void* data), - void* data) { +hsa_status_t hsa_amd_register_system_event_handler(hsa_amd_system_event_callback_t callback, + void* data) { TRY; IS_OPEN(); - switch (type) { - case GPU_MEMORY_FAULT_EVENT: - return core::Runtime::runtime_singleton_->SetCustomVMFaultHandler(callback, data); - default: - return HSA_STATUS_ERROR_INVALID_ARGUMENT; - } + return core::Runtime::runtime_singleton_->SetCustomSystemEventHandler(callback, data); CATCH; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp index 0625c6f5ff..0683adbfa2 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp @@ -1050,38 +1050,40 @@ bool Runtime::VMFaultHandler(hsa_signal_value_t val, void* arg) { hsa_status_t custom_handler_status = HSA_STATUS_ERROR; // If custom handler is registered, pack the fault info and call the handler - if (runtime_singleton_->vm_fault_handler_custom_ != nullptr) { - hsa_amd_gpu_memory_fault_info_t* fault_info = new hsa_amd_gpu_memory_fault_info_t; + if (runtime_singleton_->GetCustomSystemEventHandler()) { + hsa_amd_gpu_memory_fault_info_t fault_info; // Find the faulty agent auto it = runtime_singleton_->agents_by_node_.find(fault.NodeId); assert(it != runtime_singleton_->agents_by_node_.end() && "Can't find faulty agent."); Agent* faulty_agent = it->second.front(); - fault_info->agent = Agent::Convert(faulty_agent); + fault_info.agent = Agent::Convert(faulty_agent); - fault_info->virtual_address = fault.VirtualAddress; - fault_info->fault_reason_mask = 0x00000000; + fault_info.virtual_address = fault.VirtualAddress; + fault_info.fault_reason_mask = 0x00000000; if (fault.Failure.NotPresent == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00000001; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00000001; } if (fault.Failure.ReadOnly == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00000010; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00000010; } if (fault.Failure.NoExecute == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00000100; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00000100; } if (fault.Failure.GpuAccess == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00001000; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00001000; } if (fault.Failure.ECC == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00010000; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00010000; } if (fault.Failure.Imprecise == 1) { - fault_info->fault_reason_mask = fault_info->fault_reason_mask | 0x00100000; + fault_info.fault_reason_mask = fault_info.fault_reason_mask | 0x00100000; } - - custom_handler_status = runtime_singleton_->vm_fault_handler_custom_(fault_info, - runtime_singleton_->vm_fault_handler_user_data_); + hsa_amd_event_t memory_fault_event; + memory_fault_event.event_type = GPU_MEMORY_FAULT_EVENT; + memory_fault_event.memory_fault = fault_info; + custom_handler_status = runtime_singleton_->GetCustomSystemEventHandler()( + &memory_fault_event, runtime_singleton_->GetCustomSystemEventData()); } // No custom VM fault handler registered or it failed. @@ -1176,7 +1178,7 @@ Runtime::Runtime() sys_clock_freq_(0), vm_fault_event_(nullptr), vm_fault_signal_(nullptr), - vm_fault_handler_custom_(nullptr), + system_event_handler_user_data_(nullptr), ref_count_(0) { start_svm_address_ = 0; #if defined(HSA_LARGE_MODEL) @@ -1446,15 +1448,15 @@ void Runtime::AsyncEvents::Clear() { arg_.clear(); } -hsa_status_t Runtime::SetCustomVMFaultHandler( - hsa_status_t (*callback)(const void* event_specific_data, void* data), - void* data) { - if (vm_fault_handler_custom_ != nullptr) { +hsa_status_t Runtime::SetCustomSystemEventHandler(hsa_amd_system_event_callback_t callback, + void* data) { + if (system_event_handler_) { return HSA_STATUS_ERROR; } else { - vm_fault_handler_custom_ = callback; - vm_fault_handler_user_data_ = data; + system_event_handler_ = callback; + system_event_handler_user_data_ = data; return HSA_STATUS_SUCCESS; } } + } // namespace core diff --git a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h index b4b95e2f3c..ff3903586a 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h @@ -1629,62 +1629,73 @@ hsa_status_t HSA_API hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handl /** * @brief GPU system event type. */ -typedef enum hsa_amd_event_s { - /** - * AMD GPU memory fault. +typedef enum hsa_amd_event_type_s { + /* + AMD GPU memory fault. */ - GPU_MEMORY_FAULT_EVENT = 0 -} hsa_amd_event_t; + GPU_MEMORY_FAULT_EVENT = 0, +} hsa_amd_event_type_t; /** - * @brief AMD GPU memory fault event data (event_specific_data) type passed to event handler. + * @brief AMD GPU memory fault event data. */ typedef struct hsa_amd_gpu_memory_fault_info_s { - /** - * The agent where the memory fault occurred. - */ - hsa_agent_t agent; - /** - * Virtual address accessed. - */ - uint64_t virtual_address; - /** - * Bit field encoding the memory access failure reasons. There could be multiple bits set - * for one fault. - * 0x00000001 Page not present or supervisor privilege. - * 0x00000010 Write access to a read-only page. - * 0x00000100 Execute access to a page marked NX. - * 0x00001000 Host access only. - * 0x00010000 ECC failure (if supported by HW). - * 0x00100000 Can't determine the exact fault address. - */ - uint32_t fault_reason_mask; + /* + The agent where the memory fault occurred. + */ + hsa_agent_t agent; + /* + Virtual address accessed. + */ + uint64_t virtual_address; + /* + Bit field encoding the memory access failure reasons. There could be multiple bits set + for one fault. + 0x00000001 Page not present or supervisor privilege. + 0x00000010 Write access to a read-only page. + 0x00000100 Execute access to a page marked NX. + 0x00001000 Host access only. + 0x00010000 ECC failure (if supported by HW). + 0x00100000 Can't determine the exact fault address. + */ + uint32_t fault_reason_mask; } hsa_amd_gpu_memory_fault_info_t; +/** + * @brief AMD GPU event data passed to event handler. + */ +typedef struct hsa_amd_event_s { + /* + The event type. + */ + hsa_amd_event_type_t event_type; + union { + /* + The memory fault info, only valid when @p event_type is GPU_MEMORY_FAULT_EVENT. + */ + hsa_amd_gpu_memory_fault_info_t memory_fault; + }; +} hsa_amd_event_t; + +typedef hsa_status_t (*hsa_amd_system_event_callback_t)(const hsa_amd_event_t* event, void* data); + /** * @brief Register AMD GPU event handler. * - * @param[in] type The GPU event type. - * - * @param[in] callback Callback to be invoked when the event is triggered. - * The HSA runtime passes two arguments to the callback: the event data and user data. - * Event data is defined per event by the HSA runtime. For GPU_MEMORY_FAULT_EVENT, - * the event data type is hsa_amd_gpu_memory_fault_info_t. + * @param[in] callback Callback to be invoked when an event is triggered. + * The HSA runtime passes two arguments to the callback: @p event + * is defined per event by the HSA runtime, and @p data is the user data. * * @param[in] data User data that is passed to @p callback. May be NULL. * - * @param[out] callback Function pointer to the handler. + * @retval HSA_STATUS_SUCCESS The handler has been registered successfully. * - * @retval ::HSA_STATUS_SUCCESS The handler has been registered successfully. + * @retval HSA_STATUS_ERROR An event handler has already been registered. * - * @retval ::HSA_STATUS_ERROR A handler for the event has already been registered. - * - * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p type is invalid. + * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p event is invalid. */ -hsa_status_t hsa_amd_register_system_event_handler( - hsa_amd_event_t type, - hsa_status_t (*callback)(const void* event_specific_data, void* data), - void* data); +hsa_status_t hsa_amd_register_system_event_handler(hsa_amd_system_event_callback_t callback, + void* data); #ifdef __cplusplus } // end extern "C" block