hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9206 ---------------------------------------- A race condition exists when switching the scheduling class of an xcu group while tasks are being enqueued. The issue occurs due to the following interleaving: mkdir -p group -> create an xcu group echo cfs > group/xcu.sched_class echo pid > group/cgroup.procs -> xcu_sched_class_write -> mutex_lock(&xcg_mutex); -> xcu_cg_set_sched_class -> xcg_perxcu_cfs_rq_deinit -> mutex_lock(&xcu->xcu_lock); -> cfs_rq = NULL -> mutex_unlock(&xcu->xcu_lock); -> vstream_kick -> mutex_lock(&xcu->xcu_lock); -> enqueue_ctx -> NULL pointer dereference -> mutex_unlock(&xcu->xcu_lock); -> xcu_cfs_cg_init -> alloc cfs_rq -> mutex_unlock(&xcg_mutex); To prevent this, add a sanity check in xse_integrity_check() to ensure that the cfs_rq associated with the xse is valid when the scheduling class is CFS. This returns -EINVAL early if the cfs_rq is temporarily NULL during the transition, avoiding the kernel crash. Fixes: 43bbefc53356 ("xsched: Add XCU control group implementation and its backend in xsched CFS") Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/xsched.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/xsched.h b/include/linux/xsched.h index c3617386cb8d..fde7b3c8ee7d 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -65,7 +65,6 @@ extern struct list_head xsched_class_list; #define for_each_vstream_in_ctx(vs, ctx) \ list_for_each_entry((vs), &((ctx)->vstream_list), ctx_node) - /* Manages xsched RT-like class linked list based runqueue. * * Now RT-like class runqueue structs is identical @@ -354,6 +353,12 @@ static inline int xse_integrity_check(struct xsched_entity *xse) return -EINVAL; } +#ifdef CONFIG_XCU_SCHED_CFS + /* The cfs_rq of xse may be NULL in some scenarios */ + if (xse->class == &fair_xsched_class && !xsched_cfs_rq_of(xse)) + return -EINVAL; +#endif + #ifdef CONFIG_CGROUP_XCU if (xse->is_group && !xse_this_cfs_rq(xse)) { // Can only be in the free process -- 2.34.1