diff options
author | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2016-09-22 12:02:29 +0100 |
---|---|---|
committer | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2017-12-05 11:47:01 +0000 |
commit | 2f4fb22f242b897568d5cbf0e6bc6a77f036f44a (patch) | |
tree | 9396a0270f7dde43d07453728aea2ea1bd27ad9b /src/mem/cache | |
parent | 9a49827a44853679b737b8ee4255ce22d5fbfa6c (diff) | |
download | gem5-2f4fb22f242b897568d5cbf0e6bc6a77f036f44a.tar.xz |
mem: Co-ordination of CMOs in the xbar
A clean packet request serving a cache maintenance operation (CMO)
visits all memories down to the specified xbar. The visited caches
invalidate their copy (if the CMO is invalidating) and if a dirty copy
is found a write packet writes the dirty data to the memory level
below the specified xbar. A response is send back when all the caches
are clean and/or invalidated and the specified xbar has seen the write
packet.
This patch adds the following functionality in the xbar:
1) Accounts for the cache clean requests that go through the xbar
2) Generates the cache clean response when both the cache clean
request and the corresponding writeclean packet has crossed the
destination xbar.
Previously transactions in the xbar were identified using the pointer
of the original request. Cache clean transactions comprise of two
different packets, the clean request and the writeclean, and therefore
have different request pointers. This patch adds support for custom
transaction IDs that by default take the value of the request pointer
but can be overriden by the contructor. This allows the clean request
and writeclean share the same id which the coherent xbar uses to
co-ordinate them and send the response in a timely manner.
Change-Id: I80db76386a1caded38dc66e6e18f930c3bb800ff
Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5051
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Diffstat (limited to 'src/mem/cache')
-rw-r--r-- | src/mem/cache/cache.cc | 11 | ||||
-rw-r--r-- | src/mem/cache/cache.hh | 2 | ||||
-rw-r--r-- | src/mem/cache/mshr.cc | 2 |
3 files changed, 8 insertions, 7 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index b0e904d39..a83f8ab12 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -1092,7 +1092,7 @@ Cache::recvAtomic(PacketPtr pkt) // until the point of reference. DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n", __func__, pkt->print(), blk->print()); - PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest()); + PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id); writebacks.push_back(wb_pkt); pkt->setSatisfied(); } @@ -1679,7 +1679,7 @@ Cache::writebackBlk(CacheBlk *blk) } PacketPtr -Cache::writecleanBlk(CacheBlk *blk, Request::Flags dest) +Cache::writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id) { Request *req = new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0, Request::wbMasterId); @@ -1688,7 +1688,7 @@ Cache::writecleanBlk(CacheBlk *blk, Request::Flags dest) } req->taskId(blk->task_id); blk->task_id = ContextSwitchTaskId::Unknown; - PacketPtr pkt = new Packet(req, MemCmd::WriteClean); + PacketPtr pkt = new Packet(req, MemCmd::WriteClean, blkSize, id); DPRINTF(Cache, "Create %s writable: %d, dirty: %d\n", pkt->print(), blk->isWritable(), blk->isDirty()); // make sure the block is not marked dirty @@ -2093,7 +2093,7 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing, if (blk_valid && blk->isDirty()) { DPRINTF(CacheVerbose, "%s: packet (snoop) %s found block: %s\n", __func__, pkt->print(), blk->print()); - PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest()); + PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id); PacketList writebacks; writebacks.push_back(wb_pkt); @@ -2643,7 +2643,8 @@ Cache::sendMSHRQueuePacket(MSHR* mshr) // until the point of reference. DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n", __func__, pkt->print(), blk->print()); - PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest()); + PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), + pkt->id); PacketList writebacks; writebacks.push_back(wb_pkt); doWritebacks(writebacks, 0); diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index cd3a1d8e5..4d840be27 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -458,7 +458,7 @@ class Cache : public BaseCache * @param dest The destination of this clean operation * @return The write clean packet for the block. */ - PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest = 0); + PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id); /** * Create a CleanEvict request for the given block. diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index d89adef19..f1a9b985e 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -426,7 +426,7 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order) // the packet and the request as part of handling the deferred // snoop. PacketPtr cp_pkt = will_respond ? new Packet(pkt, true, true) : - new Packet(new Request(*pkt->req), pkt->cmd, blkSize); + new Packet(new Request(*pkt->req), pkt->cmd, blkSize, pkt->id); if (will_respond) { // we are the ordering point, and will consequently |