diff options
author | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-07-14 09:25:45 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-07-14 12:06:38 -0500 |
commit | d980e34032968c9b34b9343ea167c1d3cbe15d17 (patch) | |
tree | 7f1f706ef3989dc7e04cd26db5c17c5e6157db45 /src/kernel | |
parent | 2c06d0339fa477951f4a65df8bed606de1a2ec5e (diff) | |
download | blackbird-hostboot-d980e34032968c9b34b9343ea167c1d3cbe15d17.tar.gz blackbird-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')
-rw-r--r-- | src/kernel/deferred.C | 27 |
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; |