Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f61c25f authored by Jimmy Shiu's avatar Jimmy Shiu Committed by DarkJoker360
Browse files

sched/core: fix userspace affining threads incorrectly by task name.



To identify certain apps which request max cpu freq to affine its
tasks to specific cpus, besides checking its lib name, task name is
also a factor that we can identify the suspcious task.

Test: build and test the 'perfect kick 2' game.
Bug: 163293825
Bug: 161324271
Change-Id: I4359859db743b4c9122e9df40af0b109370e8f1f
Signed-off-by: default avatarJimmy Shiu <jimmyshiu@google.com>
parent 14d08e65
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -145,6 +145,9 @@ extern int sched_little_cluster_coloc_fmin_khz_handler(struct ctl_table *table,
#define LIB_PATH_LENGTH 512
extern char sched_lib_name[LIB_PATH_LENGTH];
extern unsigned int sched_lib_mask_force;
extern int sysctl_sched_lib_name_handler(struct ctl_table *table, int write,
					 void __user *buffer, size_t *lenp,
					 loff_t *ppos);
extern bool is_sched_lib_based_app(pid_t pid);

#endif /* _LINUX_SCHED_SYSCTL_H */
+77 −4
Original line number Diff line number Diff line
@@ -5071,6 +5071,60 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)

char sched_lib_name[LIB_PATH_LENGTH];
unsigned int sched_lib_mask_force;
struct libname_node {
	char *name;
	struct list_head list;
};
static LIST_HEAD(__sched_lib_name_list);
static DEFINE_SPINLOCK(__sched_lib_name_lock);

/*
 * A sysctl callback for handling 'sched_lib_name' operation. Except processing
 * the data with the usual function 'proc_dostring()', additionally tokenize the
 * input text with the dilimiter ',' and store in a linked list
 * '__sched_lib_name_list'.
 */
int sysctl_sched_lib_name_handler(struct ctl_table *table, int write,
				  void __user *buffer, size_t *lenp,
				  loff_t *ppos)
{
	int ret;
	char *curr, *next;
	char dup_sched_lib_name[LIB_PATH_LENGTH];
	struct libname_node *pos, *tmp;

	ret = proc_dostring(table, write, buffer, lenp, ppos);
	if (write && !ret) {
		spin_lock(&__sched_lib_name_lock);
		/* Free the old list. */
		if (!list_empty(&__sched_lib_name_list)) {
			list_for_each_entry_safe (
				pos, tmp, &__sched_lib_name_list, list) {
				list_del(&pos->list);
				kfree(pos->name);
				kfree(pos);
			}
		}

		if (strnlen(sched_lib_name, LIB_PATH_LENGTH) == 0) {
			spin_unlock(&__sched_lib_name_lock);
			return 0;
		}

		/* Split sched_lib_name by ',' and store in a linked list. */
		strlcpy(dup_sched_lib_name, sched_lib_name, LIB_PATH_LENGTH);
		next = dup_sched_lib_name;
		while ((curr = strsep(&next, ",")) != NULL) {
			pos = kmalloc(sizeof(struct libname_node), GFP_KERNEL);
			pos->name = kstrdup(curr, GFP_KERNEL);
			list_add_tail(&pos->list, &__sched_lib_name_list);
		}
		spin_unlock(&__sched_lib_name_lock);
	}

	return ret;
}

bool is_sched_lib_based_app(pid_t pid)
{
	const char *name = NULL;
@@ -5079,6 +5133,7 @@ bool is_sched_lib_based_app(pid_t pid)
	bool found = false;
	struct task_struct *p;
	struct mm_struct *mm;
	struct libname_node *pos;

	if (strnlen(sched_lib_name, LIB_PATH_LENGTH) == 0)
		return false;
@@ -5095,6 +5150,17 @@ bool is_sched_lib_based_app(pid_t pid)
	get_task_struct(p);
	rcu_read_unlock();

	spin_lock(&__sched_lib_name_lock);
	/* Check if the task name equals any of the sched_lib_name list. */
	list_for_each_entry (pos, &__sched_lib_name_list, list) {
		if (!strncmp(p->comm, pos->name, LIB_PATH_LENGTH)) {
			found = true;
			spin_unlock(&__sched_lib_name_lock);
			goto put_task_struct;
		}
	}
	spin_unlock(&__sched_lib_name_lock);

	mm = get_task_mm(p);
	if (!mm)
		goto put_task_struct;
@@ -5107,12 +5173,19 @@ bool is_sched_lib_based_app(pid_t pid)
			if (IS_ERR(name))
				goto release_sem;

			if (strnstr(name, sched_lib_name,
			/* Check if the file name includes any of the
			 * sched_lib_name list. */
			spin_lock(&__sched_lib_name_lock);
			list_for_each_entry (pos, &__sched_lib_name_list,
					     list) {
				if (strnstr(name, pos->name,
					    strnlen(name, LIB_PATH_LENGTH))) {
					found = true;
					break;
				}
			}
			spin_unlock(&__sched_lib_name_lock);
		}
	}

release_sem:
+1 −1
Original line number Diff line number Diff line
@@ -638,7 +638,7 @@ static struct ctl_table kern_table[] = {
		.data		= sched_lib_name,
		.maxlen		= LIB_PATH_LENGTH,
		.mode		= 0644,
		.proc_handler	= proc_dostring,
		.proc_handler	= sysctl_sched_lib_name_handler,
	},
	{
		.procname	= "sched_lib_mask_force",