mem: Deallocate all write-queue entries when sent
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 21 Apr 2016 08:48:07 +0000 (04:48 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 21 Apr 2016 08:48:07 +0000 (04:48 -0400)
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.

src/mem/cache/cache.cc
src/mem/cache/write_queue.cc
src/mem/cache/write_queue_entry.cc
src/mem/cache/write_queue_entry.hh

index 0bdec65e75aaf558be29e8de8cc984635a417d1f..a64fc0c9c68827f396347a66f937529991416675 100644 (file)
@@ -1226,45 +1226,13 @@ Cache::functionalAccess(PacketPtr pkt, bool fromCpuSide)
 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);
-
-    wq_entry->popTarget();
-    assert(!wq_entry->hasTargets());
-
-    bool wasFull = writeBuffer.isFull();
-    writeBuffer.deallocate(wq_entry);
-
-    if (wasFull && !writeBuffer.isFull()) {
-        clearBlocked(Blocked_NoWBBuffers);
-    }
+    // Reset the bus additional time as it is now accounted for
+    pkt->headerDelay = pkt->payloadDelay = 0;
 
-    delete pkt;
+    cpuSidePort->schedTimingResp(pkt, completion_time, true);
 }
 
 void
@@ -1299,7 +1267,7 @@ Cache::recvTimingResp(PacketPtr pkt)
 
     // 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 @@ Cache::getNextQueueEntry()
     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 @@ Cache::sendWriteQueuePacket(WriteQueueEntry* wq_entry)
             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
index 57489c6f00f9263cd3e299e61c2620f8fa738e58..7a876b32674521f09bbf6558faa8121a5890750f 100644 (file)
@@ -75,17 +75,10 @@ WriteQueue::allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
 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);
 }
index c55aba9c8593b4b3dc71071d86436b73474f0b94..e54fed7a48564f764b9174fdb25f85488da89378 100644 (file)
@@ -118,23 +118,6 @@ WriteQueueEntry::allocate(Addr blk_addr, unsigned blk_size, PacketPtr target,
     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()
 {
index 7e34224313b4e52dabd0add61a18403f8bca9610..13dd09bf6f14f07a1248cc5a76f8d70816b9022c 100644 (file)
@@ -136,7 +136,6 @@ class WriteQueueEntry : public QueueEntry, public Printable
     void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
                   Tick when_ready, Counter _order);
 
-    bool markInService();
 
     /**
      * Mark this entry as free.