diff --git a/src/freedreno/ds/fd_pps_driver.cc b/src/freedreno/ds/fd_pps_driver.cc index a75f4435d99..57a32f50c5c 100644 --- a/src/freedreno/ds/fd_pps_driver.cc +++ b/src/freedreno/ds/fd_pps_driver.cc @@ -37,6 +37,12 @@ percent(uint64_t a, uint64_t b) return 100.f * (a / static_cast(b)); } +bool +FreedrenoDriver::is_dump_perfcnt_preemptible() const +{ + return false; +} + uint64_t FreedrenoDriver::get_min_sampling_period_ns() { diff --git a/src/freedreno/ds/fd_pps_driver.h b/src/freedreno/ds/fd_pps_driver.h index 0da9cfcebfa..5db3c175b6c 100644 --- a/src/freedreno/ds/fd_pps_driver.h +++ b/src/freedreno/ds/fd_pps_driver.h @@ -20,6 +20,7 @@ namespace pps class FreedrenoDriver : public Driver { public: + bool is_dump_perfcnt_preemptible() const override; uint64_t get_min_sampling_period_ns() override; bool init_perfcnt() override; void enable_counter(uint32_t counter_id) override; diff --git a/src/tool/pps/pps.cc b/src/tool/pps/pps.cc index 0aa2e930f8c..dacbb717a5c 100644 --- a/src/tool/pps/pps.cc +++ b/src/tool/pps/pps.cc @@ -10,6 +10,8 @@ #include #include +#include + namespace pps { bool check(int res, const char *msg) @@ -23,4 +25,14 @@ bool check(int res, const char *msg) return true; } +void make_thread_rt() +{ + // Use FIFO policy to avoid preemption while collecting counters + int sched_policy = SCHED_FIFO; + // Do not use max priority to avoid starving migration and watchdog threads + int priority_value = sched_get_priority_max(sched_policy) - 1; + sched_param priority_param { priority_value }; + sched_setscheduler(0, sched_policy, &priority_param); +} + } // namespace pps diff --git a/src/tool/pps/pps.h b/src/tool/pps/pps.h index 639cccbb5f6..2be10628de4 100644 --- a/src/tool/pps/pps.h +++ b/src/tool/pps/pps.h @@ -27,6 +27,8 @@ enum class State { /// @return True if ok, false otherwise bool check(int res, const char *msg); +void make_thread_rt(); + /// @param num Numerator /// @param den Denominator /// @return A ratio between two floating point numbers, or 0 if the denominator is 0 diff --git a/src/tool/pps/pps_datasource.cc b/src/tool/pps/pps_datasource.cc index 5584e9833ea..088bc7ec975 100644 --- a/src/tool/pps/pps_datasource.cc +++ b/src/tool/pps/pps_datasource.cc @@ -306,18 +306,6 @@ void GpuDataSource::trace(TraceContext &ctx) state->was_cleared = false; } - // Save current scheduler for restoring later - int prev_sched_policy = sched_getscheduler(0); - sched_param prev_priority_param; - sched_getparam(0, &prev_priority_param); - - // Use FIFO policy to avoid preemption while collecting counters - int sched_policy = SCHED_FIFO; - // Do not use max priority to avoid starving migration and watchdog threads - int priority_value = sched_get_priority_max(sched_policy) - 1; - sched_param priority_param { priority_value }; - sched_setscheduler(0, sched_policy, &priority_param); - if (driver->dump_perfcnt()) { while (auto gpu_timestamp = driver->next()) { if (gpu_timestamp <= descriptor_gpu_timestamp) { @@ -346,9 +334,6 @@ void GpuDataSource::trace(TraceContext &ctx) add_timestamp(event, driver); last_correlation_timestamp = cpu_ts; } - - // Reset normal scheduler - sched_setscheduler(0, prev_sched_policy, &prev_priority_param); } void GpuDataSource::trace_callback(TraceContext ctx) diff --git a/src/tool/pps/pps_driver.h b/src/tool/pps/pps_driver.h index 8d1c59631ac..05791cafcb1 100644 --- a/src/tool/pps/pps_driver.h +++ b/src/tool/pps/pps_driver.h @@ -45,6 +45,9 @@ class Driver Driver(const Driver &) = delete; Driver &operator=(const Driver &) = delete; + /// @return Whether dump_perfcnt is preemptible + virtual bool is_dump_perfcnt_preemptible() const { return true; } + /// @return The minimum sampling period for the current device virtual uint64_t get_min_sampling_period_ns() = 0; diff --git a/src/tool/pps/pps_producer.cc b/src/tool/pps/pps_producer.cc index 69ff7193b4f..f0df89652ec 100644 --- a/src/tool/pps/pps_producer.cc +++ b/src/tool/pps/pps_producer.cc @@ -24,6 +24,10 @@ int main(int argc, const char **argv) (argc > 1) ? Driver::find_driver_name(argv[1]) : Driver::default_driver_name(); GpuDataSource::register_data_source(driver_name); + const auto &driver = Driver::get_supported_drivers().at(driver_name); + if (!driver->is_dump_perfcnt_preemptible()) + make_thread_rt(); + while (true) { GpuDataSource::wait_started(); GpuDataSource::Trace(GpuDataSource::trace_callback);