Arnaldo Carvalho de Melo wrote: > Em Sat, Dec 20, 2008 at 12:55:20AM -0500, Steven Rostedt escreveu: > >> We are pleased to announce the 2.6.24.7-rt25 and 2.6.26.8-rt12 trees, >> which can be downloaded from the location: >> >> http://rt.et.redhat.com/download/ >> >> Information on the RT patch can be found at: >> >> http://rt.wiki.kernel.org/index.php/Main_Page >> >> Changes since 2.6.26.6-rt11 >> > > I managed to boot 2.6.26.8-rt12 once, but it oopsed when I started a > market data workload while generating load with a make -j 64 kernel > compile, couldn't get the proper backtrace because I was swamped with > /proc/sys/kernel/hung_task_timeout_secs related messages. Hi Arnaldo, I believe this may have been a result of the patch: sched-prioritize-non-migrating-rt-tasks.patch Please try this patch: ---------------------- commit a8841359ef48279dd3c11f0dca614d7f9da6f7b7 Author: Gregory Haskins <ghaskins@xxxxxxxxxx> Date: Fri Jan 9 17:27:43 2009 -0500 sched: revert "sched-prioritize-non-migrating-rt-tasks.patch" This patch was originally accepted to -rt and later pulled upstream to -tip. However, it was later dropped due to a better alternative solutuion. Therefore, we dropped this patch in 28-rt but inadvertently left it in 26-rt. Now it seems to be causing a crash in 26.8-rt12. However, it is not worth finding/fixing the problem. We should just drop the patch in 26-rt as well. For the convenience of testers out there, please apply this patch to -rt12 to revert the logic. The proper solution for -rt13 is to just remove sched-prioritize-non-migrating-rt-tasks.patch from the series file. Signed-off-by: Gregory Haskins <ghaskins@xxxxxxxxxx> diff --git a/kernel/sched.c b/kernel/sched.c index c56bfde..88c9519 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -203,8 +203,7 @@ static inline int task_has_rt_policy(struct task_struct *p) */ struct rt_prio_array { DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */ - struct list_head xqueue[MAX_RT_PRIO]; /* exclusive queue */ - struct list_head squeue[MAX_RT_PRIO]; /* shared queue */ + struct list_head queue[MAX_RT_PRIO]; }; struct rt_bandwidth { @@ -8360,8 +8359,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) array = &rt_rq->active; for (i = 0; i < MAX_RT_PRIO; i++) { - INIT_LIST_HEAD(array->xqueue + i); - INIT_LIST_HEAD(array->squeue + i); + INIT_LIST_HEAD(array->queue + i); __clear_bit(i, array->bitmap); } /* delimiter for bitsearch: */ diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 4eec7aa..3b92165 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -519,13 +519,7 @@ static void __enqueue_rt_entity(struct sched_rt_entity *rt_se) if (group_rq && (rt_rq_throttled(group_rq) || !group_rq->rt_nr_running)) return; - if (rt_se->nr_cpus_allowed == 1) - list_add_tail(&rt_se->run_list, - array->xqueue + rt_se_prio(rt_se)); - else - list_add_tail(&rt_se->run_list, - array->squeue + rt_se_prio(rt_se)); - + list_add_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se)); __set_bit(rt_se_prio(rt_se), array->bitmap); inc_rt_tasks(rt_se, rt_rq); @@ -537,8 +531,7 @@ static void __dequeue_rt_entity(struct sched_rt_entity *rt_se) struct rt_prio_array *array = &rt_rq->active; list_del_init(&rt_se->run_list); - if (list_empty(array->squeue + rt_se_prio(rt_se)) - && list_empty(array->xqueue + rt_se_prio(rt_se))) + if (list_empty(array->queue + rt_se_prio(rt_se))) __clear_bit(rt_se_prio(rt_se), array->bitmap); dec_rt_tasks(rt_se, rt_rq); @@ -667,21 +660,15 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep) /* * Put task to the end of the run list without the overhead of dequeue * followed by enqueue. - * - * Note: We always enqueue the task to the shared-queue, regardless of its - * previous position w.r.t. exclusive vs shared. This is so that exclusive RR - * tasks fairly round-robin with all tasks on the runqueue, not just other - * exclusive tasks. */ static void requeue_rt_entity(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se) { struct rt_prio_array *array = &rt_rq->active; + struct list_head *queue = array->queue + rt_se_prio(rt_se); - if (on_rt_rq(rt_se)) { - list_del_init(&rt_se->run_list); - list_add_tail(&rt_se->run_list, array->squeue + rt_se_prio(rt_se)); - } + if (on_rt_rq(rt_se)) + list_move_tail(&rt_se->run_list, queue); } static void requeue_task_rt(struct rq *rq, struct task_struct *p) @@ -739,46 +726,13 @@ static int select_task_rq_rt(struct task_struct *p, int sync) } #endif /* CONFIG_SMP */ -static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, - struct rt_rq *rt_rq); - /* * Preempt the current task with a newly woken task if needed: */ static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p) { - if (p->prio < rq->curr->prio) { + if (p->prio < rq->curr->prio) resched_task(rq->curr); - return; - } - -#ifdef CONFIG_SMP - /* - * If: - * - * - the newly woken task is of equal priority to the current task - * - the newly woken task is non-migratable while current is migratable - * - current will be preempted on the next reschedule - * - * we should check to see if current can readily move to a different - * cpu. If so, we will reschedule to allow the push logic to try - * to move current somewhere else, making room for our non-migratable - * task. - */ - if((p->prio == rq->curr->prio) - && p->rt.nr_cpus_allowed == 1 - && rq->curr->rt.nr_cpus_allowed != 1 - && pick_next_rt_entity(rq, &rq->rt) != &rq->curr->rt) { - cpumask_t mask; - - if (cpupri_find(&rq->rd->cpupri, rq->curr, &mask)) - /* - * There appears to be other cpus that can accept - * current, so lets reschedule to try and push it away - */ - resched_task(rq->curr); - } -#endif } static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, @@ -792,15 +746,8 @@ static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, idx = sched_find_first_bit(array->bitmap); BUG_ON(idx >= MAX_RT_PRIO); - queue = array->xqueue + idx; - if (!list_empty(queue)) - next = list_entry(queue->next, struct sched_rt_entity, - run_list); - else { - queue = array->squeue + idx; - next = list_entry(queue->next, struct sched_rt_entity, - run_list); - } + queue = array->queue + idx; + next = list_entry(queue->next, struct sched_rt_entity, run_list); return next; } @@ -889,7 +836,7 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu) continue; if (next && next->prio < idx) continue; - list_for_each_entry(rt_se, array->squeue + idx, run_list) { + list_for_each_entry(rt_se, array->queue + idx, run_list) { struct task_struct *p = rt_task_of(rt_se); if (pick_rt_task(rq, p, cpu)) { next = p; @@ -1331,14 +1278,6 @@ static void set_cpus_allowed_rt(struct task_struct *p, } update_rt_migration(rq); - - if (unlikely(weight == 1 || p->rt.nr_cpus_allowed == 1)) - /* - * If either the new or old weight is a "1", we need - * to requeue to properly move between shared and - * exclusive queues. - */ - requeue_task_rt(rq, p); } p->cpus_allowed = *new_mask;
Attachment:
signature.asc
Description: OpenPGP digital signature