Przeglądaj źródła

Save all state before any of it is changed

The platform profile may restrict what values the governor can take, so
we need to save all state first to ensure the restored state is correct.
Then, the platform profile is the first thing we set (and restore) to
ensure all other changes are made to the best of our ability.
MithicSpirit 1 miesiąc temu
rodzic
commit
2d71be6a94
1 zmienionych plików z 75 dodań i 54 usunięć
  1. 75 54
      daemon/gamemode-context.c

+ 75 - 54
daemon/gamemode-context.c

@@ -218,6 +218,29 @@ void game_mode_context_destroy(GameModeContext *self)
 	pthread_rwlock_destroy(&self->rwlock);
 }
 
+static void game_mode_store_splitlock(GameModeContext *self)
+{
+	FILE *f = fopen("/proc/sys/kernel/split_lock_mitigate", "r");
+	if (f == NULL) {
+		if (errno == ENOENT)
+			return;
+
+		LOG_ERROR("Couldn't open /proc/sys/kernel/split_lock_mitigate : %s\n", strerror(errno));
+		return;
+	}
+
+	char value_str[40];
+	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;
+	}
+	fclose(f);
+
+	self->initial_split_lock_mitigate = strtol(value_str, NULL, 10);
+}
+
 static int game_mode_disable_splitlock(GameModeContext *self, bool disable)
 {
 	if (!config_get_disable_splitlock(self->config))
@@ -226,30 +249,8 @@ static int game_mode_disable_splitlock(GameModeContext *self, bool disable)
 	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 (disable && value_num == 0)
+		return 0;
 
 	if (value_num == -1)
 		return 0;
@@ -270,25 +271,26 @@ static int game_mode_disable_splitlock(GameModeContext *self, bool disable)
 	return 0;
 }
 
+static void game_mode_store_governor(GameModeContext *self)
+{
+	if (self->current_govenor != GAME_MODE_GOVERNOR_DEFAULT)
+		return;
+
+	const char *initial_state = get_gov_state();
+	if (initial_state == NULL)
+		return;
+
+	strncpy(self->initial_cpu_mode, initial_state, sizeof(self->initial_cpu_mode) - 1);
+	self->initial_cpu_mode[sizeof(self->initial_cpu_mode) - 1] = '\0';
+	LOG_MSG("governor was initially set to [%s]\n", initial_state);
+}
+
 static int game_mode_set_governor(GameModeContext *self, enum GameModeGovernor gov)
 {
 	if (self->current_govenor == gov) {
 		return 0;
 	}
 
-	if (self->current_govenor == GAME_MODE_GOVERNOR_DEFAULT) {
-		/* Read the initial governor state so we can revert it correctly */
-		const char *initial_state = get_gov_state();
-		if (initial_state == NULL) {
-			return 0;
-		}
-
-		/* store the initial cpu governor mode */
-		strncpy(self->initial_cpu_mode, initial_state, sizeof(self->initial_cpu_mode) - 1);
-		self->initial_cpu_mode[sizeof(self->initial_cpu_mode) - 1] = '\0';
-		LOG_MSG("governor was initially set to [%s]\n", initial_state);
-	}
-
 	char *gov_str = NULL;
 	char gov_config_str[CONFIG_VALUE_MAX] = { 0 };
 	switch (gov) {
@@ -328,25 +330,26 @@ static int game_mode_set_governor(GameModeContext *self, enum GameModeGovernor g
 	return 0;
 }
 
+static void game_mode_store_profile(GameModeContext *self)
+{
+	if (self->current_profile != GAME_MODE_PROFILE_DEFAULT)
+		return;
+
+	const char *initial_state = get_profile_state();
+	if (initial_state == NULL)
+		return;
+
+	strncpy(self->initial_profile, initial_state, sizeof(self->initial_profile) - 1);
+	self->initial_profile[sizeof(self->initial_profile) - 1] = '\0';
+	LOG_MSG("platform profile was initially set to [%s]\n", initial_state);
+}
+
 static int game_mode_set_profile(GameModeContext *self, enum GameModeProfile prof)
 {
 	if (self->current_profile == prof) {
 		return 0;
 	}
 
-	if (self->current_profile == GAME_MODE_PROFILE_DEFAULT) {
-		/* Read the initial platform profile so we can revert it correctly */
-		const char *initial_state = get_profile_state();
-		if (initial_state == NULL) {
-			return 0;
-		}
-
-		/* store the initial platform profile */
-		strncpy(self->initial_profile, initial_state, sizeof(self->initial_profile) - 1);
-		self->initial_profile[sizeof(self->initial_profile) - 1] = '\0';
-		LOG_MSG("platform profile was initially set to [%s]\n", initial_state);
-	}
-
 	const char *prof_str = NULL;
 	char prof_config_str[CONFIG_VALUE_MAX] = { 0 };
 	switch (prof) {
@@ -468,6 +471,15 @@ unlock:
 	pthread_rwlock_unlock(&self->rwlock);
 }
 
+static void game_mode_context_store_defaults(GameModeContext *self)
+{
+	game_mode_store_profile(self);
+
+	game_mode_store_governor(self);
+
+	game_mode_store_splitlock(self);
+}
+
 /**
  * Pivot into game mode.
  *
@@ -479,6 +491,14 @@ static void game_mode_context_enter(GameModeContext *self)
 	LOG_MSG("Entering Game Mode...\n");
 	sd_notifyf(0, "STATUS=%sGameMode is now active.%s\n", "\x1B[1;32m", "\x1B[0m");
 
+	/* Store the default value for everything before anything changes. */
+	game_mode_context_store_defaults(self);
+
+	/* Set the profile before anything else since it can restrict things
+	 * like the governor.
+	 */
+	game_mode_set_profile(self, GAME_MODE_PROFILE_DESIRED);
+
 	if (game_mode_set_governor(self, GAME_MODE_GOVERNOR_DESIRED) == 0) {
 		/* We just switched to a non-default governor.  Enable the iGPU
 		 * optimization.
@@ -486,8 +506,6 @@ static void game_mode_context_enter(GameModeContext *self)
 		game_mode_enable_igpu_optimization(self);
 	}
 
-	game_mode_set_profile(self, GAME_MODE_PROFILE_DESIRED);
-
 	/* Inhibit the screensaver */
 	if (config_get_inhibit_screensaver(self->config)) {
 		game_mode_destroy_idle_inhibitor(self->idle_inhibitor);
@@ -522,6 +540,11 @@ static void game_mode_context_leave(GameModeContext *self)
 	LOG_MSG("Leaving Game Mode...\n");
 	sd_notifyf(0, "STATUS=%sGameMode is currently deactivated.%s\n", "\x1B[1;36m", "\x1B[0m");
 
+	/* Restore profile before anything else since it can restrict things
+	 * like the governor.
+	 */
+	game_mode_set_profile(self, GAME_MODE_PROFILE_DEFAULT);
+
 	/* Remove GPU optimisations */
 	game_mode_apply_gpu(self->stored_gpu);
 
@@ -535,8 +558,6 @@ static void game_mode_context_leave(GameModeContext *self)
 
 	game_mode_disable_splitlock(self, false);
 
-	game_mode_set_profile(self, GAME_MODE_PROFILE_DEFAULT);
-
 	game_mode_set_governor(self, GAME_MODE_GOVERNOR_DEFAULT);
 
 	game_mode_disable_igpu_optimization(self);