diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/intmsghandler.H | 2 | ||||
-rw-r--r-- | src/kernel/intmsghandler.C | 17 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/include/kernel/intmsghandler.H b/src/include/kernel/intmsghandler.H index 9e5a001ed..2dad00c2b 100644 --- a/src/include/kernel/intmsghandler.H +++ b/src/include/kernel/intmsghandler.H @@ -78,6 +78,7 @@ class InterruptMsgHdlr : public MessageHandler MSG_KEY_THREAD_WKUP = 0x8000000000000000ul, MSG_KEY_ADD_CPU_CORE = 0x4000000000000000ul, MSG_KEY_IPC_MSG = 0x2000000000000000ul, + MSG_IPC_SALT = 0x0000000100000000ul, }; /** @@ -177,6 +178,7 @@ class InterruptMsgHdlr : public MessageHandler static InterruptMsgHdlr * cv_instance; static uint64_t cv_ipc_base_address; + static uint64_t cv_ipc_salt; Spinlock iv_lock; }; diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C index b4b5254a7..805b0d761 100644 --- a/src/kernel/intmsghandler.C +++ b/src/kernel/intmsghandler.C @@ -37,6 +37,7 @@ const char* VFS_ROOT_MSG_INTR = "/msg/interrupt"; InterruptMsgHdlr * InterruptMsgHdlr::cv_instance = NULL; uint64_t InterruptMsgHdlr::cv_ipc_base_address = 0; +uint64_t InterruptMsgHdlr::cv_ipc_salt = 0; void InterruptMsgHdlr::create(MessageQueue * i_msgQ, uint64_t i_ipc_addr) { @@ -193,9 +194,19 @@ void InterruptMsgHdlr::sendIpcMsg(uint64_t i_pir) { if(cv_instance) { - // To avoid conflict with interrupts on thread i_pir, change the key - // for the message to be an invalid PIR. - uint64_t pir_key = i_pir | MSG_KEY_IPC_MSG; + //Note that due to how IPC works between independent HB + //Instances, their is a race between when the data area + //"lock" is released and when the doorbell handled response + //is sent back to the kernel. Basically the other instances + //pounce on the data area as soon as it is unlocked, and + //a duplicate doorbell happens before kernel clears first + //message. + //Since the kernel will drop any message with the same PIR + //key on the floor, need to make it unique with a incrementing + //counter + + cv_ipc_salt += MSG_IPC_SALT; + uint64_t pir_key = i_pir | MSG_KEY_IPC_MSG | cv_ipc_salt; cv_instance->iv_lock.lock(); cv_instance->sendMessage(MSG_INTR_IPC, |