From: Brandon Potter Date: Tue, 29 Oct 2019 15:19:59 +0000 (-0400) Subject: cpu-o3: bugfix for partial faults in x86 X-Git-Tag: v19.0.0.0~352 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04b3ab0a571a4c55352a9680e886a58c1e6812b2;p=gem5.git cpu-o3: bugfix for partial faults in x86 The c58cb8c9 changeset broke some code related to checking consistency model guarantees (found in X86 benchmarks). This changeset adds some documentation to the code and obviates the problem. Change-Id: Ied9c6b0b1d237538efe4beb2f97ef76248ce2746 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22283 Maintainer: Brandon Potter Tested-by: kokoro Reviewed-by: Brandon Potter --- diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index c2d5e90b4..d7dc618a2 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -1152,13 +1152,37 @@ LSQ::SingleDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) return ( (LSQRequest::_requests[0]->getPaddr() & blockMask) == blockAddr); } +/** + * Caches may probe into the load-store queue to enforce memory ordering + * guarantees. This method supports probes by providing a mechanism to compare + * snoop messages with requests tracked by the load-store queue. + * + * Consistency models must enforce ordering constraints. TSO, for instance, + * must prevent memory reorderings except stores which are reordered after + * loads. The reordering restrictions negatively impact performance by + * cutting down on memory level parallelism. However, the core can regain + * performance by generating speculative loads. Speculative loads may issue + * without affecting correctness if precautions are taken to handle invalid + * memory orders. The load queue must squash under memory model violations. + * Memory model violations may occur when block ownership is granted to + * another core or the block cannot be accurately monitored by the load queue. + */ template bool LSQ::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) { bool is_hit = false; for (auto &r: _requests) { - if ((r->getPaddr() & blockMask) == blockAddr) { + /** + * The load-store queue handles partial faults which complicates this + * method. Physical addresses must be compared between requests and + * snoops. Some requests will not have a valid physical address, since + * partial faults may have outstanding translations. Therefore, the + * existence of a valid request address must be checked before + * comparing block hits. We assume no pipeline squash is needed if a + * valid request address does not exist. + */ + if (r->hasPaddr() && (r->getPaddr() & blockMask) == blockAddr) { is_hit = true; break; }