History

sched/deadline: Make DL capacity-aware

The current SCHED_DEADLINE (DL) scheduler uses a global EDF scheduling algorithm w/o considering CPU capacity or task utilization. This works well on homogeneous systems where DL tasks are guaranteed to have a bounded tardiness but presents issues on heterogeneous systems. A DL task can migrate to a CPU which does not have enough CPU capacity to correctly serve the task (e.g. a task w/ 70ms runtime and 100ms period on a CPU w/ 512 capacity). Add the DL fitness function dl_task_fits_capacity() for DL admission control on heterogeneous systems. A task fits onto a CPU if: CPU original capacity / 1024 >= task runtime / task deadline Use this function on heterogeneous systems to try to find a CPU which meets this criterion during task wakeup, push and offline migration. On homogeneous systems the original behavior of the DL admission control should be retained.

Luca Abeni committed 6 years ago

Commit b4118981 parent 60ffd5e3 files · +42 −5Browse files

Unified · Split

3 files
  1. kernel/sched/cpudeadline.c +13 −1
  2. kernel/sched/deadline.c +14 −4
  3. kernel/sched/sched.h +15 −0
kernel/sched/cpudeadline.c+13−1
@@ -121,7 +121,19 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, · 120 unmodified lines
121121
122122 if (later_mask &&
123123 cpumask_and(later_mask, cp->free_cpus, p->cpus_ptr)) {
124− return 1;
124+ int cpu;
125+
126+ if (!static_branch_unlikely(&sched_asym_cpucapacity))
127+ return 1;
128+
129+ /* Ensure the capacity of the CPUs fits the task. */
130+ for_each_cpu(cpu, later_mask) {
131+ if (!dl_task_fits_capacity(p, cpu))
132+ cpumask_clear_cpu(cpu, later_mask);
133+ }
134+
135+ if (!cpumask_empty(later_mask))
136+ return 1;
125137 } else {
126138 int best_cpu = cpudl_maximum(cp);
127139
kernel/sched/deadline.c+14−4
@@ -1643,6 +1643,7 @@ static int · 1642 unmodified lines
16431643 select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)
16441644 {
16451645 struct task_struct *curr;
1646+ bool select_rq;
16461647 struct rq *rq;
16471648
16481649 if (sd_flag != SD_BALANCE_WAKE)
@@ -1662,10 +1663,19 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags) · 13 unmodified lines
16621663 * other hand, if it has a shorter deadline, we
16631664 * try to make it stay here, it might be important.
16641665 */
1665− if (unlikely(dl_task(curr)) &&
1666− (curr->nr_cpus_allowed < 2 ||
1667− !dl_entity_preempt(&p->dl, &curr->dl)) &&
1668− (p->nr_cpus_allowed > 1)) {
1666+ select_rq = unlikely(dl_task(curr)) &&
1667+ (curr->nr_cpus_allowed < 2 ||
1668+ !dl_entity_preempt(&p->dl, &curr->dl)) &&
1669+ p->nr_cpus_allowed > 1;
1670+
1671+ /*
1672+ * Take the capacity of the CPU into account to
1673+ * ensure it fits the requirement of the task.
1674+ */
1675+ if (static_branch_unlikely(&sched_asym_cpucapacity))
1676+ select_rq |= !dl_task_fits_capacity(p, cpu);
1677+
1678+ if (select_rq) {
16691679 int target = find_later_rq(p);
16701680
16711681 if (target != -1 &&
kernel/sched/sched.h+15−0
@@ -317,6 +317,21 @@ static inline bool __dl_overflow(struct dl_bw *dl_b, unsigned long cap, · 316 unmodified lines
317317 cap_scale(dl_b->bw, cap) < dl_b->total_bw - old_bw + new_bw;
318318 }
319319
320+/*
321+ * Verify the fitness of task @p to run on @cpu taking into account the
322+ * CPU original capacity and the runtime/deadline ratio of the task.
323+ *
324+ * The function will return true if the CPU original capacity of the
325+ * @cpu scaled by SCHED_CAPACITY_SCALE >= runtime/deadline ratio of the
326+ * task and false otherwise.
327+ */
328+static inline bool dl_task_fits_capacity(struct task_struct *p, int cpu)
329+{
330+ unsigned long cap = arch_scale_cpu_capacity(cpu);
331+
332+ return cap_scale(p->dl.dl_deadline, cap) >= p->dl.dl_runtime;
333+}
334+
320335 extern void init_dl_bw(struct dl_bw *dl_b);
321336 extern int sched_dl_global_validate(void);
322337 extern void sched_dl_do_global(void);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t