summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2014-07-17 14:01:40 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-07-17 16:03:02 -0500
commitcbcc22add05fb4a43faed34edd2b1ffa039dfc23 (patch)
tree74b26fb64fc221d58c66e94da3f090fa9e10e62d
parent89bd6adf7689cbddad15cd9a9e55d4b98b1df183 (diff)
downloadtalos-hostboot-cbcc22add05fb4a43faed34edd2b1ffa039dfc23.tar.gz
talos-hostboot-cbcc22add05fb4a43faed34edd2b1ffa039dfc23.zip
Restrict timebase sync to once per core.
As part of Id3a3bc0b7367e61f2725af17975fe3ba068f69a9, I fixed the deferred work queue to not leak work objects if there are multiple objects. When cores wake up, each thread inserts a work object to synchronize its timebase. Now that they are not leaking, we are running this 8 times, which is causing enough clock drift that we are getting passed the timeout for core wakeups. Modify deferred work queue to allow us to skip performing work if there is already an outstanding deferred work object. This will return us to running the timebase sync just once. Change-Id: Iccffeb9d0578dcd08d41d41ca6af1b82388e7e34 RTC: 111512 Backport: release-fips811 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/12281 Tested-by: Jenkins Server Reviewed-by: Brian Silver <bsilver@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/kernel/deferred.H10
-rw-r--r--src/kernel/cpumgr.C6
-rw-r--r--src/kernel/deferred.C10
-rw-r--r--src/usr/intr/intrrp.H3
4 files changed, 19 insertions, 10 deletions
diff --git a/src/include/kernel/deferred.H b/src/include/kernel/deferred.H
index f80a47bdb..5d22557c3 100644
--- a/src/include/kernel/deferred.H
+++ b/src/include/kernel/deferred.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -149,11 +151,13 @@ class DeferredQueue
/** Insert a work item into the queue.
*
* @param i_work - The item to add.
+ * @param i_onlyIfEmpty - Only insert the object if the queue is
+ * already empty, otherwise delete.
*
* Ownership of the work item is transfered to the queue, which is
* responsible for delete once the work is complete.
*/
- static void insert(DeferredWork* i_work);
+ static void insert(DeferredWork* i_work, bool i_onlyIfEmpty = false);
/** Execute any pending work items. */
static void execute();
@@ -161,7 +165,7 @@ class DeferredQueue
friend class DeferredWork;
// Instance functions for static pair.
- void _insert(DeferredWork* i_work);
+ void _insert(DeferredWork* i_work, bool i_onlyIfEmpty);
void _execute();
/** Remove a completed work item from the queue.
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index ba3b08356..44f61a173 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2010,2014 */
+/* Contributors Listed Below - COPYRIGHT 2010,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -293,7 +295,7 @@ void CpuManager::startSlaveCPU(cpu_t* cpu)
};
SyncTimebase* deferred = new SyncTimebase();
- DeferredQueue::insert(deferred);
+ DeferredQueue::insert(deferred, true /* only if empty */);
DeferredQueue::execute();
}
diff --git a/src/kernel/deferred.C b/src/kernel/deferred.C
index 8963226fc..af8a10189 100644
--- a/src/kernel/deferred.C
+++ b/src/kernel/deferred.C
@@ -60,10 +60,10 @@ DeferredQueue::~DeferredQueue()
kassert(0 == iv_cpus_and_next);
}
-void DeferredQueue::insert(DeferredWork* i_work)
+void DeferredQueue::insert(DeferredWork* i_work, bool i_onlyIfEmpty)
{
// Call singleton insert.
- Singleton<DeferredQueue>::instance()._insert(i_work);
+ Singleton<DeferredQueue>::instance()._insert(i_work, i_onlyIfEmpty);
}
void DeferredQueue::execute()
@@ -72,7 +72,7 @@ void DeferredQueue::execute()
Singleton<DeferredQueue>::instance()._execute();
}
-void DeferredQueue::_insert(DeferredWork* i_work)
+void DeferredQueue::_insert(DeferredWork* i_work, bool i_onlyIfEmpty)
{
lock.lock();
@@ -81,6 +81,10 @@ void DeferredQueue::_insert(DeferredWork* i_work)
{
iv_cpus_and_next = reinterpret_cast<uint64_t>(i_work);
}
+ else if (i_onlyIfEmpty)
+ {
+ delete i_work;
+ }
else
{
// Follow linked list to last work item.
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index 8a7360828..314ae5217 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -301,8 +301,7 @@ namespace INTR
enum
{
- // TODO: RTC 111512; change back to 1s
- CPU_WAKEUP_SECONDS = 2,
+ CPU_WAKEUP_SECONDS = 1,
CPU_WAKEUP_INTERVAL_COUNT = 10,
CPU_WAKEUP_INTERVAL_NS = (NS_PER_SEC * CPU_WAKEUP_SECONDS) /
CPU_WAKEUP_INTERVAL_COUNT,
OpenPOWER on IntegriCloud