sched/cpupri: Add CPUPRI_HIGHER

Add CPUPRI_HIGHER above the RT99 priority to denote the CPU is in use
by higher priority tasks (specifically deadline).

XXX: we should probably drive PUSH-PULL from cpupri, that would
automagically result in an RT-PUSH when DL sets cpupri to CPUPRI_HIGHER.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
This commit is contained in:
Peter Zijlstra 2020-10-14 21:39:04 +02:00
parent 934fc3314b
commit b13772f813
3 changed files with 14 additions and 4 deletions

View File

@ -11,7 +11,7 @@
* This code tracks the priority of each CPU so that global migration * This code tracks the priority of each CPU so that global migration
* decisions are easy to calculate. Each CPU can be in a state as follows: * decisions are easy to calculate. Each CPU can be in a state as follows:
* *
* (INVALID), NORMAL, RT1, ... RT99 * (INVALID), NORMAL, RT1, ... RT99, HIGHER
* *
* going from the lowest priority to the highest. CPUs in the INVALID state * going from the lowest priority to the highest. CPUs in the INVALID state
* are not eligible for routing. The system maintains this state with * are not eligible for routing. The system maintains this state with
@ -19,7 +19,7 @@
* in that class). Therefore a typical application without affinity * in that class). Therefore a typical application without affinity
* restrictions can find a suitable CPU with O(1) complexity (e.g. two bit * restrictions can find a suitable CPU with O(1) complexity (e.g. two bit
* searches). For tasks with affinity restrictions, the algorithm has a * searches). For tasks with affinity restrictions, the algorithm has a
* worst case complexity of O(min(100, nr_domcpus)), though the scenario that * worst case complexity of O(min(101, nr_domcpus)), though the scenario that
* yields the worst case search is fairly contrived. * yields the worst case search is fairly contrived.
*/ */
#include "sched.h" #include "sched.h"
@ -37,6 +37,8 @@
* 50 49 49 50 * 50 49 49 50
* ... * ...
* 99 0 0 99 * 99 0 0 99
*
* 100 100 (CPUPRI_HIGHER)
*/ */
static int convert_prio(int prio) static int convert_prio(int prio)
{ {
@ -54,6 +56,10 @@ static int convert_prio(int prio)
case MAX_RT_PRIO-1: case MAX_RT_PRIO-1:
cpupri = CPUPRI_NORMAL; /* 0 */ cpupri = CPUPRI_NORMAL; /* 0 */
break; break;
case MAX_RT_PRIO:
cpupri = CPUPRI_HIGHER; /* 100 */
break;
} }
return cpupri; return cpupri;
@ -195,7 +201,7 @@ int cpupri_find_fitness(struct cpupri *cp, struct task_struct *p,
* cpupri_set - update the CPU priority setting * cpupri_set - update the CPU priority setting
* @cp: The cpupri context * @cp: The cpupri context
* @cpu: The target CPU * @cpu: The target CPU
* @newpri: The priority (INVALID-RT99) to assign to this CPU * @newpri: The priority (INVALID,NORMAL,RT1-RT99,HIGHER) to assign to this CPU
* *
* Note: Assumes cpu_rq(cpu)->lock is locked * Note: Assumes cpu_rq(cpu)->lock is locked
* *

View File

@ -1,10 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#define CPUPRI_NR_PRIORITIES MAX_RT_PRIO #define CPUPRI_NR_PRIORITIES (MAX_RT_PRIO+1)
#define CPUPRI_INVALID -1 #define CPUPRI_INVALID -1
#define CPUPRI_NORMAL 0 #define CPUPRI_NORMAL 0
/* values 1-99 are for RT1-RT99 priorities */ /* values 1-99 are for RT1-RT99 priorities */
#define CPUPRI_HIGHER 100
struct cpupri_vec { struct cpupri_vec {
atomic_t count; atomic_t count;

View File

@ -1394,6 +1394,8 @@ static void inc_dl_deadline(struct dl_rq *dl_rq, u64 deadline)
if (dl_rq->earliest_dl.curr == 0 || if (dl_rq->earliest_dl.curr == 0 ||
dl_time_before(deadline, dl_rq->earliest_dl.curr)) { dl_time_before(deadline, dl_rq->earliest_dl.curr)) {
if (dl_rq->earliest_dl.curr == 0)
cpupri_set(&rq->rd->cpupri, rq->cpu, CPUPRI_HIGHER);
dl_rq->earliest_dl.curr = deadline; dl_rq->earliest_dl.curr = deadline;
cpudl_set(&rq->rd->cpudl, rq->cpu, deadline); cpudl_set(&rq->rd->cpudl, rq->cpu, deadline);
} }
@ -1411,6 +1413,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline)
dl_rq->earliest_dl.curr = 0; dl_rq->earliest_dl.curr = 0;
dl_rq->earliest_dl.next = 0; dl_rq->earliest_dl.next = 0;
cpudl_clear(&rq->rd->cpudl, rq->cpu); cpudl_clear(&rq->rd->cpudl, rq->cpu);
cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr);
} else { } else {
struct rb_node *leftmost = dl_rq->root.rb_leftmost; struct rb_node *leftmost = dl_rq->root.rb_leftmost;
struct sched_dl_entity *entry; struct sched_dl_entity *entry;