summaryrefslogtreecommitdiffstats
path: root/src/kernel/cpumgr.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-07-31 10:26:12 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-08-10 11:38:42 -0500
commit99f217daf307b3cd963bcbce8eb7b025d58f734e (patch)
tree87a82faba5be946460ff25f222f0f10a03afdfce /src/kernel/cpumgr.C
parentda472c60655393f0bb49113713a8be2bdd2a9b6f (diff)
downloadtalos-hostboot-99f217daf307b3cd963bcbce8eb7b025d58f734e.tar.gz
talos-hostboot-99f217daf307b3cd963bcbce8eb7b025d58f734e.zip
Support for master winkle.
RTC: 44730 Change-Id: Ifaeecc659e1bfd8ded4744dc591fc993471519ba Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1471 Tested-by: Jenkins Server Reviewed-by: Mark W. Wenning <wenning@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/cpumgr.C')
-rw-r--r--src/kernel/cpumgr.C101
1 files changed, 75 insertions, 26 deletions
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 943ef48fd..909661cca 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -38,13 +38,13 @@
#include <kernel/heapmgr.H>
#include <kernel/intmsghandler.H>
#include <errno.h>
+#include <kernel/deferred.H>
+#include <kernel/misc.H>
cpu_t** CpuManager::cv_cpus = NULL;
bool CpuManager::cv_shutdown_requested = false;
uint64_t CpuManager::cv_shutdown_status = 0;
-Barrier CpuManager::cv_barrier;
-bool CpuManager::cv_defrag = false;
-size_t CpuManager::cv_cpuCount = 0;
+size_t CpuManager::cv_cpuSeq = 0;
bool CpuManager::cv_forcedMemPeriodic = false;
InteractiveDebug CpuManager::cv_interactive_debug;
@@ -95,6 +95,35 @@ void CpuManager::requestShutdown(uint64_t i_status)
cv_shutdown_status = i_status;
__sync_synchronize();
cv_shutdown_requested = true;
+
+ class ExecuteShutdown : public DeferredWork
+ {
+ public:
+ void masterPreWork()
+ {
+ // The stats can be retrieved from global variables as needed.
+ // This can be uncommented for debug if desired
+ #ifdef __MEMSTATS__
+ if(c->master)
+ HeapManager::stats();
+ #endif
+ }
+
+ void activeMainWork()
+ {
+ KernelMisc::shutdown();
+ }
+
+ void nonactiveMainWork()
+ {
+ // Something wasn't synchronized correctly if we got to here.
+ // Should not have CPUs coming online while trying to execute
+ // a shutdown.
+ kassert(false);
+ }
+ };
+
+ DeferredQueue::insert(new ExecuteShutdown());
}
void CpuManager::startCPU(ssize_t i)
@@ -163,8 +192,20 @@ void CpuManager::activateCPU(cpu_t * i_cpu)
{
// Set active.
i_cpu->active = true;
- __sync_add_and_fetch(&cv_cpuCount, 1);
- lwsync();
+
+ // Update sequence ID.
+ do
+ {
+ uint64_t old_seq = cv_cpuSeq;
+ i_cpu->cpu_start_seqid = old_seq + 1 + (1ull << 32);
+
+ if (__sync_bool_compare_and_swap(&cv_cpuSeq, old_seq,
+ i_cpu->cpu_start_seqid))
+ {
+ break;
+ }
+ } while (1);
+ i_cpu->cpu_start_seqid >>= 32;
// Verify / set SPRs.
uint64_t msr = getMSR();
@@ -172,6 +213,24 @@ void CpuManager::activateCPU(cpu_t * i_cpu)
setLPCR(WAKEUP_LPCR_VALUE);
}
+void CpuManager::deactivateCPU(cpu_t * i_cpu)
+{
+ // Set inactive.
+ i_cpu->active = false;
+
+ // Update sequence ID.
+ do
+ {
+ uint64_t old_seq = cv_cpuSeq;
+ uint64_t new_seq = old_seq - 1 + (1ull << 32);
+
+ if (__sync_bool_compare_and_swap(&cv_cpuSeq, old_seq, new_seq))
+ {
+ break;
+ }
+ } while(1);
+}
+
void CpuManager::executePeriodics(cpu_t * i_cpu)
{
if(i_cpu->master)
@@ -211,32 +270,22 @@ void CpuManager::executePeriodics(cpu_t * i_cpu)
if((0 == (i_cpu->periodic_count % CPU_PERIODIC_DEFRAG)) ||
(forceMemoryPeriodic))
{
- // set up barrier based on # cpus cv_barrier;
- // TODO whatif other cpus become active?
- isync(); // Ensure all instructions complete before this point, so
- // we don't get a stale shutdown_requested.
- if(!cv_shutdown_requested)
+ class MemoryCoalesce : public DeferredWork
{
- cv_barrier.init(cv_cpuCount);
- lwsync(); // Ensure barrier init is globally visible before
- // setting defrag = true.
- cv_defrag = true;
- }
+ public:
+ void masterPreWork()
+ {
+ HeapManager::coalesce();
+ PageManager::coalesce();
+ }
+ };
+
+ DeferredQueue::insert(new MemoryCoalesce());
}
}
- if(cv_defrag)
- {
- cv_barrier.wait();
- if(i_cpu->master)
- {
- HeapManager::coalesce();
- PageManager::coalesce();
- cv_defrag = false;
- }
+ DeferredQueue::execute();
- cv_barrier.wait();
- }
}
int CpuManager::startCore(uint64_t pir)
OpenPOWER on IntegriCloud