Commit f60bf584 authored by Zheng Zucheng's avatar Zheng Zucheng Committed by Yang Yingliang
Browse files

sched: Fix offline task can't be killed in a timely

hulk inclusion
category: bugfix
bugzilla: 51828, https://gitee.com/openeuler/kernel/issues/I4K96G


CVE: NA

--------------------------------

If online tasks occupy 100% CPU resources, offline tasks can't be scheduled
since offline tasks are throttled, as a result, offline task can't timely
respond after receiving SIGKILL signal.

Signed-off-by: default avatarZheng Zucheng <zhengzucheng@huawei.com>
Reviewed-by: default avatarXiu Jianfeng <xiujianfeng@huawei.com>
Reviewed-by: default avatarChen Hui <judy.chenhui@huawei.com>
Reviewed-by: default avatarXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 8ca949bd
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -886,4 +886,8 @@ static inline void put_cgroup_ns(struct cgroup_namespace *ns)
		free_cgroup_ns(ns);
}

#ifdef CONFIG_QOS_SCHED
void cgroup_move_task_to_root(struct task_struct *tsk);
#endif

#endif /* _LINUX_CGROUP_H */
+4 −0
Original line number Diff line number Diff line
@@ -1951,4 +1951,8 @@ static inline void rseq_syscall(struct pt_regs *regs)

#endif

#ifdef CONFIG_QOS_SCHED
void sched_move_offline_task(struct task_struct *p);
#endif

#endif
+22 −0
Original line number Diff line number Diff line
@@ -2719,6 +2719,28 @@ void cgroup_procs_write_finish(struct task_struct *task)
			ss->post_attach();
}

#ifdef CONFIG_QOS_SCHED
void cgroup_move_task_to_root(struct task_struct *tsk)
{
	struct css_set *css;
	struct cgroup *cpu_cgrp;
	struct cgroup *cpu_root_cgrp;

	mutex_lock(&cgroup_mutex);
	percpu_down_write(&cgroup_threadgroup_rwsem);

	spin_lock_irq(&css_set_lock);
	css = task_css_set(tsk);
	cpu_cgrp = css->subsys[cpu_cgrp_id]->cgroup;
	cpu_root_cgrp = &cpu_cgrp->root->cgrp;
	spin_unlock_irq(&css_set_lock);

	(void)cgroup_attach_task(cpu_root_cgrp, tsk, false);
	percpu_up_write(&cgroup_threadgroup_rwsem);
	mutex_unlock(&cgroup_mutex);
}
#endif

static void cgroup_print_ss_mask(struct seq_file *seq, u16 ss_mask)
{
	struct cgroup_subsys *ss;
+32 −0
Original line number Diff line number Diff line
@@ -6357,6 +6357,38 @@ static int alloc_qos_sched_group(struct task_group *tg, struct task_group *paren

	return 1;
}

struct offline_args {
	struct work_struct work;
	struct task_struct *p;
};

static void sched_move_work(struct work_struct *work)
{
	struct sched_param param = { .sched_priority = 0 };
	struct offline_args *args = container_of(work, struct offline_args, work);

	cgroup_move_task_to_root(args->p);
	sched_setscheduler(args->p, SCHED_NORMAL, &param);
	put_task_struct(args->p);
	kfree(args);
}

void sched_move_offline_task(struct task_struct *p)
{
	struct offline_args *args;

	if (unlikely(task_group(p)->qos_level != -1))
		return;

	args = kmalloc(sizeof(struct offline_args), GFP_ATOMIC);
	if (args) {
		get_task_struct(p);
		args->p = p;
		INIT_WORK(&args->work, sched_move_work);
		queue_work(system_highpri_wq, &args->work);
	}
}
#endif

static void sched_free_group(struct task_group *tg)
+3 −0
Original line number Diff line number Diff line
@@ -1040,6 +1040,9 @@ static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
			signal->group_stop_count = 0;
			t = p;
			do {
#ifdef CONFIG_QOS_SCHED
				sched_move_offline_task(t);
#endif
				task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
				sigaddset(&t->pending.signal, SIGKILL);
				signal_wake_up(t, 1);