Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/deadline: Less agressive dl_server handling

Chris reported that commit 5f6bd380c7bd ("sched/rt: Remove default
bandwidth control") caused a significant dip in his favourite
benchmark of the day. Simply disabling dl_server cured things.

His workload hammers the 0->1, 1->0 transitions, and the
dl_server_{start,stop}() overhead kills it -- fairly obviously a bad
idea in hind sight and all that.

Change things around to only disable the dl_server when there has not
been a fair task around for a whole period. Since the default period
is 1 second, this ensures the benchmark never trips this, overhead
gone.

Fixes: 557a6bfc662c ("sched/fair: Add trivial fair server")
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juri Lelli <juri.lelli@redhat.com>
Acked-by: Juri Lelli <juri.lelli@redhat.com>
Link: https://lkml.kernel.org/r/20250702121158.465086194@infradead.org

+23 -12
+1
include/linux/sched.h
··· 698 698 unsigned int dl_defer : 1; 699 699 unsigned int dl_defer_armed : 1; 700 700 unsigned int dl_defer_running : 1; 701 + unsigned int dl_server_idle : 1; 701 702 702 703 /* 703 704 * Bandwidth enforcement timer. Each -deadline task has its
+22 -3
kernel/sched/deadline.c
··· 1150 1150 /* a defer timer will not be reset if the runtime consumed was < dl_server_min_res */ 1151 1151 static const u64 dl_server_min_res = 1 * NSEC_PER_MSEC; 1152 1152 1153 + static bool dl_server_stopped(struct sched_dl_entity *dl_se); 1154 + 1153 1155 static enum hrtimer_restart dl_server_timer(struct hrtimer *timer, struct sched_dl_entity *dl_se) 1154 1156 { 1155 1157 struct rq *rq = rq_of_dl_se(dl_se); ··· 1171 1169 1172 1170 if (!dl_se->server_has_tasks(dl_se)) { 1173 1171 replenish_dl_entity(dl_se); 1172 + dl_server_stopped(dl_se); 1174 1173 return HRTIMER_NORESTART; 1175 1174 } 1176 1175 ··· 1575 1572 void dl_server_update(struct sched_dl_entity *dl_se, s64 delta_exec) 1576 1573 { 1577 1574 /* 0 runtime = fair server disabled */ 1578 - if (dl_se->dl_runtime) 1575 + if (dl_se->dl_runtime) { 1576 + dl_se->dl_server_idle = 0; 1579 1577 update_curr_dl_se(dl_se->rq, dl_se, delta_exec); 1578 + } 1580 1579 } 1581 1580 1582 1581 void dl_server_start(struct sched_dl_entity *dl_se) ··· 1601 1596 setup_new_dl_entity(dl_se); 1602 1597 } 1603 1598 1604 - if (!dl_se->dl_runtime) 1599 + if (!dl_se->dl_runtime || dl_se->dl_server_active) 1605 1600 return; 1606 1601 1607 1602 dl_se->dl_server_active = 1; ··· 1620 1615 dl_se->dl_defer_armed = 0; 1621 1616 dl_se->dl_throttled = 0; 1622 1617 dl_se->dl_server_active = 0; 1618 + } 1619 + 1620 + static bool dl_server_stopped(struct sched_dl_entity *dl_se) 1621 + { 1622 + if (!dl_se->dl_server_active) 1623 + return false; 1624 + 1625 + if (dl_se->dl_server_idle) { 1626 + dl_server_stop(dl_se); 1627 + return true; 1628 + } 1629 + 1630 + dl_se->dl_server_idle = 1; 1631 + return false; 1623 1632 } 1624 1633 1625 1634 void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq, ··· 2373 2354 if (dl_server(dl_se)) { 2374 2355 p = dl_se->server_pick_task(dl_se); 2375 2356 if (!p) { 2376 - if (dl_server_active(dl_se)) { 2357 + if (!dl_server_stopped(dl_se)) { 2377 2358 dl_se->dl_yielded = 1; 2378 2359 update_curr_dl_se(rq, dl_se, 0); 2379 2360 }
-9
kernel/sched/fair.c
··· 5802 5802 struct cfs_bandwidth *cfs_b = tg_cfs_bandwidth(cfs_rq->tg); 5803 5803 struct sched_entity *se; 5804 5804 long queued_delta, runnable_delta, idle_delta, dequeue = 1; 5805 - long rq_h_nr_queued = rq->cfs.h_nr_queued; 5806 5805 5807 5806 raw_spin_lock(&cfs_b->lock); 5808 5807 /* This will start the period timer if necessary */ ··· 5885 5886 5886 5887 /* At this point se is NULL and we are at root level*/ 5887 5888 sub_nr_running(rq, queued_delta); 5888 - 5889 - /* Stop the fair server if throttling resulted in no runnable tasks */ 5890 - if (rq_h_nr_queued && !rq->cfs.h_nr_queued) 5891 - dl_server_stop(&rq->fair_server); 5892 5889 done: 5893 5890 /* 5894 5891 * Note: distribution will already see us throttled via the ··· 6961 6966 static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags) 6962 6967 { 6963 6968 bool was_sched_idle = sched_idle_rq(rq); 6964 - int rq_h_nr_queued = rq->cfs.h_nr_queued; 6965 6969 bool task_sleep = flags & DEQUEUE_SLEEP; 6966 6970 bool task_delayed = flags & DEQUEUE_DELAYED; 6967 6971 struct task_struct *p = NULL; ··· 7043 7049 } 7044 7050 7045 7051 sub_nr_running(rq, h_nr_queued); 7046 - 7047 - if (rq_h_nr_queued && !rq->cfs.h_nr_queued) 7048 - dl_server_stop(&rq->fair_server); 7049 7052 7050 7053 /* balance early to pull high priority tasks */ 7051 7054 if (unlikely(!was_sched_idle && sched_idle_rq(rq)))