Skip to content

Commit

Permalink
sched/core: Forbid Unity-based games from changing their CPU affinity
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
kerneltoast authored and mylove90 committed May 18, 2024
1 parent 0c2a480 commit 245b1a1
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5782,6 +5782,28 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
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;
Expand All @@ -5802,6 +5824,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;
Expand Down

0 comments on commit 245b1a1

Please sign in to comment.