Commit 1fe7493d authored by Zhang Qiao's avatar Zhang Qiao Committed by Wenyu Huang
Browse files

sched: Support kill boost for offline task

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8MF4R


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 avatarZhang Qiao <zhangqiao22@huawei.com>
Signed-off-by: default avatarWenyu Huang <huangwenyu5@huawei.com>
parent 926b9b0c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -855,4 +855,8 @@ static inline void cgroup_bpf_put(struct cgroup *cgrp) {}

#endif /* CONFIG_CGROUP_BPF */

#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
@@ -2458,4 +2458,8 @@ static inline int sched_core_idle_cpu(int cpu) { return idle_cpu(cpu); }

extern void sched_set_stop_task(int cpu, struct task_struct *stop);

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

#endif
+20 −0
Original line number Diff line number Diff line
@@ -2936,6 +2936,26 @@ void cgroup_procs_write_finish(struct task_struct *task, bool threadgroup_locked
			ss->post_attach();
}

#ifdef CONFIG_QOS_SCHED
void cgroup_move_task_to_root(struct task_struct *tsk)
{
	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);
	cpu_cgrp = task_cgroup(tsk, cpu_cgrp_id);
	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
@@ -10384,6 +10384,38 @@ static void sched_change_qos_group(struct task_struct *tsk, struct task_group *t
		__setscheduler_prio(tsk, normal_prio(tsk));
	}
}

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 inline void alloc_uclamp_sched_group(struct task_group *tg,
+3 −0
Original line number Diff line number Diff line
@@ -1060,6 +1060,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);