summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-01-03 11:10:42 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-01-05 00:57:01 -0600
commit048789fdce6b406de3b7149f8171afd63eea1829 (patch)
tree2291287f0fd3cb05441a96e72346e27436ebbba1 /src
parenta001b92d6d5ab2383a7c8c51f1ee43f8095d1d56 (diff)
downloadtalos-hostboot-048789fdce6b406de3b7149f8171afd63eea1829.tar.gz
talos-hostboot-048789fdce6b406de3b7149f8171afd63eea1829.zip
Fix race condition between stackmanager and vmmmanager.
Change-Id: Ie3f3fb2050428af1fc398b1577dfc090cd7d26cf Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/591 Tested-by: Jenkins Server Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com> Reviewed-by: Melissa J. Connell <missyc@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: MATTHEW S. BARTH <msbarth@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/stacksegment.H2
-rw-r--r--src/include/kernel/taskmgr.H3
-rw-r--r--src/include/kernel/vmmmgr.H1
-rw-r--r--src/kernel/msghandler.C13
-rw-r--r--src/kernel/stacksegment.C4
5 files changed, 22 insertions, 1 deletions
diff --git a/src/include/kernel/stacksegment.H b/src/include/kernel/stacksegment.H
index 2d3474dc6..460a61b49 100644
--- a/src/include/kernel/stacksegment.H
+++ b/src/include/kernel/stacksegment.H
@@ -108,6 +108,8 @@ class StackSegment : public Segment
* @brief Delete previously created stack for a task.
*
* @param i_task - Task ID of task owning the stack.
+ *
+ * @note This function obtains the VMM-subsystem spinlock.
*/
static void deleteStack(tid_t i_task);
diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H
index 63aa76484..b38618d22 100644
--- a/src/include/kernel/taskmgr.H
+++ b/src/include/kernel/taskmgr.H
@@ -125,6 +125,9 @@ class TaskManager
* @param[in] t - The task to end.
* @param[in] retval - Return value from the task.
* @param[in] status - TASK_STATUS_* enumeration of how the task ended.
+ *
+ * @note This function obtains the VMM-subsystem spinlock as part of
+ * releasing the task stack.
*/
static void endTask(task_t* t, void* retval, int status);
diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H
index 845066229..3782bb762 100644
--- a/src/include/kernel/vmmmgr.H
+++ b/src/include/kernel/vmmmgr.H
@@ -200,6 +200,7 @@ class VmmManager
public:
friend class Block;
+ friend class StackSegment;
};
diff --git a/src/kernel/msghandler.C b/src/kernel/msghandler.C
index 82dab7f8f..08859633a 100644
--- a/src/kernel/msghandler.C
+++ b/src/kernel/msghandler.C
@@ -22,6 +22,7 @@
// IBM_PROLOG_END
#include <assert.h>
#include <errno.h>
+#include <util/locked/queue.H>
#include <kernel/msghandler.H>
#include <kernel/task.H>
#include <kernel/cpu.H>
@@ -96,6 +97,11 @@ int MessageHandler::recvMessage(msg_t* i_msg)
// Lock subsystem spinlock.
if (iv_lock) iv_lock->lock();
+ // List of tasks to end due to errors.
+ // Ending the task must happen outside of the spinlock due to
+ // requirements of TaskManager::endTask.
+ Util::Locked::Queue<task_t> endTaskList;
+
// Get <key, rc> from response.
MessageHandler_Pending::key_type key =
reinterpret_cast<MessageHandler_Pending::key_type>(i_msg->data[0]);
@@ -141,7 +147,7 @@ int MessageHandler::recvMessage(msg_t* i_msg)
// Unsuccessful, unhandled response. Kill task.
printk("Unhandled msg rc %d for key %p on task %d @ %p\n",
msg_rc, key, deferred_task->tid, deferred_task->context.nip);
- TaskManager::endTask(deferred_task, NULL, TASK_STATUS_CRASHED);
+ endTaskList.insert(deferred_task);
}
else if (CONTINUE_DEFER == rc)
{
@@ -157,6 +163,11 @@ int MessageHandler::recvMessage(msg_t* i_msg)
// Finished handling the response, unlock subsystem.
if (iv_lock) iv_lock->unlock();
+ while(task_t* end_task = endTaskList.remove())
+ {
+ TaskManager::endTask(end_task, NULL, TASK_STATUS_CRASHED);
+ }
+
// Release memory for message (created from sendMsg).
delete(i_msg);
diff --git a/src/kernel/stacksegment.C b/src/kernel/stacksegment.C
index 0ea3e24a8..f7ced0f1f 100644
--- a/src/kernel/stacksegment.C
+++ b/src/kernel/stacksegment.C
@@ -149,6 +149,8 @@ void* StackSegment::_createStack(tid_t i_task)
void StackSegment::_deleteStack(tid_t i_task)
{
+ VmmManager::getLock()->lock();
+
uint64_t l_addr_8mb = i_task * (8*MEGABYTE) + VMM_VADDR_STACK_SEGMENT;
StackBlockNode* l_node = iv_blockList.find(l_addr_8mb);
@@ -159,5 +161,7 @@ void StackSegment::_deleteStack(tid_t i_task)
delete l_node->block;
delete l_node;
+ VmmManager::getLock()->unlock();
+
return;
}
OpenPOWER on IntegriCloud