index 24621ce..d9ba9d5 100644 (file)
@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);

static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
{
+       struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
struct sched_rt_entity *rt_se = rt_rq->rt_se;

-       if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
-               struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
-
-               enqueue_rt_entity(rt_se);
+       if (rt_rq->rt_nr_running) {
+               if (rt_se && !on_rt_rq(rt_se))
+                       enqueue_rt_entity(rt_se);
if (rt_rq->highest_prio < curr->prio)
}
@@ -199,6 +199,8 @@ static inline struct rt_rq *group_rt_rq(struct sched_rt_entity *rt_se)

static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
{
+       if (rt_rq->rt_nr_running)
}

static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
@@ -229,6 +231,9 @@ static inline struct rt_bandwidth *sched_rt_bandwidth(struct rt_rq *rt_rq)
#endif /* CONFIG_RT_GROUP_SCHED */

#ifdef CONFIG_SMP
+/*
+ * We ran out of runtime, see if we can borrow some from our neighbours.
+ */
static int do_balance_runtime(struct rt_rq *rt_rq)
{
struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
@@ -240,7 +245,7 @@ static int do_balance_runtime(struct rt_rq *rt_rq)

spin_lock(&rt_b->rt_runtime_lock);
rt_period = ktime_to_ns(rt_b->rt_period);
struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i);
s64 diff;

@@ -248,12 +253,21 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
continue;

spin_lock(&iter->rt_runtime_lock);
+               /*
+                * Either all rqs have inf runtime and there's nothing to steal
+                * or __disable_runtime() below sets a specific rq to inf to
+                * indicate its been disabled and disalow stealing.
+                */
if (iter->rt_runtime == RUNTIME_INF)
goto next;

+               /*
+                * From runqueues with spare time, take 1/n part of their
+                * spare time, but no more than our period.
+                */
diff = iter->rt_runtime - iter->rt_time;
if (diff > 0) {
-                       do_div(diff, weight);
+                       diff = div_u64((u64)diff, weight);
if (rt_rq->rt_runtime + diff > rt_period)
diff = rt_period - rt_rq->rt_runtime;
iter->rt_runtime -= diff;
@@ -272,6 +286,9 @@ next:
return more;
}

+/*
+ * Ensure this RQ takes back all the runtime it lend to its neighbours.
+ */
static void __disable_runtime(struct rq *rq)
{
struct root_domain *rd = rq->rd;
@@ -287,18 +304,34 @@ static void __disable_runtime(struct rq *rq)

spin_lock(&rt_b->rt_runtime_lock);
spin_lock(&rt_rq->rt_runtime_lock);
+               /*
+                * Either we're all inf and nobody needs to borrow, or we're
+                * already disabled and thus have nothing to do, or we have
+                * exactly the right amount of runtime to take out.
+                */
if (rt_rq->rt_runtime == RUNTIME_INF ||
rt_rq->rt_runtime == rt_b->rt_runtime)
goto balanced;
spin_unlock(&rt_rq->rt_runtime_lock);

+               /*
+                * Calculate the difference between what we started out with
+                * and what we current have, that's the amount of runtime
+                * we lend and now have to reclaim.
+                */
want = rt_b->rt_runtime - rt_rq->rt_runtime;

+               /*
+                * Greedy reclaim, take back as much as we can.
+                */
struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i);
s64 diff;

-                       if (iter == rt_rq)
+                       /*
+                        * Can't reclaim from ourselves or disabled runqueues.
+                        */
+                       if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF)
continue;

spin_lock(&iter->rt_runtime_lock);
@@ -317,8 +350,16 @@ static void __disable_runtime(struct rq *rq)
}

spin_lock(&rt_rq->rt_runtime_lock);
+               /*
+                * We cannot be left wanting - that would mean some runtime
+                * leaked out of the system.
+                */
BUG_ON(want);
balanced:
+               /*
+                * Disable all the borrow logic by pretending we have inf
+                * runtime - in which case borrowing doesn't make sense.
+                */
rt_rq->rt_runtime = RUNTIME_INF;
spin_unlock(&rt_rq->rt_runtime_lock);
spin_unlock(&rt_b->rt_runtime_lock);
@@ -341,6 +382,9 @@ static void __enable_runtime(struct rq *rq)
if (unlikely(!scheduler_running))
return;

+       /*
+        * Reset each runqueue's bandwidth settings
+        */
for_each_leaf_rt_rq(rt_rq, rq) {
struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);

@@ -348,6 +392,7 @@ static void __enable_runtime(struct rq *rq)
spin_lock(&rt_rq->rt_runtime_lock);
rt_rq->rt_runtime = rt_b->rt_runtime;
rt_rq->rt_time = 0;
+               rt_rq->rt_throttled = 0;
spin_unlock(&rt_rq->rt_runtime_lock);
spin_unlock(&rt_b->rt_runtime_lock);
}
@@ -386,7 +431,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
int i, idle = 1;

-       if (rt_b->rt_runtime == RUNTIME_INF)
+       if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
return 1;

@@ -438,9 +483,6 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
{
u64 runtime = sched_rt_runtime(rt_rq);

-       if (runtime == RUNTIME_INF)
-               return 0;
-
if (rt_rq->rt_throttled)
return rt_rq_throttled(rt_rq);

@@ -484,16 +526,23 @@ static void update_curr_rt(struct rq *rq)
schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));

curr->se.sum_exec_runtime += delta_exec;
+       account_group_exec_runtime(curr, delta_exec);
+
curr->se.exec_start = rq->clock;
cpuacct_charge(curr, delta_exec);

+       if (!rt_bandwidth_enabled())
+               return;
+
for_each_sched_rt_entity(rt_se) {
rt_rq = rt_rq_of_se(rt_se);

spin_lock(&rt_rq->rt_runtime_lock);
-               rt_rq->rt_time += delta_exec;
-               if (sched_rt_runtime_exceeded(rt_rq))
+               if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
+                       rt_rq->rt_time += delta_exec;
+                       if (sched_rt_runtime_exceeded(rt_rq))
+               }
spin_unlock(&rt_rq->rt_runtime_lock);
}
}
@@ -782,7 +831,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
/*
* Preempt the current task with a newly woken task if needed:
*/
-static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p)
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
{
if (p->prio < rq->curr->prio) {
@@ -861,6 +910,8 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
#define RT_MAX_TRIES 3

static int double_lock_balance(struct rq *this_rq, struct rq *busiest);
+static void double_unlock_balance(struct rq *this_rq, struct rq *busiest);
+

@@ -1022,7 +1073,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
break;

/* try again */
-               spin_unlock(&lowest_rq->lock);
+               double_unlock_balance(rq, lowest_rq);
lowest_rq = NULL;
}

@@ -1091,7 +1142,7 @@ static int push_rt_task(struct rq *rq)

-       spin_unlock(&lowest_rq->lock);
+       double_unlock_balance(rq, lowest_rq);

ret = 1;
out:
@@ -1128,7 +1179,7 @@ static int pull_rt_task(struct rq *this_rq)

if (this_cpu == cpu)
continue;

@@ -1197,7 +1248,7 @@ static int pull_rt_task(struct rq *this_rq)

}
skip:
-               spin_unlock(&src_rq->lock);
+               double_unlock_balance(this_rq, src_rq);
}

return ret;
@@ -1409,7 +1460,7 @@ static void watchdog(struct rq *rq, struct task_struct *p)
p->rt.timeout++;
next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ);
if (p->rt.timeout > next)
-                       p->it_sched_expires = p->se.sum_exec_runtime;
+                       p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
}
}

@@ -1453,9 +1504,6 @@ static const struct sched_class rt_sched_class = {
-#ifdef CONFIG_SMP
{"ft_lang_label":"__label__en","ft_lang_prob":0.53505784,"math_prob":0.90230155,"size":6330,"snap":"2019-51-2020-05","text_gpt3_token_len":1797,"char_repetition_ratio":0.18574138,"word_repetition_ratio":0.05050505,"special_character_ratio":0.32906792,"punctuation_ratio":0.19252548,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9534113,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2019-12-14T21:55:14Z\",\"WARC-Record-ID\":\"<urn:uuid:936522ee-4d3d-4429-b00e-0ad81609068a>\",\"Content-Length\":\"48995\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:f294c0fe-ae0e-4c2b-81c9-5aca640707e1>\",\"WARC-Concurrent-To\":\"<urn:uuid:3b305240-13d1-4602-b5b7-df266f74f4c0>\",\"WARC-IP-Address\":\"216.228.121.37\",\"WARC-Target-URI\":\"http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blobdiff;f=kernel/sched_rt.c;h=d9ba9d5f99d6af74b7c1db5ff5814c15900b68b0;hp=24621cea8bb0b5ff2918aaafd01ef87d55bf41a4;hb=03f60840fa462e92220b093f778b2426ceab23af;hpb=d986434a7d32079cc6cbedcdb04d834aa9b323ff\",\"WARC-Payload-Digest\":\"sha1:2ZJA7H3ZRM3U3IMQMFDBNK5YATO7BAL3\",\"WARC-Block-Digest\":\"sha1:MSZICOA6XE3M6V26GMRQXSPYXGYVFHJP\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2019/CC-MAIN-2019-51/CC-MAIN-2019-51_segments_1575541294513.54_warc_CC-MAIN-20191214202754-20191214230754-00210.warc.gz\"}"}