cpu-o3: bugfix for partial faults in x86
authorBrandon Potter <brandon.potter@amd.com>
Tue, 29 Oct 2019 15:19:59 +0000 (11:19 -0400)
committerBrandon Potter <Brandon.Potter@amd.com>
Thu, 31 Oct 2019 13:18:38 +0000 (13:18 +0000)
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 <Brandon.Potter@amd.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
src/cpu/o3/lsq_impl.hh

index c2d5e90b4396a3550d36c95682f560727323e2eb..d7dc618a2771a71529032905894f884065b7aebb 100644 (file)
@@ -1152,13 +1152,37 @@ LSQ<Impl>::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<class Impl>
 bool
 LSQ<Impl>::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;
         }