mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
sched/fair: Switch to task based throttle model
In current throttle model, when a cfs_rq is throttled, its entity will be dequeued from cpu's rq, making tasks attached to it not able to run, thus achiveing the throttle target. This has a drawback though: assume a task is a reader of percpu_rwsem and is waiting. When it gets woken, it can not run till its task group's next period comes, which can be a relatively long time. Waiting writer will have to wait longer due to this and it also makes further reader build up and eventually trigger task hung. To improve this situation, change the throttle model to task based, i.e. when a cfs_rq is throttled, record its throttled status but do not remove it from cpu's rq. Instead, for tasks that belong to this cfs_rq, when they get picked, add a task work to them so that when they return to user, they can be dequeued there. In this way, tasks throttled will not hold any kernel resources. And on unthrottle, enqueue back those tasks so they can continue to run. Throttled cfs_rq's PELT clock is handled differently now: previously the cfs_rq's PELT clock is stopped once it entered throttled state but since now tasks(in kernel mode) can continue to run, change the behaviour to stop PELT clock when the throttled cfs_rq has no tasks left. Suggested-by: Chengming Zhou <chengming.zhou@linux.dev> # tag on pick Signed-off-by: Valentin Schneider <vschneid@redhat.com> Signed-off-by: Aaron Lu <ziqianlu@bytedance.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Valentin Schneider <vschneid@redhat.com> Tested-by: Chen Yu <yu.c.chen@intel.com> Tested-by: Matteo Martelli <matteo.martelli@codethink.co.uk> Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> Link: https://lore.kernel.org/r/20250829081120.806-4-ziqianlu@bytedance.com
This commit is contained in:
1 parent
7fc2d14392
commit
e1fad12dcb
3 files changed
+186
-172
No files matched your search
+182
-169
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -162,7 +162,7 @@ static inline void update_idle_cfs_rq_clock_pelt(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
u64 throttled;
|
||||
|
||||
if (unlikely(cfs_rq->throttle_count))
|
||||
if (unlikely(cfs_rq->pelt_clock_throttled))
|
||||
throttled = U64_MAX;
|
||||
else
|
||||
throttled = cfs_rq->throttled_clock_pelt_time;
|
||||
@@ -173,7 +173,7 @@ static inline void update_idle_cfs_rq_clock_pelt(struct cfs_rq *cfs_rq)
|
||||
/* rq->task_clock normalized against any time this cfs_rq has spent throttled */
|
||||
static inline u64 cfs_rq_clock_pelt(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
if (unlikely(cfs_rq->throttle_count))
|
||||
if (unlikely(cfs_rq->pelt_clock_throttled))
|
||||
return cfs_rq->throttled_clock_pelt - cfs_rq->throttled_clock_pelt_time;
|
||||
|
||||
return rq_clock_pelt(rq_of(cfs_rq)) - cfs_rq->throttled_clock_pelt_time;
|
||||
|
||||
@@ -735,7 +735,8 @@ struct cfs_rq {
|
||||
u64 throttled_clock_pelt_time;
|
||||
u64 throttled_clock_self;
|
||||
u64 throttled_clock_self_time;
|
||||
int throttled;
|
||||
bool throttled:1;
|
||||
bool pelt_clock_throttled:1;
|
||||
int throttle_count;
|
||||
struct list_head throttled_list;
|
||||
struct list_head throttled_csd_list;
|
||||
|
||||
Reference in new issue
Block a user