pps: make pps-producer RT only on freedreno

Calling sched_setscheduler twice every sample period has high CPU
overhead.  For intel and panfrost, their dump_perfcnt is preemptible and
they don't need the scheduler change.

For freedreno, simply makes the main thread RT at all time.  This solves
most of the cpu overhead issue.

v2: removed pthread_t param and just change the scheduler for the
    calling thread

Acked-by: Rob Clark <robdclark@chromium.org> (v1)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19668>
This commit is contained in:
Chia-I Wu 2022-11-10 17:45:28 -08:00 committed by Marge Bot
parent 557120b593
commit 339d80d5f2
7 changed files with 28 additions and 15 deletions

View file

@ -37,6 +37,12 @@ percent(uint64_t a, uint64_t b)
return 100.f * (a / static_cast<double>(b));
}
bool
FreedrenoDriver::is_dump_perfcnt_preemptible() const
{
return false;
}
uint64_t
FreedrenoDriver::get_min_sampling_period_ns()
{

View file

@ -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;

View file

@ -10,6 +10,8 @@
#include <cerrno>
#include <cstring>
#include <sched.h>
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

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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);