diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2016-04-21 04:48:07 -0400 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2016-04-21 04:48:07 -0400 |
commit | 13b9d4215dd0b5154f8f27fc6867a07c648a1af9 (patch) | |
tree | a47c957482b797e2bfda17b015bc8c7d832b9006 /src/mem/cache/cache.cc | |
parent | 6c92ee49f1125559ffc7c20cfe96306b9c4de017 (diff) | |
download | gem5-13b9d4215dd0b5154f8f27fc6867a07c648a1af9.tar.xz |
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 (limited to 'src/mem/cache/cache.cc')
-rw-r--r-- | src/mem/cache/cache.cc | 78 |
1 files changed, 8 insertions, 70 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 0bdec65e7..a64fc0c9c 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -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 |