Browse Source

Update gamemode-context.c

added support for disabling the kernel split lock mitigation when entering game mode
Henrik Holst 1 year ago
parent
commit
9a7ee00bbf
1 changed files with 60 additions and 0 deletions
  1. 60 0
      daemon/gamemode-context.c

+ 60 - 0
daemon/gamemode-context.c

@@ -91,6 +91,8 @@ struct GameModeContext {
 	uint32_t last_cpu_energy_uj;
 	uint32_t last_igpu_energy_uj;
 
+	long initial_split_lock_mitigate;
+
 	/* Reaper control */
 	struct {
 		pthread_t thread;
@@ -114,6 +116,7 @@ static void game_mode_context_enter(GameModeContext *self);
 static void game_mode_context_leave(GameModeContext *self);
 static char *game_mode_context_find_exe(pid_t pid);
 static void game_mode_execute_scripts(char scripts[CONFIG_LIST_MAX][CONFIG_VALUE_MAX], int timeout);
+static int game_mode_disable_splitlock(GameModeContext *self, bool disable);
 
 static void start_reaper_thread(GameModeContext *self)
 {
@@ -151,6 +154,8 @@ void game_mode_context_init(GameModeContext *self)
 	/* Initialise the current CPU info */
 	game_mode_initialise_cpu(self->config, &self->cpu);
 
+	self->initial_split_lock_mitigate = -1;
+
 	pthread_rwlock_init(&self->rwlock, NULL);
 
 	/* Get the reaper thread going */
@@ -202,6 +207,57 @@ void game_mode_context_destroy(GameModeContext *self)
 	pthread_rwlock_destroy(&self->rwlock);
 }
 
+static int game_mode_disable_splitlock(GameModeContext *self, bool disable)
+{
+	if (!config_get_disable_splitlock(self->config))
+		return 0;
+
+	long value_num = self->initial_split_lock_mitigate;
+	char value_str[40];
+
+	if (disable) {
+		FILE *f = fopen("/proc/sys/kernel/split_lock_mitigate", "r");
+		if (f == NULL) {
+			if (errno == ENOENT)
+				return 0;
+
+			LOG_ERROR("Couldn't open /proc/sys/kernel/split_lock_mitigate : %s\n", strerror(errno));
+			return 1;
+		}
+
+		if (fgets(value_str, sizeof value_str, f) == NULL) {
+			LOG_ERROR("Couldn't read from /proc/sys/kernel/split_lock_mitigate : %s\n", strerror(errno));
+			fclose(f);
+			return 1;
+		}
+
+		self->initial_split_lock_mitigate = strtol (value_str, NULL, 10);
+		fclose(f);
+
+		value_num = 0;
+		if (self->initial_split_lock_mitigate == value_num)
+			return 0;
+	}
+
+	if (value_num == -1)
+		return 0;
+
+	sprintf(value_str, "%ld", value_num);
+
+	const char *const exec_args[] = {
+		"pkexec", LIBEXECDIR "/procsysctl", "split_lock_mitigate", value_str, NULL,
+	};
+
+	LOG_MSG("Requesting update of split_lock_mitigate to %s\n", value_str);
+	int ret = run_external_process(exec_args, NULL, -1);
+	if (ret != 0) {
+		LOG_ERROR("Failed to update split_lock_mitigate\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int game_mode_set_governor(GameModeContext *self, enum GameModeGovernor gov)
 {
 	if (self->current_govenor == gov) {
@@ -369,6 +425,8 @@ static void game_mode_context_enter(GameModeContext *self)
 	if (config_get_inhibit_screensaver(self->config))
 		game_mode_inhibit_screensaver(true);
 
+	game_mode_disable_splitlock(self, true);
+	
 	/* Apply GPU optimisations by first getting the current values, and then setting the target */
 	game_mode_get_gpu(self->stored_gpu);
 	game_mode_apply_gpu(self->target_gpu);
@@ -404,6 +462,8 @@ static void game_mode_context_leave(GameModeContext *self)
 	if (config_get_inhibit_screensaver(self->config))
 		game_mode_inhibit_screensaver(false);
 
+	game_mode_disable_splitlock(self, false);
+	
 	game_mode_set_governor(self, GAME_MODE_GOVERNOR_DEFAULT);
 
 	game_mode_disable_igpu_optimization(self);