From ee5bc9501976ed57479e6b30fc02386061327a86 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Wed, 4 Apr 2018 12:14:29 -0500 Subject: [PATCH] SQTT memory checks --- src/core/context.h | 45 +++++++++++++++++--------------- src/core/intercept_queue.cpp | 2 +- src/core/profile.h | 7 ++--- test/ctrl/tool.cpp | 50 ++++++++++++++++++++++-------------- 4 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/core/context.h b/src/core/context.h index bdd6772eb6..2ee1d896f6 100644 --- a/src/core/context.h +++ b/src/core/context.h @@ -322,6 +322,7 @@ class Context { } struct callback_data_t { + const profile_t* profile; info_vector_t* info_vector; size_t index; char* ptr; @@ -340,7 +341,7 @@ class Context { if (!complete) WARN_LOGGING("timeout"); } for (rocprofiler_feature_t* rinfo : *(tuple.info_vector)) rinfo->data.kind = ROCPROFILER_DATA_KIND_UNINIT; - callback_data_t callback_data{tuple.info_vector, tuple.info_vector->size(), NULL}; + callback_data_t callback_data{tuple.profile, tuple.info_vector, tuple.info_vector->size(), NULL}; const hsa_status_t status = api_->hsa_ven_amd_aqlprofile_iterate_data(tuple.profile, DataCallback, &callback_data); if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(status, "context iterate data failed"); @@ -404,6 +405,7 @@ class Context { hsa_ven_amd_aqlprofile_info_data_t* ainfo_data, void* data) { hsa_status_t status = HSA_STATUS_SUCCESS; callback_data_t* callback_data = reinterpret_cast(data); + const profile_t* profile = callback_data->profile; info_vector_t& info_vector = *(callback_data->info_vector); uint32_t index = callback_data->index; const uint32_t sample_id = ainfo_data->sample_id; @@ -425,39 +427,40 @@ class Context { } else if (ainfo_type == HSA_VEN_AMD_AQLPROFILE_INFO_SQTT_DATA) { if (rinfo->data.result_bytes.copy) { if (sample_id == 0) { - if (rinfo->data.result_bytes.size == 0) { - const uint32_t output_buffer_size = SqttProfile::GetSize(); + const uint32_t output_buffer_size = profile->output_buffer.size; const uint32_t output_buffer_size64 = output_buffer_size / sizeof(uint64_t); - rinfo->data.result_bytes.ptr = calloc(output_buffer_size64, sizeof(uint64_t)); + void* ptr = calloc(output_buffer_size64, sizeof(uint64_t)); rinfo->data.result_bytes.size = output_buffer_size; - } else if (rinfo->data.result_bytes.size != SqttProfile::GetSize()) { - EXC_RAISING(HSA_STATUS_ERROR, "result bytes copy mode, data array size mismatch(" << rinfo->data.result_bytes.size << ")"); - } + rinfo->data.result_bytes.ptr = ptr; + callback_data->ptr = reinterpret_cast(ptr); } char* result_bytes_ptr = reinterpret_cast(rinfo->data.result_bytes.ptr); const char* end = result_bytes_ptr + rinfo->data.result_bytes.size; const char* src = reinterpret_cast(ainfo_data->sqtt_data.ptr); - const uint32_t size = ainfo_data->sqtt_data.size; - char* ptr = (sample_id == 0) ? result_bytes_ptr : callback_data->ptr; - uint64_t* header = reinterpret_cast(ptr); + uint32_t size = ainfo_data->sqtt_data.size; + char* ptr = callback_data->ptr; + uint32_t* header = reinterpret_cast(ptr); char* dest = ptr + sizeof(*header); - if ((dest + size) < end) { - hsa_status_t status = hsa_memory_copy(dest, src, size); - if (status == HSA_STATUS_SUCCESS) { - *header = size; - callback_data->ptr = dest + align_size(size, sizeof(uint64_t)); - rinfo->data.result_bytes.instance_count = sample_id + 1; - rinfo->data.kind = ROCPROFILER_DATA_KIND_BYTES; - } - } else { - EXC_RAISING(HSA_STATUS_ERROR, "result bytes copy mode, out of boundary, size = " << rinfo->data.result_bytes.size); + if ((dest + size) >= end) { + if (dest < end) size = end - dest; + else EXC_RAISING(HSA_STATUS_ERROR, "SQTT data out of output buffer"); + } + + hsa_status_t status = hsa_memory_copy(dest, src, size); + if (status == HSA_STATUS_SUCCESS) { + *header = size; + callback_data->ptr = dest + align_size(size, sizeof(uint32_t)); + rinfo->data.result_bytes.instance_count = sample_id + 1; + rinfo->data.kind = ROCPROFILER_DATA_KIND_BYTES; } } else { if (sample_id == 0) { - rinfo->data.result_bytes.ptr = ainfo_data->sqtt_data.ptr; + rinfo->data.result_bytes.ptr = profile->output_buffer.ptr; + rinfo->data.result_bytes.size = profile->output_buffer.size; rinfo->data.result_bytes.instance_count = UINT32_MAX; } + rinfo->data.result_bytes.instance_count += 1; rinfo->data.kind = ROCPROFILER_DATA_KIND_BYTES; } diff --git a/src/core/intercept_queue.cpp b/src/core/intercept_queue.cpp index 9c29a714e8..481716fc2a 100644 --- a/src/core/intercept_queue.cpp +++ b/src/core/intercept_queue.cpp @@ -14,5 +14,5 @@ InterceptQueue::obj_map_t* InterceptQueue::obj_map_ = NULL; const char* InterceptQueue::kernel_none_ = ""; uint64_t InterceptQueue::timeout_ = UINT64_MAX; Tracker* InterceptQueue::tracker_ = NULL; -bool InterceptQueue::tracker_on_ = true; +bool InterceptQueue::tracker_on_ = false; } // namespace rocprofiler diff --git a/src/core/profile.h b/src/core/profile.h index 298f955d19..1bc37a9ef4 100644 --- a/src/core/profile.h +++ b/src/core/profile.h @@ -113,7 +113,8 @@ class Profile { // Check the profile buffer sizes status = api->hsa_ven_amd_aqlprofile_start(&profile_, NULL); if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(status, "aqlprofile_start(NULL)"); - Allocate(rsrc); + status = Allocate(rsrc); + if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(status, "Allocate()"); // Generate start/stop profiling packets status = api->hsa_ven_amd_aqlprofile_start(&profile_, &start); if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(status, "aqlprofile_start"); @@ -211,7 +212,7 @@ class PmcProfile : public Profile { class SqttProfile : public Profile { public: static inline void SetSize(const uint32_t& size) { output_buffer_size_ = size; } - static inline uint32_t GetSize() { return output_buffer_size_; } +// static inline uint32_t GetSize() { return output_buffer_size_; } SqttProfile(const util::AgentInfo* agent_info) : Profile(agent_info) { profile_.type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_SQTT; @@ -225,9 +226,9 @@ class SqttProfile : public Profile { } hsa_status_t Allocate(util::HsaRsrcFactory* rsrc) { - profile_.output_buffer.size = output_buffer_size_; profile_.command_buffer.ptr = rsrc->AllocateSysMemory(agent_info_, profile_.command_buffer.size); + profile_.output_buffer.size = output_buffer_size_; profile_.output_buffer.ptr = rsrc->AllocateLocalMemory(agent_info_, profile_.output_buffer.size); return (profile_.command_buffer.ptr && profile_.output_buffer.ptr) ? HSA_STATUS_SUCCESS diff --git a/test/ctrl/tool.cpp b/test/ctrl/tool.cpp index a5581c6833..b9444972d8 100644 --- a/test/ctrl/tool.cpp +++ b/test/ctrl/tool.cpp @@ -100,8 +100,10 @@ static inline uint32_t GetPid() { return syscall(__NR_getpid); } static inline uint32_t GetTid() { return syscall(__NR_gettid); } // Error handler -void fatal(const char* msg) { - fprintf(stderr, "%s\n", msg); +void fatal(const std::string msg) { + fflush(stdout); + fprintf(stderr, "%s\n\n", msg.c_str()); + fflush(stderr); abort(); } @@ -206,7 +208,7 @@ context_entry_t* alloc_context_entry() { abort(); } - const uint32_t index = next_context_count(); + const uint32_t index = next_context_count() - 1; auto ret = context_array->insert({index, context_entry_t{}}); if (ret.second == false) { fprintf(stderr, "context_array corruption, index repeated %u\n", index); @@ -277,7 +279,6 @@ hsa_status_t trace_data_cb(hsa_ven_amd_aqlprofile_info_type_t info_type, if (info_type == HSA_VEN_AMD_AQLPROFILE_INFO_SQTT_DATA) { fprintf(arg->file, " SE(%u) size(%u)\n", info_data->sample_id, info_data->sqtt_data.size); dump_sqtt_trace(arg->label, info_data->sample_id, info_data->sqtt_data.ptr, info_data->sqtt_data.size); - } else status = HSA_STATUS_ERROR; return status; @@ -305,17 +306,18 @@ void output_results(FILE* file, const rocprofiler_feature_t* features, const uns uint64_t size = 0; const char* ptr = reinterpret_cast(p->data.result_bytes.ptr); + const char* end = reinterpret_cast(ptr + p->data.result_bytes.size); for (unsigned i = 0; i < p->data.result_bytes.instance_count; ++i) { - const uint32_t chunk_size = *reinterpret_cast(ptr); - const char* chunk_data = ptr + sizeof(uint64_t); - dump_sqtt_trace(label, i, chunk_data, chunk_size); + const uint32_t chunk_size = *reinterpret_cast(ptr); + const char* chunk_data = ptr + sizeof(uint32_t); + if (chunk_data >= end) fatal("SQTT data is out of the result buffer size"); - const uint32_t off = align_size(chunk_size, sizeof(uint64_t)); + dump_sqtt_trace(label, i, chunk_data, chunk_size); + const uint32_t off = align_size(chunk_size, sizeof(uint32_t)); ptr = chunk_data + off; - size += chunk_size; + if (chunk_data >= end) fatal("SQTT data ptr is out of the result buffer size"); } fprintf(file, "size(%lu)\n", size); - if (size > p->data.result_bytes.size) fatal("SQTT data size is out of the result buffer size"); free(p->data.result_bytes.ptr); const_cast(p)->data.result_bytes.size = 0; } else { @@ -646,7 +648,7 @@ extern "C" PUBLIC_API void OnLoadTool() } std::map parameters_dict; - parameters_dict["COMPUTE_UNIT_TARGET"] = + parameters_dict["TARGET_CU"] = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_COMPUTE_UNIT_TARGET; parameters_dict["VM_ID_MASK"] = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_VM_ID_MASK; @@ -760,13 +762,21 @@ extern "C" PUBLIC_API void OnLoadTool() unsigned index = metrics_vec.size(); for (auto* entry : traces_list) { auto params_list = xml->GetNodes("top.trace.parameters"); - if (params_list.size() != 1) { - fprintf(stderr, "ROCProfiler: Single input 'parameters' section is supported\n"); - abort(); + if (params_list.size() > 1) { + fatal("ROCProfiler: Single input 'parameters' section is supported"); } - const std::string& name = entry->opts["name"]; - const bool to_copy_data = (entry->opts["copy"] == "true"); - printf(" %s (\n", name.c_str()); + std::string name = ""; + bool to_copy_data = false; + for (const auto& opt : entry->opts) { +// const std::string& name = entry->opts["name"]; +// const bool to_copy_data = (entry->opts["copy"] == "true"); + if (opt.first == "name") name = opt.second; + else if (opt.first == "copy") to_copy_data = (opt.second == "true"); + else fatal("ROCProfiler: Bad trace property '" + opt.first + "'"); + } + if (name == "") fatal("ROCProfiler: Bad trace properties, name is not specified"); + + printf(" %s (", name.c_str()); features[index] = {}; features[index].kind = ROCPROFILER_FEATURE_KIND_TRACE; features[index].name = strdup(name.c_str()); @@ -783,7 +793,7 @@ extern "C" PUBLIC_API void OnLoadTool() abort(); } const uint32_t value = strtol(v.second.c_str(), NULL, 0); - printf(" %s = 0x%x\n", parameter_name.c_str(), value); + printf("\n %s = 0x%x", parameter_name.c_str(), value); parameters[p_index] = {}; parameters[p_index].parameter_name = parameters_dict[parameter_name]; parameters[p_index].value = value; @@ -793,7 +803,9 @@ extern "C" PUBLIC_API void OnLoadTool() features[index].parameters = parameters; features[index].parameter_count = parameter_count; } - printf(" )\n"); + if (params_list.empty() == false) printf("\n "); + printf(")\n"); + fflush(stdout); ++index; } fflush(stdout);