diff options
author | Krishnendra Nathella <krinat01@arm.com> | 2015-07-19 15:03:30 -0500 |
---|---|---|
committer | Krishnendra Nathella <krinat01@arm.com> | 2015-07-19 15:03:30 -0500 |
commit | cabd4768c7186911fda91b9ea458df775b79486a (patch) | |
tree | ded7b5edfa8d62f144258f9c8032744a86158d96 /src/cpu/simple | |
parent | c0d19391d423d16c5dc587c4946e8395b9c0db91 (diff) | |
download | gem5-cabd4768c7186911fda91b9ea458df775b79486a.tar.xz |
cpu: Fix LLSC atomic CPU wakeup
Writes to locked memory addresses (LLSC) did not wake up the locking
CPU. This can lead to deadlocks on multi-core runs. In AtomicSimpleCPU,
recvAtomicSnoop was checking if the incoming packet was an invalidation
(isInvalidate) and only then handled a locked snoop. But, writes are
seen instead of invalidates when running without caches (fast-forward
configurations). As as simple fix, now handleLockedSnoop is also called
even if the incoming snoop packet are from writes.
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/atomic.cc | 5 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 10 |
2 files changed, 12 insertions, 3 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 1eb219483..f3e14d401 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -292,7 +292,10 @@ AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop(PacketPtr pkt) } // if snoop invalidates, release any associated locks - if (pkt->isInvalidate()) { + // When run without caches, Invalidation packets will not be received + // hence we must check if the incoming packets are writes and wakeup + // the processor accordingly + if (pkt->isInvalidate() || pkt->isWrite()) { DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n", pkt->getAddr()); for (auto &t_info : cpu->threadInfo) { diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index da6427306..43f4eb9f4 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -876,8 +876,14 @@ TimingSimpleCPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt) } } - for (auto &t_info : cpu->threadInfo) { - TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask); + // Making it uniform across all CPUs: + // The CPUs need to be woken up only on an invalidation packet (when using caches) + // or on an incoming write packet (when not using caches) + // It is not necessary to wake up the processor on all incoming packets + if (pkt->isInvalidate() || pkt->isWrite()) { + for (auto &t_info : cpu->threadInfo) { + TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask); + } } } |