From d4f032e36b84cba331ff9b5e16aa4d447c44391a Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 16 Apr 2021 15:21:14 +0530 Subject: [PATCH] ANDROID: cgroup: Add android_rvh_cgroup_force_kthread_migration In Android GKI, CONFIG_FAIR_GROUP_SCHED is enabled [1] to help prioritize important work. Given that CPU shares of root cgroup can't be changed, leaving the tasks inside root cgroup will give them higher share compared to the other tasks inside important cgroups. This is mitigated by moving all tasks inside root cgroup to a different cgroup after Android is booted. However, there are many kernel tasks stuck in the root cgroup after the boot. It is possible to relax kernel threads and kworkers migrations under certain scenarios. However the patch [2] posted at upstream is not accepted. Hence add a restricted vendor hook to notify modules when a kernel thread is requested for cgroup migration. The modules can relax the restrictions forced by the kernel and allow the cgroup migration. [1] https://android.googlesource.com/kernel/common/+/f08f049de11c15a4251cb1db08cf0bee20bd9b59 [2] https://lore.kernel.org/lkml/1617714261-18111-1-git-send-email-pkondeti@codeaurora.org Bug: 184594949 Change-Id: I445a170ba797c8bece3b4b59b7a42cdd85438f1f Signed-off-by: Pavankumar Kondeti Signed-off-by: Shaleen Agrawal --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/cgroup.h | 3 +++ kernel/cgroup/cgroup-internal.h | 3 ++- kernel/cgroup/cgroup-v1.c | 2 +- kernel/cgroup/cgroup.c | 11 ++++++++--- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index d42aa91214a3..e2e65a987954 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -154,6 +154,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timer_calc_index); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_allow_domain_state); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_exit); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_tick); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_wakeup_ignore); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_replace_next_task_fair); diff --git a/include/trace/hooks/cgroup.h b/include/trace/hooks/cgroup.h index 15f6a348db7c..1c22b84fb8b1 100644 --- a/include/trace/hooks/cgroup.h +++ b/include/trace/hooks/cgroup.h @@ -18,6 +18,9 @@ struct cgroup_taskset; DECLARE_HOOK(android_vh_cgroup_attach, TP_PROTO(struct cgroup_subsys *ss, struct cgroup_taskset *tset), TP_ARGS(ss, tset)) +DECLARE_RESTRICTED_HOOK(android_rvh_cgroup_force_kthread_migration, + TP_PROTO(struct task_struct *tsk, struct cgroup *dst_cgrp, bool *force_migration), + TP_ARGS(tsk, dst_cgrp, force_migration), 1); #endif #include diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h index bfbeabc17a9d..02f32b13d9e5 100644 --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h @@ -232,7 +232,8 @@ int cgroup_migrate(struct task_struct *leader, bool threadgroup, int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, bool threadgroup); struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup, - bool *locked) + bool *locked, + struct cgroup *dst_cgrp); __acquires(&cgroup_threadgroup_rwsem); void cgroup_procs_write_finish(struct task_struct *task, bool locked) __releases(&cgroup_threadgroup_rwsem); diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 865902267bba..a7df8d5c6f41 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -502,7 +502,7 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of, if (!cgrp) return -ENODEV; - task = cgroup_procs_write_start(buf, threadgroup, &locked); + task = cgroup_procs_write_start(buf, threadgroup, &locked, cgrp); ret = PTR_ERR_OR_ZERO(task); if (ret) goto out_unlock; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 300cf3a4863b..2f640903ffd5 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -2793,11 +2793,13 @@ int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, } struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup, - bool *locked) + bool *locked, + struct cgroup *dst_cgrp) __acquires(&cgroup_threadgroup_rwsem) { struct task_struct *tsk; pid_t pid; + bool force_migration = false; if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) return ERR_PTR(-EINVAL); @@ -2832,13 +2834,16 @@ struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup, if (threadgroup) tsk = tsk->group_leader; + if (tsk->flags & PF_KTHREAD) + trace_android_rvh_cgroup_force_kthread_migration(tsk, dst_cgrp, &force_migration); + /* * kthreads may acquire PF_NO_SETAFFINITY during initialization. * If userland migrates such a kthread to a non-root cgroup, it can * become trapped in a cpuset, or RT kthread may be born in a * cgroup with no rt_runtime allocated. Just say no. */ - if (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY)) { + if (!force_migration && (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY))) { tsk = ERR_PTR(-EINVAL); goto out_unlock_threadgroup; } @@ -4881,7 +4886,7 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, if (!dst_cgrp) return -ENODEV; - task = cgroup_procs_write_start(buf, threadgroup, &locked); + task = cgroup_procs_write_start(buf, threadgroup, &locked, dst_cgrp); ret = PTR_ERR_OR_ZERO(task); if (ret) goto out_unlock;