diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2013-04-17 16:53:18 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-04-18 10:34:59 -0500 |
commit | 01b01010e8076b9fa048a370f85c696d8a25ed9f (patch) | |
tree | 6e85035c5344802ed0d5d68b4be39d782154cfc7 /src/kernel | |
parent | bb42935e42d82c247d81ea03c4242ceccc41b487 (diff) | |
download | talos-hostboot-01b01010e8076b9fa048a370f85c696d8a25ed9f.tar.gz talos-hostboot-01b01010e8076b9fa048a370f85c696d8a25ed9f.zip |
Add thread-safety to kernel interrupt handler.
The interrupt handling was originally written with the intent
that only a single thread would receive interrupts. We
purposefully program the Interrupt Presenter hardware to
route all interrupts to a single core.
IPIs (Inter-processor Interrupts) are not routable by the ICP
and end up being delivered to the targeted thread. When we
trigger a winkle-wakeup of a thread, that thread gets the IPI
interrupt. Since we broadcast the IPI to all threads on a core
there is potential for multiple threads to be using the interrupt
object at once. Hence, we added a spinlock to protect it.
Change-Id: I736de774496b13cc9f344d389b9f249bbabeb036
Tested-by: Jenkins Server
Reviewed-by: Dean Sanner <dsanner@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/intmsghandler.C | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C index 0a6e87b0d..8bf68950c 100644 --- a/src/kernel/intmsghandler.C +++ b/src/kernel/intmsghandler.C @@ -99,11 +99,13 @@ void InterruptMsgHdlr::handleInterrupt() if(cv_instance) { + cv_instance->iv_lock.lock(); cv_instance->sendMessage(MSG_INTR_EXTERN, reinterpret_cast<void*>(pir), reinterpret_cast<void*>( static_cast<uint64_t>(xirr)), NULL); + cv_instance->iv_lock.unlock(); } } @@ -140,8 +142,10 @@ void InterruptMsgHdlr::addCpuCore(uint64_t i_pir) // for the message to be an invalid PIR. uint64_t pir_key = i_pir | 0x8000000000000000ul; + cv_instance->iv_lock.lock(); cv_instance->sendMessage(MSG_INTR_ADD_CPU, (void*)pir_key,(void *)i_pir,t); + cv_instance->iv_lock.unlock(); } } |