sli: fix rq_clock warning caused by sli

In order to reduce the critical section, we invoke sli_update_tick()
to do sli statistics after release the rq lock. But there is a race
condition that could led the rq_clock warning.

Warning generates like following:
CPU0				CPU1
rq_lock()
update_rq_clock()
rq_unlock()
				rq_lock()
sli_update_tick()		load balance

Although, CPU0 had updated the rq_clock(). But CPU1 may concurrently
do the load balance and acquire CPU0's rq lock, and the CPU0's
clock_update_flags would be cleared. It means that caller should
update the rq clock before actually use it. Unfortunately, CPU0
cann't observed it. So the warning was produced by sli when it
invoke rq_clock().

Therefore, we must move the sli_check_longsys() in the front of
rq_unlock().

Signed-off-by: Bin Lai <robinlai@tencent.com>
This commit is contained in:
Bin Lai 2022-07-02 18:48:25 +08:00
parent 4a520fdf3a
commit 92e026f5b5
3 changed files with 10 additions and 9 deletions

View File

@ -132,6 +132,7 @@ int sli_schedlat_max_show(struct seq_file *m, struct cgroup *cgrp);
ssize_t cgroup_sli_control_write(struct kernfs_open_file *of, char *buf,
size_t nbytes, loff_t off);
int cgroup_sli_control_show(struct seq_file *sf, void *v);
void sli_check_longsys(struct task_struct *tsk);
void sli_update_tick(struct task_struct *tsk);
struct sli_notify_ctx* sctx_alloc(void);

View File

@ -531,11 +531,13 @@ out:
rcu_read_unlock();
}
#ifdef CONFIG_SCHED_INFO
void sli_check_longsys(struct task_struct *tsk)
{
long delta;
if (!static_branch_likely(&sli_enabled))
return;
if (tsk->sched_class != &fair_sched_class)
return ;
@ -559,7 +561,6 @@ void sli_check_longsys(struct task_struct *tsk)
delta = rq_clock(task_rq(tsk)) - tsk->sched_info.kernel_exec_start;
sli_schedlat_stat(tsk, SCHEDLAT_LONGSYS, delta);
}
#endif
static void sli_proactive_monitor_work(struct work_struct *work)
{
@ -642,13 +643,6 @@ void sli_update_tick(struct task_struct *tsk)
{
struct cgroup *cgrp;
if (!static_branch_likely(&sli_enabled))
return;
#ifdef CONFIG_SCHED_INFO
sli_check_longsys(tsk);
#endif
if (!static_branch_likely(&sli_monitor_enabled))
return;

View File

@ -3697,6 +3697,9 @@ void scheduler_tick(void)
calc_global_load_tick(rq);
psi_task_tick(rq);
#ifdef CONFIG_CGROUP_SLI
sli_check_longsys(curr);
#endif
rq_unlock(rq, &rf);
perf_event_task_tick();
@ -3786,6 +3789,9 @@ static void sched_tick_remote(struct work_struct *work)
curr->sched_class->task_tick(rq, curr, 0);
calc_load_nohz_remote(rq);
#ifdef CONFIG_CGROUP_SLI
sli_check_longsys(curr);
#endif
out_unlock:
rq_unlock_irq(rq, &rf);
out_requeue: