From d4308d3d2e2c4b51b83ffd59436cd51c7afb226c Mon Sep 17 00:00:00 2001 From: Jan Stoess Date: Fri, 18 Jun 2010 16:17:18 +0200 Subject: [PATCH] Fix migration when hierarchical scheduling is enabled --- kernel/src/api/v4/sched-hs/schedule.cc | 22 ++++++++++++++-------- kernel/src/api/v4/sched-hs/schedule.h | 10 +++++++--- kernel/src/api/v4/schedule.cc | 2 +- kernel/src/api/v4/schedule.h | 1 + kernel/src/api/v4/thread.h | 7 +++++-- kernel/src/glue/v4-powerpc/init.cc | 5 +++++ 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/kernel/src/api/v4/sched-hs/schedule.cc b/kernel/src/api/v4/sched-hs/schedule.cc index 05e81e71..018d41d9 100644 --- a/kernel/src/api/v4/sched-hs/schedule.cc +++ b/kernel/src/api/v4/sched-hs/schedule.cc @@ -1,6 +1,6 @@ /********************************************************************* * - * Copyright (C) 2007-2009, Karlsruhe University + * Copyright (C) 2007-2010, Karlsruhe University * * File path: api/v4/sched-hs/schedule.cc * Description: @@ -93,7 +93,7 @@ prio_queue_t * prio_queue_t::add_prio_domain(schedule_ctrl_t prio_control) ASSERT(domain_tcb->sched_state.flags.is_set(sched_ktcb_t::is_schedule_domain)); domain_tcb->sched_state.set_prio_queue(this); - if( cpu != get_current_cpu() ) + if( cpu != get_current_cpu() ) domain_tcb->migrate_to_processor(cpu); TRACEPOINT (SCHEDULE_PRIO_DOMAIN, "new prio domain tcb %t, cpu %d, prio %d, stride %d\n", @@ -107,8 +107,9 @@ prio_queue_t *prio_queue_t::domain_partner( cpuid_t cpu ) { ASSERT(domain_tcb); - if( domain_tcb->is_local_cpu() ) + if( domain_tcb->get_cpu() == cpu ) return this; + #if defined(CONFIG_SMP) prio_queue_t *partner_queue = cpu_head; @@ -577,6 +578,7 @@ static void xcpu_integrate_thread(tcb_t * tcb) scheduler_t *scheduler = get_current_scheduler(); sched_ktcb_t *sched_state = &tcb->sched_state; + /* VU: the thread may have received an IPC meanwhile hence we * check whether the thread is already running again. to make it * fully working the waiting timeout must be set more carefull! */ @@ -608,19 +610,23 @@ void scheduler_t::move_tcb(tcb_t *tcb, cpuid_t cpu) tcb->set_cpu(cpu); unlock_requeue(); - + + prio_queue_t *new_prio_queue = tcb->sched_state.get_prio_queue()->domain_partner(cpu); + tcb->sched_state.set_pass(0); // Force tcb to use the pass of the target domain. + tcb->sched_state.set_prio_queue(new_prio_queue); + + if (need_xcpu) { tcb->sched_state.requeue_callback = xcpu_integrate_thread; remote_schedule(tcb); } - prio_queue_t *new_prio_queue = tcb->sched_state.get_prio_queue()->domain_partner(cpu); - tcb->sched_state.set_pass(0); // Force tcb to use the pass of the target domain. - tcb->sched_state.set_prio_queue(new_prio_queue); - tcb->unlock(); + TRACE_SCHEDULE_DETAILS("move_tcb: %t (s=%s) cpu %d pq %p dtcb %t", tcb, + tcb->get_state().string(), cpu, new_prio_queue, + new_prio_queue->get_domain_tcb()); } diff --git a/kernel/src/api/v4/sched-hs/schedule.h b/kernel/src/api/v4/sched-hs/schedule.h index 6512c610..1359e1d8 100644 --- a/kernel/src/api/v4/sched-hs/schedule.h +++ b/kernel/src/api/v4/sched-hs/schedule.h @@ -246,7 +246,7 @@ public: tcb->sched_state.requeue = NULL; TRACE_SCHEDULE_DETAILS("smp_requeue:dequeue_head %t (s=%s) cpu %d (head %t)", - tcb, tcb->get_state().string(), tcb->get_cpu(), tcb_list); + tcb, tcb->get_state().string(), tcb->get_cpu(), tcb_list); return (tcb_t *) tcb; @@ -287,10 +287,14 @@ public: } void enqueue_ready(tcb_t * tcb, bool head = false) { - while (tcb != get_idle_tcb()) + while (tcb->get_global_id() != IDLETHREAD ) { ASSERT(tcb); ASSERT(tcb->sched_state.get_prio_queue()); + TRACE_SCHEDULE_DETAILS("enqueue_ready %t () pq %t dtcb %t idle %p\n", tcb, + tcb->sched_state.get_prio_queue(), tcb->sched_state.get_prio_queue()->get_domain_tcb(), + get_idle_tcb()); + tcb->sched_state.get_prio_queue()->enqueue(tcb, head); tcb = tcb->sched_state.get_prio_queue()->get_domain_tcb(); } @@ -299,7 +303,7 @@ public: void dequeue_ready(tcb_t * tcb) { ASSERT(tcb); - while (tcb != get_idle_tcb()) + while (tcb->get_global_id() != IDLETHREAD ) { ASSERT(tcb); ASSERT(tcb->sched_state.get_prio_queue()); diff --git a/kernel/src/api/v4/schedule.cc b/kernel/src/api/v4/schedule.cc index 74e2feb2..17768374 100644 --- a/kernel/src/api/v4/schedule.cc +++ b/kernel/src/api/v4/schedule.cc @@ -389,7 +389,7 @@ void SECTION(".init") scheduler_t::init( bool bootcpu ) /* set idle-magic */ get_idle_tcb()->create_kernel_thread(NILTHREAD, &__idle_utcb, sktcb_lo); get_idle_tcb()->set_space(get_kernel_space()); - get_idle_tcb()->myself_global.set_raw((word_t)0x1d1e1d1e1d1e1d1eULL); + get_idle_tcb()->myself_global.set(IDLETHREAD); get_idle_tcb()->create_startup_stack(idle_thread); if( bootcpu ) diff --git a/kernel/src/api/v4/schedule.h b/kernel/src/api/v4/schedule.h index d1e5a31e..4573552d 100644 --- a/kernel/src/api/v4/schedule.h +++ b/kernel/src/api/v4/schedule.h @@ -319,6 +319,7 @@ private: void commit_schedule_parameters(schedule_req_t &req); static schedule_request_queue_t schedule_request_queue[CONFIG_SMP_MAX_CPUS]; + static const word_t idle_tid = (word_t)0x1d1e1d1e1d1e1d1eULL; }; diff --git a/kernel/src/api/v4/thread.h b/kernel/src/api/v4/thread.h index 247f5aca..4438d030 100644 --- a/kernel/src/api/v4/thread.h +++ b/kernel/src/api/v4/thread.h @@ -1,6 +1,6 @@ /********************************************************************* * - * Copyright (C) 2002-2008, Karlsruhe University + * Copyright (C) 2002-2008, 2010, Karlsruhe University * * File path: api/v4/thread.h * Description: thread ids @@ -78,7 +78,7 @@ public: static const threadid_t idlethread() { threadid_t tid; - tid.raw = 0x1d1e1d1e; + tid.raw = (word_t)0x1d1e1d1e1d1e1d1eULL; return tid; } @@ -107,6 +107,7 @@ public: word_t get_raw() { return this->raw; } void set_raw(word_t raw) { this->raw = raw; } + void set(threadid_t tid) { this->raw = tid.raw; } /* operators */ bool operator == (const threadid_t & tid) @@ -119,6 +120,7 @@ public: return this->raw != tid.raw; } + private: union { word_t raw; @@ -154,6 +156,7 @@ INLINE threadid_t threadid(word_t rawid) #define NILTHREAD (threadid_t::nilthread()) #define ANYTHREAD (threadid_t::anythread()) #define ANYLOCALTHREAD (threadid_t::anylocalthread()) +#define IDLETHREAD (threadid_t::idlethread()) #endif /* !__API__V4__THREAD_H__ */ diff --git a/kernel/src/glue/v4-powerpc/init.cc b/kernel/src/glue/v4-powerpc/init.cc index 0349d105..5b81e9ad 100644 --- a/kernel/src/glue/v4-powerpc/init.cc +++ b/kernel/src/glue/v4-powerpc/init.cc @@ -663,9 +663,14 @@ static SECTION(".init") void install_exception_handlers( cpuid_t cpu ) * The kernel's C entry point. * ****************************************************************************/ + +#include extern "C" SECTION(".init") void l4_powerpc_init( word_t r3, word_t r4, word_t r5 ) { + MAGIC_BREAKPOINT; + init_console(); + MAGIC_BREAKPOINT; #if defined(CONFIG_KDB_CONS_OF1275) init_of1275_console( r5 ); // XXX: use standard init routine! #endif