summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2016-04-21 04:48:07 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2016-04-21 04:48:07 -0400
commit13b9d4215dd0b5154f8f27fc6867a07c648a1af9 (patch)
treea47c957482b797e2bfda17b015bc8c7d832b9006 /src
parent6c92ee49f1125559ffc7c20cfe96306b9c4de017 (diff)
downloadgem5-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')
-rw-r--r--src/mem/cache/cache.cc78
-rw-r--r--src/mem/cache/write_queue.cc19
-rw-r--r--src/mem/cache/write_queue_entry.cc17
-rw-r--r--src/mem/cache/write_queue_entry.hh1
4 files changed, 14 insertions, 101 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
diff --git a/src/mem/cache/write_queue.cc b/src/mem/cache/write_queue.cc
index 57489c6f0..7a876b326 100644
--- a/src/mem/cache/write_queue.cc
+++ b/src/mem/cache/write_queue.cc
@@ -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);
}
diff --git a/src/mem/cache/write_queue_entry.cc b/src/mem/cache/write_queue_entry.cc
index c55aba9c8..e54fed7a4 100644
--- a/src/mem/cache/write_queue_entry.cc
+++ b/src/mem/cache/write_queue_entry.cc
@@ -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()
{
diff --git a/src/mem/cache/write_queue_entry.hh b/src/mem/cache/write_queue_entry.hh
index 7e3422431..13dd09bf6 100644
--- a/src/mem/cache/write_queue_entry.hh
+++ b/src/mem/cache/write_queue_entry.hh
@@ -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.