changeset dd9763792521 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=dd9763792521
description:
        mem: Deallocate all write-queue entries when sent

        This patch removes the write-queue entry tracking previously used for
        uncacheable writes. The write-queue entry is now deallocated as soon
        as the packet is sent. As a result we also forego the stats for
        uncacheable writes. Additionally, there is no longer a need to attach
        the write-queue entry to the packet.

diffstat:

 src/mem/cache/cache.cc             |  78 +++----------------------------------
 src/mem/cache/write_queue.cc       |  19 ++------
 src/mem/cache/write_queue_entry.cc |  17 --------
 src/mem/cache/write_queue_entry.hh |   1 -
 4 files changed, 14 insertions(+), 101 deletions(-)

diffs (178 lines):

diff -r 4bc3a0c0861c -r dd9763792521 src/mem/cache/cache.cc
--- a/src/mem/cache/cache.cc    Thu Apr 21 04:48:06 2016 -0400
+++ b/src/mem/cache/cache.cc    Thu Apr 21 04:48:07 2016 -0400
@@ -1226,45 +1226,13 @@
 void
 Cache::handleUncacheableWriteResp(PacketPtr pkt)
 {
-    WriteQueueEntry *wq_entry =
-        dynamic_cast<WriteQueueEntry*>(pkt->senderState);
-    assert(wq_entry);
-
-    WriteQueueEntry::Target *target = wq_entry->getTarget();
-    Packet *tgt_pkt = target->pkt;
-
-    // we send out invalidation reqs and get invalidation
-    // responses for write-line requests
-    assert(tgt_pkt->cmd != MemCmd::WriteLineReq);
-
-    int stats_cmd_idx = tgt_pkt->cmdToIndex();
-    Tick miss_latency = curTick() - target->recvTime;
-    assert(pkt->req->masterId() < system->maxMasters());
-    mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
-        miss_latency;
-
-    tgt_pkt->makeTimingResponse();
-    // if this packet is an error copy that to the new packet
-    if (pkt->isError())
-        tgt_pkt->copyError(pkt);
-    // Reset the bus additional time as it is now accounted for
-    tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0;
     Tick completion_time = clockEdge(responseLatency) +
         pkt->headerDelay + pkt->payloadDelay;
 
-    cpuSidePort->schedTimingResp(tgt_pkt, completion_time, true);
+    // Reset the bus additional time as it is now accounted for
+    pkt->headerDelay = pkt->payloadDelay = 0;
 
-    wq_entry->popTarget();
-    assert(!wq_entry->hasTargets());
-
-    bool wasFull = writeBuffer.isFull();
-    writeBuffer.deallocate(wq_entry);
-
-    if (wasFull && !writeBuffer.isFull()) {
-        clearBlocked(Blocked_NoWBBuffers);
-    }
-
-    delete pkt;
+    cpuSidePort->schedTimingResp(pkt, completion_time, true);
 }
 
 void
@@ -1299,7 +1267,7 @@
 
     // we have dealt with any (uncacheable) writes above, from here on
     // we know we are dealing with an MSHR due to a miss or a prefetch
-    MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
+    MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
     assert(mshr);
 
     if (mshr == noTargetMSHR) {
@@ -2248,12 +2216,8 @@
     WriteQueueEntry *wq_entry = writeBuffer.getNext();
 
     // If we got a write buffer request ready, first priority is a
-    // full write buffer (but only if we have no uncacheable write
-    // responses outstanding, possibly revisit this last part),
-    // otherwhise we favour the miss requests
-    if (wq_entry &&
-        ((writeBuffer.isFull() && writeBuffer.numInService() == 0) ||
-         !miss_mshr)) {
+    // full write buffer, otherwise we favour the miss requests
+    if (wq_entry && (writeBuffer.isFull() || !miss_mshr)) {
         // need to search MSHR queue for conflicting earlier miss.
         MSHR *conflict_mshr =
             mshrQueue.findPending(wq_entry->blkAddr,
@@ -2501,34 +2465,8 @@
             tgt_pkt->cmdString(), tgt_pkt->getAddr(),
             tgt_pkt->getSize());
 
-    PacketPtr pkt = nullptr;
-    bool delete_pkt = false;
-
-    if (tgt_pkt->isEviction()) {
-        assert(!wq_entry->isUncacheable());
-        // no response expected, just forward packet as it is
-        pkt = tgt_pkt;
-    } else {
-        // the only thing we deal with besides eviction commands
-        // are uncacheable writes
-        assert(tgt_pkt->req->isUncacheable() && tgt_pkt->isWrite());
-        // not a cache block request, but a response is expected
-        // make copy of current packet to forward, keep current
-        // copy for response handling
-        pkt = new Packet(tgt_pkt, false, true);
-        pkt->setData(tgt_pkt->getConstPtr<uint8_t>());
-        delete_pkt = true;
-    }
-
-    pkt->pushSenderState(wq_entry);
-
-    if (!memSidePort->sendTimingReq(pkt)) {
-        if (delete_pkt) {
-            // we are awaiting a retry, but we
-            // delete the packet and will be creating a new packet
-            // when we get the opportunity
-            delete pkt;
-        }
+    // forward as is, both for evictions and uncacheable writes
+    if (!memSidePort->sendTimingReq(tgt_pkt)) {
         // note that we have now masked any requestBus and
         // schedSendEvent (we will wait for a retry before
         // doing anything), and this is so even if we do not
diff -r 4bc3a0c0861c -r dd9763792521 src/mem/cache/write_queue.cc
--- a/src/mem/cache/write_queue.cc      Thu Apr 21 04:48:06 2016 -0400
+++ b/src/mem/cache/write_queue.cc      Thu Apr 21 04:48:07 2016 -0400
@@ -75,17 +75,10 @@
 void
 WriteQueue::markInService(WriteQueueEntry *entry)
 {
-    if (!entry->isUncacheable()) {
-        // a normal eviction, such as a writeback or a clean evict, no
-        // more to do as we are done from the perspective of this
-        // cache
-        entry->popTarget();
-        deallocate(entry);
-    } else {
-        // uncacheable write, and we will eventually receive a
-        // response
-        entry->markInService();
-        readyList.erase(entry->readyIter);
-        _numInService += 1;
-    }
+    // for a normal eviction, such as a writeback or a clean evict,
+    // there is no more to do as we are done from the perspective of
+    // this cache, and for uncacheable write we do not need the entry
+    // as part of the response handling
+    entry->popTarget();
+    deallocate(entry);
 }
diff -r 4bc3a0c0861c -r dd9763792521 src/mem/cache/write_queue_entry.cc
--- a/src/mem/cache/write_queue_entry.cc        Thu Apr 21 04:48:06 2016 -0400
+++ b/src/mem/cache/write_queue_entry.cc        Thu Apr 21 04:48:07 2016 -0400
@@ -118,23 +118,6 @@
     targets.add(target, when_ready, _order);
 }
 
-bool
-WriteQueueEntry::markInService()
-{
-    assert(!inService);
-    if (!isUncacheable()) {
-        // we just forwarded the request packet & don't expect a
-        // response, so get rid of it
-        assert(getNumTargets() == 1);
-        popTarget();
-        return true;
-    }
-
-    inService = true;
-
-    return false;
-}
-
 void
 WriteQueueEntry::deallocate()
 {
diff -r 4bc3a0c0861c -r dd9763792521 src/mem/cache/write_queue_entry.hh
--- a/src/mem/cache/write_queue_entry.hh        Thu Apr 21 04:48:06 2016 -0400
+++ b/src/mem/cache/write_queue_entry.hh        Thu Apr 21 04:48:07 2016 -0400
@@ -136,7 +136,6 @@
     void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
                   Tick when_ready, Counter _order);
 
-    bool markInService();
 
     /**
      * Mark this entry as free.
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to