summaryrefslogtreecommitdiffstats
path: root/src/kernel/deferred.C
diff options
context:
space:
mode:
authorA. Patrick Williams III <iawillia@us.ibm.com>2014-07-14 09:25:45 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-07-14 12:06:38 -0500
commitd980e34032968c9b34b9343ea167c1d3cbe15d17 (patch)
tree7f1f706ef3989dc7e04cd26db5c17c5e6157db45 /src/kernel/deferred.C
parent2c06d0339fa477951f4a65df8bed606de1a2ec5e (diff)
downloadtalos-hostboot-d980e34032968c9b34b9343ea167c1d3cbe15d17.tar.gz
talos-hostboot-d980e34032968c9b34b9343ea167c1d3cbe15d17.zip
Revert "Revert "Resolve deadlock conditions in deferred work queue.""
This reverts commit 2c06d0339fa477951f4a65df8bed606de1a2ec5e. Increase of the winkle timeout to 2 seconds (I92a3511beddb650675101b6f853c219cac14876e) resolves this temporarily. Change-Id: I1f22373bba0cdfb308325c8f0eb52f2b0ed84ee8 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/12200 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/deferred.C')
-rw-r--r--src/kernel/deferred.C27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/kernel/deferred.C b/src/kernel/deferred.C
index ffa16d742..8963226fc 100644
--- a/src/kernel/deferred.C
+++ b/src/kernel/deferred.C
@@ -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. */
@@ -31,10 +33,20 @@
reinterpret_cast<DeferredWork*>((item)->iv_cpus_and_next & 0xFFFFFFFF)
/** Set the DeferredWork pointer part of a iv_cpus_and_next instance var. */
-#define DEFERRED_QUEUE_SET_NEXT_PTR(item) \
- (item)->iv_cpus_and_next = \
- ((item)->iv_cpus_and_next & 0xFFFFFFFF00000000ull) | \
- reinterpret_cast<uint64_t>(item)
+#define DEFERRED_QUEUE_SET_NEXT_PTR(tail,item) \
+ { \
+ uint64_t old_value = 0; \
+ uint64_t new_value = 0; \
+ do \
+ { \
+ old_value = (tail)->iv_cpus_and_next; \
+ new_value = (old_value & 0xFFFFFFFF00000000ull) | \
+ reinterpret_cast<uint64_t>(item); \
+ } \
+ while (!__sync_bool_compare_and_swap(&(tail)->iv_cpus_and_next, \
+ old_value, \
+ new_value)); \
+ }
/** Extract the CPU count portion of a iv_cpus_and_next instance var. */
#define DEFERRED_QUEUE_GET_CPU_COUNT(item) (item)->iv_cpus_and_next >> 32
@@ -79,7 +91,7 @@ void DeferredQueue::_insert(DeferredWork* i_work)
}
// Add work item to the end of the list.
- DEFERRED_QUEUE_SET_NEXT_PTR(i_work);
+ DEFERRED_QUEUE_SET_NEXT_PTR(tail, i_work);
}
lock.unlock();
@@ -125,6 +137,9 @@ void DeferredQueue::_complete(DeferredWork* i_work)
old_ptr = iv_cpus_and_next;
} while(!__sync_bool_compare_and_swap(&iv_cpus_and_next, old_ptr, new_ptr));
+ // Clean up our own queue pointer.
+ DEFERRED_QUEUE_SET_NEXT_PTR(i_work, (DeferredWork*)NULL);
+
// Get the CPU count from the old object pointer and wait until those
// CPUs get into i_work.
old_ptr >>= 32;
OpenPOWER on IntegriCloud