mem: Fix the snoop filter when there is a downstream addr mapper
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 20 Jun 2016 14:11:18 +0000 (15:11 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 20 Jun 2016 14:11:18 +0000 (15:11 +0100)
The snoop filter handles requests in two steps which preceed and
follow the call to send the packet downstream. An address mapper could
possibly change the address of the packet when it is sent downstream
breaking the snoop filter assumption that the address is unchanged

Change-Id: Ib2db755e9ebef4f2f7c0169a46b1b11185ffbe79
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
src/mem/coherent_xbar.cc
src/mem/snoop_filter.cc
src/mem/snoop_filter.hh

index 22642e6f29a1808c1e441da53eda4726e22aa785..f33a33b0f40e87a44a5ca93430de922760ce304e 100644 (file)
@@ -115,7 +115,6 @@ CoherentXBar::~CoherentXBar()
 void
 CoherentXBar::init()
 {
-    // the base class is responsible for determining the block size
     BaseXBar::init();
 
     // iterate over our slave ports and determine which of our
@@ -233,7 +232,9 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
 
     // in certain cases the crossbar is responsible for responding
     bool respond_directly = false;
-
+    // store the original address as an address mapper could possibly
+    // modify the address upon a sendTimingRequest
+    const Addr addr(pkt->getAddr());
     if (sink_packet) {
         DPRINTF(CoherentXBar, "Not forwarding %s to %#llx\n",
                 pkt->cmdString(), pkt->getAddr());
@@ -265,7 +266,7 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
 
     if (snoopFilter && !system->bypassCaches()) {
         // Let the snoop filter know about the success of the send operation
-        snoopFilter->finishRequest(!success, pkt);
+        snoopFilter->finishRequest(!success, addr);
     }
 
     // check if we were successful in sending the packet onwards
@@ -660,7 +661,7 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
             // operation, and do it even before sending it onwards to
             // avoid situations where atomic upward snoops sneak in
             // between and change the filter state
-            snoopFilter->finishRequest(false, pkt);
+            snoopFilter->finishRequest(false, pkt->getAddr());
 
             snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID,
                                          sf_res.first);
index 9e8f8afb87dab5484ec4c419ac54aa510d4a0c99..636861c2b6171432796ea0d4cfe7d949b76db7aa 100755 (executable)
@@ -146,12 +146,12 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
 }
 
 void
-SnoopFilter::finishRequest(bool will_retry, const Packet* cpkt)
+SnoopFilter::finishRequest(bool will_retry, const Addr addr)
 {
     if (reqLookupResult != cachedLocations.end()) {
         // since we rely on the caller, do a basic check to ensure
         // that finishRequest is being called following lookupRequest
-        assert(reqLookupResult->first == cpkt->getBlockAddr(linesize));
+        assert(reqLookupResult->first == (addr & ~(Addr(linesize - 1))));
         if (will_retry) {
             // Undo any changes made in lookupRequest to the snoop filter
             // entry if the request will come again. retryItem holds
index 2a8d1ce21963a52e59f82552042c787b5554a907..3851e581081cf1999dc4fdf661612d850078b246 100755 (executable)
@@ -141,9 +141,9 @@ class SnoopFilter : public SimObject {
      * reqLookupResult.
      *
      * @param will_retry    This request will retry on this bus / snoop filter
-     * @param cpkt          Request packet, merely for sanity checking
+     * @param addr          Packet address, merely for sanity checking
      */
-    void finishRequest(bool will_retry, const Packet* cpkt);
+    void finishRequest(bool will_retry, const Addr addr);
 
     /**
      * Handle an incoming snoop from below (the master port). These