Deadlock Fix for HSA and Serialization Disable/Enabling support (#582)

* Initial barrier

* Working on profiler serializer extraction

* Current progress

* Serializtion Support

* source formatting (clang-format v11) (#583)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* cmake formatting (cmake-format) (#584)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* Minor fix

* Current Progress

* Current progress

* More fixes

* Serialization Fixes

* Bug fix

* source formatting (clang-format v11) (#600)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* More fixes

* More minor fixes

* source formatting (clang-format v11) (#603)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* source formatting (clang-format v11) (#604)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* Lock order inversion false positive

* order fix

* More changes

* source formatting (clang-format v11) (#607)

Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>

* minor test fix

* Minor test changes

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bwelton <1683479+bwelton@users.noreply.github.com>
This commit is contained in:
Benjamin Welton
2024-03-08 07:02:43 -08:00
committad av GitHub
förälder 7b6d3c70bd
incheckning 1de44447f4
16 ändrade filer med 1099 tillägg och 234 borttagningar
@@ -24,6 +24,7 @@
#include <rocprofiler-sdk/rocprofiler.h>
#include "lib/rocprofiler-sdk/hsa/profile_serializer.hpp"
#include "lib/rocprofiler-sdk/hsa/queue.hpp"
#include <cstdint>
@@ -36,27 +37,6 @@ namespace rocprofiler
{
namespace hsa
{
/*This is a profiler serializer. It should be instantiated
only once for the profiler. The following is the
description of each field.
1. dispatch_queue - The queue to which the currently dispatched kernel
belongs to.
At any given time, in serialization only one kernel
can be executing.
2. dispatch_ready- It is a software data structure which holds
the queues which have a kernel ready to be dispatched.
This stores the queues in FIFO order.
3. serializer_mutex - The mutex is used for thread synchronization
while accessing the singleton instance of this structure.
Currently, in case of profiling kernels are serialized by default.
*/
struct profiler_serializer_t
{
const Queue* dispatch_queue{nullptr};
std::deque<const Queue*> dispatch_ready;
bool enabled{true};
};
// Tracks and manages HSA queues
class QueueController
{
@@ -65,6 +45,7 @@ public:
std::tuple<rocprofiler_agent_t, Queue::queue_cb_t, Queue::completed_cb_t>;
using queue_iterator_cb_t = std::function<void(const Queue*)>;
using callback_iterator_cb_t = std::function<void(ClientID, const agent_callback_tuple_t&)>;
using queue_map_t = std::unordered_map<hsa_queue_t*, std::unique_ptr<Queue>>;
QueueController() = default;
// Initializes the QueueInterceptor. This must be delayed until
@@ -86,7 +67,7 @@ public:
const CoreApiTable& get_core_table() const { return _core_table; }
const AmdExtTable& get_ext_table() const { return _ext_table; }
// Gets the list of supported HSA agents that can be intercepted
// Gets the list of supported HSA agents that can be Pintercepted
const auto& get_supported_agents() const { return _supported_agents; }
auto& get_supported_agents() { return _supported_agents; }
@@ -94,32 +75,41 @@ public:
void iterate_queues(const queue_iterator_cb_t&) const;
void set_queue_state(queue_state state, hsa_queue_t* hsa_queue);
void profiler_serializer_register_ready_signal_handler(const hsa_signal_t& signal,
void* data) const;
void add_dispatch_ready(const Queue* queue);
template <typename FuncT>
void profiler_serializer(FuncT&& lambda);
void iterate_callbacks(const callback_iterator_cb_t&) const;
common::Synchronized<hsa::profiler_serializer>& serializer() { return _profiler_serializer; }
/**
* Disable serialization for QueueController, has no effect if counter collection
* is not in use (which defaults to no serialization mechanism). Should only be used for
* testing.
*/
void enable_serialization();
void disable_serialization();
// Prints current state of signals for queues, used for debugging. Only prints
// serialization related signals if not compiled in debug mode.
void print_debug_signals() const;
#if !defined(NDEBUG)
// Tracks the creation of all signals in queues, used for debugging and disabled
// in release mode (adds locking around signal creation).
common::Synchronized<std::unordered_map<uint64_t, hsa_signal_t>> _debug_signals;
#endif
private:
using queue_map_t = std::unordered_map<hsa_queue_t*, std::unique_ptr<Queue>>;
using client_id_map_t = std::unordered_map<ClientID, agent_callback_tuple_t>;
using agent_cache_map_t = std::unordered_map<uint32_t, AgentCache>;
CoreApiTable _core_table = {};
AmdExtTable _ext_table = {};
common::Synchronized<queue_map_t> _queues = {};
common::Synchronized<client_id_map_t> _callback_cache = {};
agent_cache_map_t _supported_agents = {};
common::Synchronized<profiler_serializer_t> _profiler_serializer;
CoreApiTable _core_table = {};
AmdExtTable _ext_table = {};
common::Synchronized<queue_map_t> _queues = {};
common::Synchronized<client_id_map_t> _callback_cache = {};
agent_cache_map_t _supported_agents = {};
common::Synchronized<hsa::profiler_serializer> _profiler_serializer;
};
QueueController&