From addfe1fbc0f8583ad5b4cf68ba1ffc505ed2cba7 Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Thu, 24 May 2018 22:36:56 +0200 Subject: [PATCH] scheduler: Add heuristics and option to force on/off This commit adds a simple heuristic to auto detect whether to use SCHED_ISO or not. It does this by looking at the number of cores: According to some reports by users of SCHED_ISO and an explanation by Con Kolivas, games running busy loops and running on too few cores might start fighting with scheduling of the graphic driver, leading to priority inversion. This results in actually lower performance. So let's only enable SCHED_ISO on at least four cores. The user can still force SCHED_ISO on or off by setting the configuration value. All other values (or none) will apply heuristics. Signed-off-by: Kai Krakow --- daemon/gamemode.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/daemon/gamemode.c b/daemon/gamemode.c index db1c048..0012e44 100644 --- a/daemon/gamemode.c +++ b/daemon/gamemode.c @@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include /* SCHED_ISO may not be defined as it is a reserved value not yet @@ -175,7 +176,7 @@ void game_mode_context_destroy(GameModeContext *self) * everything will be good: Scheduling is only applied to the client and * its children. */ -static void game_mode_apply_scheduler(pid_t client) +static void game_mode_apply_scheduler(GameModeContext *self, pid_t client) { LOG_MSG("Setting scheduling policies...\n"); @@ -188,11 +189,32 @@ static void game_mode_apply_scheduler(pid_t client) LOG_ERROR("Renicing client [%d] failed with error %d, ignoring.\n", client, errno); } - const struct sched_param p = { .sched_priority = 0 }; - if (sched_setscheduler(client, SCHED_ISO, &p)) { - LOG_ERROR("Setting client [%d] to SCHED_ISO failed with error %d, ignoring.\n", - client, - errno); + /* + * read configuration "softrealtime" (on, off, auto) + */ + char softrealtime[CONFIG_VALUE_MAX] = { 0 }; + config_get_soft_realtime(self->config, softrealtime); + + /* + * Enable unconditionally or auto-detect soft realtime usage, + * auto detection is based on observations where dual-core CPU suffered + * priority inversion problems with the graphics driver thus running + * slower as a result, so enable only with more than 3 cores. + */ + bool enable_softrealtime = (strcmp(softrealtime, "on") == 0) || (get_nprocs() > 3); + + /* + * Actually apply the scheduler policy if not explicitly turned off + */ + if (!(strcmp(softrealtime, "off") == 0) && (enable_softrealtime)) { + const struct sched_param p = { .sched_priority = 0 }; + if (sched_setscheduler(client, SCHED_ISO, &p)) { + LOG_ERROR("Setting client [%d] to SCHED_ISO failed with error %d, ignoring.\n", + client, + errno); + } + } else { + LOG_ERROR("Not using softrealtime, setting is '%s'.\n", softrealtime); } } @@ -390,7 +412,7 @@ bool game_mode_context_register(GameModeContext *self, pid_t client) } /* Apply scheduler policies */ - game_mode_apply_scheduler(client); + game_mode_apply_scheduler(self, client); return true; }