From fb76acffb06a01facf59d20060703132d4445aa1 Mon Sep 17 00:00:00 2001 From: Sai Harshini Nimmala Date: Mon, 31 Jan 2022 21:59:23 -0800 Subject: [PATCH] sched: walt: properly account for migrating mvp task Currently, every time a task migrates while running, the enqueue resets the slice time accounted thus far, i.e. enqueue resets sum_exec_snapshot. There is a potential for a frequently active migrating task to get infinite slice. Fix this by ensuring total_exec gets updated regardless of SLICE threshold is crossed. Having a non zero total_exec will make enqueue skip taking a snapshot. Also we need to track two snapshots of sum_exec_runtime, one for total and one for slice. The total snapshot will be taken upon task's enqueue after it wakes up from sleep while the slice snapshot advances everytime the SLICE threshold is crossed. This scheme helps us track the total time the task ran since wakeup and the total time it ran in the slice. The snapshot however is the origin for accounting time towards SLICE, hence it should not be updated as long runtime is within SLICE. Once SLICE is crossed, snapshot should be updated for tracking the runtime towards the next SLICE period. Change-Id: I3cf82570c3224b2c9a40b278d2c9baa059216bc3 Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Sai Harshini Nimmala --- include/linux/sched/walt.h | 4 +++- kernel/sched/walt/walt.c | 3 ++- kernel/sched/walt/walt_cfs.c | 27 +++++++++++++++------------ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/linux/sched/walt.h b/include/linux/sched/walt.h index 08777104a28a..87757ac85a4d 100644 --- a/include/linux/sched/walt.h +++ b/include/linux/sched/walt.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _LINUX_SCHED_WALT_H @@ -119,7 +120,8 @@ struct walt_task_struct { int prev_on_rq; int prev_on_rq_cpu; struct list_head mvp_list; - u64 sum_exec_snapshot; + u64 sum_exec_snapshot_for_slice; + u64 sum_exec_snapshot_for_total; u64 total_exec; int mvp_prio; int cidx; diff --git a/kernel/sched/walt/walt.c b/kernel/sched/walt/walt.c index a7a54afe4c80..6d97ac2995df 100644 --- a/kernel/sched/walt/walt.c +++ b/kernel/sched/walt/walt.c @@ -2243,7 +2243,8 @@ static void init_new_task_load(struct task_struct *p) wts->unfilter = sysctl_sched_task_unfilter_period; INIT_LIST_HEAD(&wts->mvp_list); - wts->sum_exec_snapshot = 0; + wts->sum_exec_snapshot_for_slice = 0; + wts->sum_exec_snapshot_for_total = 0; wts->total_exec = 0; wts->mvp_prio = WALT_NOT_MVP; wts->cidx = 0; diff --git a/kernel/sched/walt/walt_cfs.c b/kernel/sched/walt/walt_cfs.c index 224d26bdde61..3bb1bdc4edeb 100644 --- a/kernel/sched/walt/walt_cfs.c +++ b/kernel/sched/walt/walt_cfs.c @@ -1084,7 +1084,7 @@ static void walt_cfs_account_mvp_runtime(struct rq *rq, struct task_struct *curr { struct walt_rq *wrq = (struct walt_rq *) rq->android_vendor_data1; struct walt_task_struct *wts = (struct walt_task_struct *) curr->android_vendor_data1; - s64 delta; + u64 slice; unsigned int limit; lockdep_assert_held(&rq->__lock); @@ -1099,24 +1099,26 @@ static void walt_cfs_account_mvp_runtime(struct rq *rq, struct task_struct *curr if (!(rq->clock_update_flags & RQCF_UPDATED)) update_rq_clock(rq); - /* sum_exec_snapshot can be ahead. See below increment */ - delta = curr->se.sum_exec_runtime - wts->sum_exec_snapshot; - if (delta < 0) - delta = 0; + if (curr->se.sum_exec_runtime > wts->sum_exec_snapshot_for_total) + wts->total_exec = curr->se.sum_exec_runtime - wts->sum_exec_snapshot_for_total; else - delta += rq_clock_task(rq) - curr->se.exec_start; + wts->total_exec = 0; + + if (curr->se.sum_exec_runtime > wts->sum_exec_snapshot_for_slice) + slice = curr->se.sum_exec_runtime - wts->sum_exec_snapshot_for_slice; + else + slice = 0; /* slice is not expired */ - if (delta < WALT_MVP_SLICE) + if (slice < WALT_MVP_SLICE) return; + wts->sum_exec_snapshot_for_slice = curr->se.sum_exec_runtime; /* * slice is expired, check if we have to deactivate the * MVP task, otherwise requeue the task in the list so * that other MVP tasks gets a chance. */ - wts->sum_exec_snapshot += delta; - wts->total_exec += delta; limit = walt_cfs_mvp_task_limit(curr); if (wts->total_exec > limit) { @@ -1165,9 +1167,10 @@ void walt_cfs_enqueue_task(struct rq *rq, struct task_struct *p) * task runtime snapshot. From now onwards we use this point as a * baseline to enforce the slice and demotion. */ - if (!wts->total_exec) /* queue after sleep */ - wts->sum_exec_snapshot = p->se.sum_exec_runtime; - + if (!wts->total_exec) /* queue after sleep */ { + wts->sum_exec_snapshot_for_total = p->se.sum_exec_runtime; + wts->sum_exec_snapshot_for_slice = p->se.sum_exec_runtime; + } } void walt_cfs_dequeue_task(struct rq *rq, struct task_struct *p)