hulk inclusion category: cleanup bugzilla: https://atomgit.com/openeuler/kernel/issues/8423 -------------------------------- Introduce a new scheduler class hook has_running() to the xsched_class interface. This hook allows each scheduling class (e.g., CFS, RT) to determine whether its associated runqueue contains runnable or pending entities that warrant a wake-up or rescheduling event. Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/xsched.h | 3 +++ kernel/xsched/cfs.c | 10 ++++++++-- kernel/xsched/core.c | 15 ++++++++++++++- kernel/xsched/rt.c | 27 +++++++++------------------ 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/include/linux/xsched.h b/include/linux/xsched.h index 86b248a18f97..53c8fa563140 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -429,6 +429,9 @@ struct xsched_class { /* Check context preemption. */ bool (*check_preempt)(struct xsched_entity *xse); + /* Check if runqueue is not empty */ + bool (*has_running)(struct xsched_cu *xcu); + /* Select jobs from XSE to submit on XCU */ size_t (*select_work)(struct xsched_cu *xcu, struct xsched_entity *xse); }; diff --git a/kernel/xsched/cfs.c b/kernel/xsched/cfs.c index 7c2258b32eaf..5db58bbb917f 100644 --- a/kernel/xsched/cfs.c +++ b/kernel/xsched/cfs.c @@ -19,7 +19,7 @@ #define CFS_INNER_RQ_EMPTY(cfs_xse) \ ((cfs_xse)->xruntime == XSCHED_TIME_INF) -void xs_rq_add(struct xsched_entity_cfs *xse) +static void xs_rq_add(struct xsched_entity_cfs *xse) { struct xsched_rq_cfs *cfs_rq = xse->cfs_rq; struct rb_node **link = &cfs_rq->ctx_timeline.rb_root.rb_node; @@ -42,7 +42,7 @@ void xs_rq_add(struct xsched_entity_cfs *xse) rb_insert_color_cached(&xse->run_node, &cfs_rq->ctx_timeline, leftmost); } -void xs_rq_remove(struct xsched_entity_cfs *xse) +static void xs_rq_remove(struct xsched_entity_cfs *xse) { struct xsched_rq_cfs *cfs_rq = xse->cfs_rq; @@ -195,6 +195,11 @@ static void enqueue_ctx_fair(struct xsched_entity *xse, struct xsched_cu *xcu) xcu->xrq.cfs.min_xruntime = (first) ? first->xruntime : XSCHED_TIME_INF; } +static inline bool has_running_fair(struct xsched_cu *xcu) +{ + return !!xcu->xrq.cfs.nr_running; +} + static struct xsched_entity *pick_next_ctx_fair(struct xsched_cu *xcu) { struct xsched_entity_cfs *xse; @@ -256,4 +261,5 @@ struct xsched_class fair_xsched_class = { .pick_next_ctx = pick_next_ctx_fair, .put_prev_ctx = put_prev_ctx_fair, .check_preempt = xs_should_preempt_fair, + .has_running = has_running_fair, }; diff --git a/kernel/xsched/core.c b/kernel/xsched/core.c index 1bf7a93985bb..13de4bec1ba6 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -366,6 +366,19 @@ struct vstream_metadata *xsched_vsm_fetch_first(struct vstream_info *vs) return vsm; } +static bool xcu_has_running(struct xsched_cu *xcu) +{ + bool ret = false; + struct xsched_class *sched; + + mutex_lock(&xcu->xcu_lock); + for_each_xsched_class(sched) + ret |= sched->has_running(xcu); + mutex_unlock(&xcu->xcu_lock); + + return ret; +} + int xsched_schedule(void *input_xcu) { struct xsched_cu *xcu = input_xcu; @@ -375,7 +388,7 @@ int xsched_schedule(void *input_xcu) while (!kthread_should_stop()) { mutex_unlock(&xcu->xcu_lock); wait_event_interruptible(xcu->wq_xcu_idle, - xcu->xrq.rt.nr_running || xcu->xrq.cfs.nr_running || kthread_should_stop()); + xcu_has_running(xcu) || kthread_should_stop()); mutex_lock(&xcu->xcu_lock); if (kthread_should_stop()) { diff --git a/kernel/xsched/rt.c b/kernel/xsched/rt.c index db7d97fed787..d0ab14f07d9a 100644 --- a/kernel/xsched/rt.c +++ b/kernel/xsched/rt.c @@ -43,33 +43,23 @@ static inline void xse_rt_move_tail(struct xsched_entity *xse) list_move_tail(&xse->rt.list_node, &xcu->xrq.rt.rq[xse->rt.prio]); } -/* Increase RT runqueue total and per prio nr_running stat. */ -static inline void xrq_inc_nr_running(struct xsched_entity *xse, - struct xsched_cu *xcu) -{ - xcu->xrq.rt.nr_running++; -} - -/* Decrease RT runqueue total and per prio nr_running stat - * and raise a bug if nr_running decrease beyond zero. - */ -static inline void xrq_dec_nr_running(struct xsched_entity *xse) +static void dequeue_ctx_rt(struct xsched_entity *xse) { struct xsched_cu *xcu = xse->xcu; + xse_rt_del(xse); xcu->xrq.rt.nr_running--; } -static void dequeue_ctx_rt(struct xsched_entity *xse) +static void enqueue_ctx_rt(struct xsched_entity *xse, struct xsched_cu *xcu) { - xse_rt_del(xse); - xrq_dec_nr_running(xse); + xse_rt_add(xse, xcu); + xcu->xrq.rt.nr_running++; } -static void enqueue_ctx_rt(struct xsched_entity *xse, struct xsched_cu *xcu) +static inline bool has_running_rt(struct xsched_cu *xcu) { - xse_rt_add(xse, xcu); - xrq_inc_nr_running(xse, xcu); + return !!xcu->xrq.rt.nr_running; } static inline struct xsched_entity *xrq_next_xse(struct xsched_cu *xcu, @@ -153,7 +143,8 @@ struct xsched_class rt_xsched_class = { .enqueue_ctx = enqueue_ctx_rt, .pick_next_ctx = pick_next_ctx_rt, .put_prev_ctx = put_prev_ctx_rt, - .check_preempt = check_preempt_ctx_rt + .check_preempt = check_preempt_ctx_rt, + .has_running = has_running_rt, }; void xsched_rt_prio_set(pid_t tgid, unsigned int prio) -- 2.34.1