mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
kernel/sched/walt: check migration disabled in allowed_ptr_locked
migrate_disable is called to prevent moving a task to a different cpu. In the process it will update the task's cpus_ptr to a temporary mask to restrict the task to run only on the current cpu. It has only one cpu set in this new mask. migrate_disable must always be paired with a migrate_enable call. When migrate_enable is called it will attempt to manipulate the allowed ptrs mask just prior to actually enabling migration on a task. This means __set_cpus_allowed_ptr is called. This calls a tracehook: migrate_enable __set_cpus_allowed_ptr __set_cpus_allowed_ptr_locked trace_android_rvh_set_cpus_allowed_ptr_locked android_rvh_set_cpus_allowed_ptr_locked The purpose of handling this hook in walt, is to prevent the assignment of a task to a halted cpu. When migrate_enable restores the affinity to p->cpus_mask and p->cpus_mask consists of a single cpu and that single cpu is halted, WALT will cause __set_cpus_allowed_ptr to reject and return early. IOW p->cpus_ptr is not set to p->cpus_mask. If the p->cpus_ptr is not restored to point to the p->cpus_mask, a subsequent migrate_disable/migrate_enable can happen, and is allowed to happen with the runque lock taken. Since the p->cpus_ptr is not pointing to the p->cpus_mask, migrate_enable will incorrectly call __set_cpus_allowed_ptr. This in turn will take the runque lock again resulting in a spinlock recursion. Address this by updating the hook code, checking the migrate_disabled flag for the task, and allowing the existing cpu to be used even if that cpu is halted. To achieve this utilize a different hook that is present in the code already: trace_android_rvh_set_cpus_allowed_by_task(). Change-Id: I42204332d708c6bc96f5de52eb9739d17cfdc0a3 Signed-off-by: Stephen Dickey <quic_dickey@quicinc.com>
This commit is contained in:
parent
30c5ecaa7f
commit
a602accc3c
|
|
@ -500,17 +500,18 @@ static void android_rvh_get_nohz_timer_target(void *unused, int *cpu, bool *done
|
|||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void android_rvh_set_cpus_allowed_ptr_locked(void *unused,
|
||||
const struct cpumask *cpu_valid_mask,
|
||||
const struct cpumask *new_mask,
|
||||
unsigned int *dest_cpu)
|
||||
static void android_rvh_set_cpus_allowed_by_task(void *unused,
|
||||
const struct cpumask *cpu_valid_mask,
|
||||
const struct cpumask *new_mask,
|
||||
struct task_struct *p,
|
||||
unsigned int *dest_cpu)
|
||||
{
|
||||
cpumask_t allowed_cpus;
|
||||
|
||||
if (unlikely(walt_disabled))
|
||||
return;
|
||||
|
||||
if (cpu_halted(*dest_cpu)) {
|
||||
if (cpu_halted(*dest_cpu) && !p->migration_disabled) {
|
||||
/* remove halted cpus from the valid mask, and store locally */
|
||||
cpumask_andnot(&allowed_cpus, cpu_valid_mask, cpu_halt_mask);
|
||||
*dest_cpu = cpumask_any_and_distribute(&allowed_cpus, new_mask);
|
||||
|
|
@ -573,8 +574,8 @@ void walt_halt_init(void)
|
|||
sched_setscheduler_nocheck(walt_drain_thread, SCHED_FIFO, ¶m);
|
||||
|
||||
register_trace_android_rvh_get_nohz_timer_target(android_rvh_get_nohz_timer_target, NULL);
|
||||
register_trace_android_rvh_set_cpus_allowed_ptr_locked(
|
||||
android_rvh_set_cpus_allowed_ptr_locked, NULL);
|
||||
register_trace_android_rvh_set_cpus_allowed_by_task(
|
||||
android_rvh_set_cpus_allowed_by_task, NULL);
|
||||
register_trace_android_rvh_rto_next_cpu(android_rvh_rto_next_cpu, NULL);
|
||||
register_trace_android_rvh_is_cpu_allowed(android_rvh_is_cpu_allowed, NULL);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user