diff --git a/src/runtime_src/core/common/info_telemetry.cpp b/src/runtime_src/core/common/info_telemetry.cpp index 7164fe9f01..14151d456f 100644 --- a/src/runtime_src/core/common/info_telemetry.cpp +++ b/src/runtime_src/core/common/info_telemetry.cpp @@ -34,6 +34,27 @@ add_rtos_tasks(const xrt_core::device* device, boost::property_tree::ptree& pt) } pt_rtos_inst.add_child("dtlb_data", pt_dtlbs); + boost::property_tree::ptree pt_preempts; + for (auto& kp : rtos_task.preemption_data) { + boost::property_tree::ptree pt_preempt; + + //add a check for not supported + if(static_cast(kp.preemption_flag_set) == -1) + return; //not supported + if(static_cast(kp.slot_index) == -1) + pt_preempt.put("slot_index", kp.slot_index); + pt_preempt.put("preemption_flag_set", kp.preemption_flag_set); + if(static_cast(kp.preemption_flag_unset) == -1) + pt_preempt.put("preemption_flag_unset", kp.preemption_flag_unset); + if(static_cast(kp.preemption_checkpoint_event) == -1) + pt_preempt.put("preemption_checkpoint_event", kp.preemption_checkpoint_event); + if(static_cast(kp.frame_boundary_preemption_events) == -1) + pt_preempt.put("frame_boundary_preemption_events", kp.frame_boundary_preemption_events); + + pt_preempts.push_back({"", pt_preempt}); + } + pt_rtos_inst.add_child("preemption_data", pt_preempts); + pt_rtos_array.push_back({"", pt_rtos_inst}); } pt.add_child("rtos_tasks", pt_rtos_array); diff --git a/src/runtime_src/core/common/query_requests.h b/src/runtime_src/core/common/query_requests.h index 26e596da1d..0c4b6fc729 100644 --- a/src/runtime_src/core/common/query_requests.h +++ b/src/runtime_src/core/common/query_requests.h @@ -1815,6 +1815,14 @@ struct rtos_telemetry : request uint64_t misses; }; + struct preempt_data { + uint64_t slot_index; + uint64_t preemption_flag_set; + uint64_t preemption_flag_unset; + uint64_t preemption_checkpoint_event; + uint64_t frame_boundary_preemption_events; + }; + struct data { uint64_t context_starts; uint64_t schedules; @@ -1822,6 +1830,7 @@ struct rtos_telemetry : request uint64_t dma_access; uint64_t resource_acquisition; std::vector dtlbs; + std::vector preemption_data; }; using result_type = std::vector; @@ -3812,8 +3821,8 @@ struct performance_mode : request */ struct preemption : request { - using result_type = uint32_t; // get value type - using value_type = uint32_t; // put value type + using result_type = bool; // get value type + using value_type = bool; // put value type static const key_type key = key_type::preemption; diff --git a/src/runtime_src/core/tools/common/reports/ReportTelemetry.cpp b/src/runtime_src/core/tools/common/reports/ReportTelemetry.cpp index 8bd333b4ff..00d3fc80e1 100644 --- a/src/runtime_src/core/tools/common/reports/ReportTelemetry.cpp +++ b/src/runtime_src/core/tools/common/reports/ReportTelemetry.cpp @@ -33,7 +33,7 @@ generate_rtos_dtlb_string(const boost::property_tree::ptree& pt) std::stringstream ss; boost::property_tree::ptree rtos_tasks = pt.get_child("rtos_tasks", empty_ptree); - boost::property_tree::ptree rtos_dtlb_data = pt.get_child("rtos_tasks..dtlb_data", empty_ptree); + boost::property_tree::ptree rtos_dtlb_data = pt.get_child("rtos_tasks.dtlb_data", empty_ptree); if(rtos_tasks.empty() && rtos_dtlb_data.empty()) return ss.str(); @@ -69,6 +69,46 @@ generate_rtos_dtlb_string(const boost::property_tree::ptree& pt) return ss.str(); } +static std::string +generate_preemption_data_string(const boost::property_tree::ptree& pt) +{ + std::stringstream ss; + boost::property_tree::ptree rtos_tasks = pt.get_child("rtos_tasks", empty_ptree); + boost::property_tree::ptree rtos_preemption_data = pt.get_child("rtos_tasks.preemption_data", empty_ptree); + if(rtos_tasks.empty() && rtos_preemption_data.empty()) + return ss.str(); + + std::vector preempt_headers = { + {"User Task", Table2D::Justification::left}, + {"Ctx ID", Table2D::Justification::left}, + {"Set Hints", Table2D::Justification::left}, + {"Unset Hints", Table2D::Justification::left}, + {"Checkpoint Events", Table2D::Justification::left}, + {"Frame Boundary Events", Table2D::Justification::left}, + }; + Table2D preemption_table(preempt_headers); + + int index = 0; + for (const auto& [name, rtos_task] : rtos_preemption_data) { + const std::vector rtos_data = { + std::to_string(index), + std::to_string(rtos_task.get("slot_index")), + std::to_string(rtos_task.get("preemption_flag_set")), + std::to_string(rtos_task.get("preemption_flag_unset")), + std::to_string(rtos_task.get("preemption_checkpoint_event")), + std::to_string(rtos_task.get("frame_boundary_preemption_events")), + }; + preemption_table.addEntry(rtos_data); + + index++; + } + + ss << " Premption Table\n"; + ss << preemption_table.toString(" ") << "\n"; + + return ss.str(); +} + static std::string generate_rtos_string(const boost::property_tree::ptree& pt) { @@ -225,6 +265,7 @@ ReportTelemetry::writeReport(const xrt_core::device* /*_pDevice*/, _output << generate_misc_string(telemetry_pt); _output << generate_rtos_string(telemetry_pt); _output << generate_rtos_dtlb_string(telemetry_pt); + _output << generate_preemption_data_string(telemetry_pt); _output << generate_opcode_string(telemetry_pt); _output << generate_stream_buffer_string(telemetry_pt); _output << generate_aie_string(telemetry_pt); diff --git a/src/runtime_src/core/tools/xbutil2/OO_Preemption.cpp b/src/runtime_src/core/tools/xbutil2/OO_Preemption.cpp index b50db4a15c..db0b7c9599 100644 --- a/src/runtime_src/core/tools/xbutil2/OO_Preemption.cpp +++ b/src/runtime_src/core/tools/xbutil2/OO_Preemption.cpp @@ -85,10 +85,10 @@ OO_Preemption::execute(const SubCmdOptions& _options) const try { if (boost::iequals(m_action, "enable")) { - xrt_core::device_update(device.get(), static_cast(1)); // default + xrt_core::device_update(device.get(), static_cast(1)); // default } else if (boost::iequals(m_action, "disable")) { - xrt_core::device_update(device.get(), static_cast(0)); + xrt_core::device_update(device.get(), static_cast(0)); } else { throw xrt_core::error(boost::str(boost::format("Invalid force-preemption value: '%s'\n") % m_action));