From d4bbaf57157abacde004d937e6c4bd8e2a39d508 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Sat, 11 May 2024 00:10:43 -0700 Subject: [PATCH] sched/core: Forbid Unity-based games from changing their CPU affinity Unity-based games (such as Wild Rift) like to shoot themselves in the foot by setting a nonsense CPU affinity, restricting the game to a narrow set of CPU cores that it thinks are the "big" cores in a heterogeneous CPU. It assumes that CPUs only have two performance domains (clusters), and therefore royally mucks up games' CPU affinities on CPUs which have more than two performance domains. Check if a setaffinity target task is part of a Unity-based game and silently ignore the setaffinity request so that it can't sabotage itself. Signed-off-by: Sultan Alsawaf --- kernel/sched/core.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d8c60e74c..b242b4167 100755 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6177,11 +6177,32 @@ out_unlock: return retval; } +static bool task_is_unity_game(struct task_struct *p) +{ + struct task_struct *t; + bool ret = false; + + /* Filter for Android user applications (i.e., positive adj) */ + if (p->signal->oom_score_adj >= 0) { + rcu_read_lock(); + for_each_thread(p, t) { + /* Check for a UnityMain thread in the thread group */ + if (!strcmp(t->comm, "UnityMain")) { + ret = true; + break; + } + } + rcu_read_unlock(); + } + + return ret; +} + long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) { cpumask_var_t cpus_allowed, new_mask; struct task_struct *p; - int retval; + int retval = 0; int skip = 0; rcu_read_lock(); @@ -6196,6 +6217,20 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) get_task_struct(p); rcu_read_unlock(); + /* + * Unity-based games like to shoot themselves in the foot by setting a + * nonsense CPU affinity, restricting the game to a narrow set of CPU + * cores that it thinks are the "big" cores in a heterogeneous CPU. It + * assumes that CPUs only have two performance domains (clusters), and + * therefore royally mucks up games' CPU affinities on CPUs which have + * more than two performance domains. + * + * Check if the target task is part of a Unity-based game and silently + * ignore the setaffinity request so that it can't sabotage itself. + */ + if (task_is_unity_game(p)) + goto out_put_task; + if (p->flags & PF_NO_SETAFFINITY) { retval = -EINVAL; goto out_put_task;