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: Jimmy Shiu <jimmyshiu@google.com>
This commit is contained in:
Jimmy Shiu 2020-08-13 13:59:27 +08:00 committed by spakkkk
parent f2ae9c47a3
commit 6e37e97e35
3 changed files with 81 additions and 5 deletions

View File

@ -166,6 +166,9 @@ extern int sched_energy_aware_handler(struct ctl_table *table, int write,
#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 */

View File

@ -5815,6 +5815,60 @@ EXPORT_SYMBOL_GPL(sched_setaffinity);
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;
@ -5823,6 +5877,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;
@ -5839,6 +5894,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;
@ -5851,11 +5917,18 @@ bool is_sched_lib_based_app(pid_t pid)
if (IS_ERR(name))
goto release_sem;
if (strnstr(name, sched_lib_name,
strnlen(name, LIB_PATH_LENGTH))) {
found = true;
break;
/* 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);
}
}

View File

@ -821,7 +821,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",