提交 4bc4fc93 编写于 作者: L Li Hua 提交者: Zheng Zengkai

sched/rt: Try to restart rt period timer when rt runtime exceeded

hulk inclusion
category: bugfix
bugzilla: 185759 https://gitee.com/openeuler/kernel/issues/I4DDEL

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

When rt_runtime is modified from -1 to a valid control value, it may
cause the task to be throttled all the time. Operations like the following
will trigger the bug. E.g:
1. echo -1 > /proc/sys/kernel/sched_rt_runtime_us
2. Run a FIFO task named A that executes while(1)
3. echo 950000 > /proc/sys/kernel/sched_rt_runtime_us

When rt_runtime is -1, The rt period timer will not be activated when task A
enqueued. And then the task will be throttled after setting rt_runtime to
950,000. The task will always be throttled because the rt period timer is not
activated.
Signed-off-by: NLi Hua <hucool.lihua@huawei.com>
Reviewed-by: NChen Hui <judy.chenhui@huawei.com>
Reviewed-by: NCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 3cdb130a
...@@ -944,6 +944,18 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se) ...@@ -944,6 +944,18 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se)
return rt_task_of(rt_se)->prio; return rt_task_of(rt_se)->prio;
} }
static inline void try_start_rt_bandwidth(struct rt_bandwidth *rt_b)
{
raw_spin_lock(&rt_b->rt_runtime_lock);
if (!rt_b->rt_period_active) {
rt_b->rt_period_active = 1;
hrtimer_forward_now(&rt_b->rt_period_timer, rt_b->rt_period);
hrtimer_start_expires(&rt_b->rt_period_timer,
HRTIMER_MODE_ABS_PINNED_HARD);
}
raw_spin_unlock(&rt_b->rt_runtime_lock);
}
static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq) static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
{ {
u64 runtime = sched_rt_runtime(rt_rq); u64 runtime = sched_rt_runtime(rt_rq);
...@@ -1020,13 +1032,17 @@ static void update_curr_rt(struct rq *rq) ...@@ -1020,13 +1032,17 @@ static void update_curr_rt(struct rq *rq)
for_each_sched_rt_entity(rt_se) { for_each_sched_rt_entity(rt_se) {
struct rt_rq *rt_rq = rt_rq_of_se(rt_se); struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
int exceeded;
if (sched_rt_runtime(rt_rq) != RUNTIME_INF) { if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
raw_spin_lock(&rt_rq->rt_runtime_lock); raw_spin_lock(&rt_rq->rt_runtime_lock);
rt_rq->rt_time += delta_exec; rt_rq->rt_time += delta_exec;
if (sched_rt_runtime_exceeded(rt_rq)) exceeded = sched_rt_runtime_exceeded(rt_rq);
if (exceeded)
resched_curr(rq); resched_curr(rq);
raw_spin_unlock(&rt_rq->rt_runtime_lock); raw_spin_unlock(&rt_rq->rt_runtime_lock);
if (exceeded)
try_start_rt_bandwidth(sched_rt_bandwidth(rt_rq));
} }
} }
} }
...@@ -2721,8 +2737,10 @@ static int sched_rt_global_validate(void) ...@@ -2721,8 +2737,10 @@ static int sched_rt_global_validate(void)
static void sched_rt_do_global(void) static void sched_rt_do_global(void)
{ {
raw_spin_lock(&def_rt_bandwidth.rt_runtime_lock);
def_rt_bandwidth.rt_runtime = global_rt_runtime(); def_rt_bandwidth.rt_runtime = global_rt_runtime();
def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period()); def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period());
raw_spin_unlock(&def_rt_bandwidth.rt_runtime_lock);
} }
int sched_rt_handler(struct ctl_table *table, int write, void *buffer, int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册