hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IDB5TR ----------------------------------------- A previous change (6861f0e578d7) updated the CFS group vruntime using sum_exec_runtime to fix shares misaccounting with multiple tasks. As a result, __raw_pick_next_ctx() may keep returning NULL and xsched_schedule() enters a busy infinite loop and cause softlockup finally. Fix this by restoring the group vruntime derivation from the first runnable entity's xruntime, while keeping the divide-by-zero protection introduced by 0d9ab2cf79b1. This effectively adapts the original behavior without a direct revert, and prevents the scheduler from spinning. Fixes: 6861f0e578d7 ("xsched: fix shares misaccounting when multiple tasks run in one cgroup") Signed-off-by: Zicheng Qu <quzicheng@huawei.com> --- include/linux/xsched.h | 2 +- kernel/xsched/cfs.c | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/linux/xsched.h b/include/linux/xsched.h index 150bcdb601df..d21393ac82d6 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -40,7 +40,7 @@ #define RUNTIME_INF ((u64)~0ULL) #define XSCHED_TIME_INF RUNTIME_INF -#define XSCHED_CFS_WEIGHT_DFLT 1 +#define XSCHED_CFS_WEIGHT_DFLT 1024 #define XSCHED_CFS_QUOTA_PERIOD_MS (100 * NSEC_PER_MSEC) #define XSCHED_CFG_SHARE_DFLT 1024 diff --git a/kernel/xsched/cfs.c b/kernel/xsched/cfs.c index d2615939292f..2c8319f7f18d 100644 --- a/kernel/xsched/cfs.c +++ b/kernel/xsched/cfs.c @@ -62,7 +62,6 @@ static void xs_cfs_rq_update(struct xsched_entity_cfs *xse_cfs, u64 new_xrt) static inline struct xsched_entity_cfs * xs_pick_first(struct xsched_rq_cfs *cfs_rq) { - struct xsched_entity_cfs *xse_cfs; struct rb_node *left; if (!cfs_rq) { @@ -75,8 +74,7 @@ xs_pick_first(struct xsched_rq_cfs *cfs_rq) if (!left) return NULL; - xse_cfs = rb_entry(left, struct xsched_entity_cfs, run_node); - return xse_cfs; + return rb_entry(left, struct xsched_entity_cfs, run_node); } /** @@ -114,11 +112,8 @@ static void xg_update(struct xsched_group_xcu_priv *xg, int task_delta) for (; xg; xg = &xcg_parent_grp_xcu(xg)) { xg->cfs_rq->nr_running += task_delta; entry = xs_pick_first(xg->cfs_rq); - if (entry) - new_xrt = xs_calc_delta_fair(xg->xse.cfs.sum_exec_runtime, - xg->xse.cfs.weight); - else - new_xrt = XSCHED_TIME_INF; + new_xrt = entry ? xs_calc_delta_fair(entry->xruntime, xg->xse.cfs.weight) + : XSCHED_TIME_INF; xg->cfs_rq->min_xruntime = new_xrt; xg->xse.cfs.xruntime = new_xrt; @@ -209,10 +204,13 @@ static struct xsched_entity *pick_next_ctx_fair(struct xsched_cu *xcu) if (!xse) return NULL; - for (; XSCHED_SE_OF(xse)->is_group; xse = xs_pick_first(rq)) { - if (!xse || CFS_INNER_RQ_EMPTY(xse)) - return NULL; + for (; xse && XSCHED_SE_OF(xse)->is_group; xse = xs_pick_first(rq)) rq = xse_this_grp_xcu(xse)->cfs_rq; + + if (!xse) { + XSCHED_DEBUG("the xse this xcu [%d] is trying to pick is NULL @ %s\n", + xcu->id, __func__); + return NULL; } return container_of(xse, struct xsched_entity, cfs); -- 2.34.1