changeset ffd46545b284 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=ffd46545b284
description:
mem: Make the requests carried by packets const
This adds a basic level of sanity checking to the packet by ensuring
that a request is not modified once the packet is created. The only
issue that had to be worked around is the relaying of
software-prefetches in the cache. The specific situation is now solved
by first copying the request, and then creating a new packet
accordingly.
diffstat:
src/mem/cache/cache_impl.hh | 23 ++++++++++++++---------
src/mem/packet.hh | 39 ++++++---------------------------------
2 files changed, 20 insertions(+), 42 deletions(-)
diffs (134 lines):
diff -r e70523bd0d26 -r ffd46545b284 src/mem/cache/cache_impl.hh
--- a/src/mem/cache/cache_impl.hh Tue Dec 02 06:07:48 2014 -0500
+++ b/src/mem/cache/cache_impl.hh Tue Dec 02 06:07:50 2014 -0500
@@ -611,18 +611,21 @@
assert(pkt->req->hasPaddr());
// There's no reason to add a prefetch as an additional target
- // to an existing MSHR. If an outstanding request is already
+ // to an existing MSHR. If an outstanding request is already
// in progress, there is nothing for the prefetch to do.
// If this is the case, we don't even create a request at all.
- PacketPtr pf = mshr ? NULL : new Packet(pkt);
+ PacketPtr pf = nullptr;
- if (pf) {
- pf->req = new Request(pkt->req->getPaddr(),
- pkt->req->getSize(),
- pkt->req->getFlags(),
- pkt->req->masterId());
- // The core will clean up prior senderState; we need our own.
- pf->senderState = NULL;
+ if (!mshr) {
+ // copy the request and create a new SoftPFReq packet
+ RequestPtr req = new Request(pkt->req->getPaddr(),
+ pkt->req->getSize(),
+ pkt->req->getFlags(),
+ pkt->req->masterId());
+ pf = new Packet(req, pkt->cmd);
+ pf->allocate();
+ assert(pf->getAddr() == pkt->getAddr());
+ assert(pf->getSize() == pkt->getSize());
}
pkt->makeTimingResponse();
@@ -632,6 +635,8 @@
std::memset(pkt->getPtr<uint8_t>(), 0xFF, pkt->getSize());
cpuSidePort->schedTimingResp(pkt, clockEdge(lat));
+ // If an outstanding request is in progress (we found an
+ // MSHR) this is set to null
pkt = pf;
}
diff -r e70523bd0d26 -r ffd46545b284 src/mem/packet.hh
--- a/src/mem/packet.hh Tue Dec 02 06:07:48 2014 -0500
+++ b/src/mem/packet.hh Tue Dec 02 06:07:50 2014 -0500
@@ -265,7 +265,7 @@
MemCmd cmd;
/// A pointer to the original request.
- RequestPtr req;
+ const RequestPtr req;
private:
/**
@@ -600,7 +600,7 @@
* first, but the Requests's physical address and size fields need
* not be valid. The command must be supplied.
*/
- Packet(Request *_req, MemCmd _cmd)
+ Packet(const RequestPtr _req, MemCmd _cmd)
: cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
size(0), src(InvalidPortID), dest(InvalidPortID),
bytesValidStart(0), bytesValidEnd(0),
@@ -623,7 +623,7 @@
* a request that is for a whole block, not the address from the
* req. this allows for overriding the size/addr of the req.
*/
- Packet(Request *_req, MemCmd _cmd, int _blkSize)
+ Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
: cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
src(InvalidPortID), dest(InvalidPortID),
bytesValidStart(0), bytesValidEnd(0),
@@ -646,7 +646,7 @@
* less than that of the original packet. In this case the new
* packet should allocate its own data.
*/
- Packet(Packet *pkt, bool clearFlags = false)
+ Packet(PacketPtr pkt, bool clearFlags = false)
: cmd(pkt->cmd), req(pkt->req),
data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
@@ -696,7 +696,7 @@
* vanilla read or write.
*/
static PacketPtr
- createRead(Request *req)
+ createRead(const RequestPtr req)
{
PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
pkt->refineCommand();
@@ -704,7 +704,7 @@
}
static PacketPtr
- createWrite(Request *req)
+ createWrite(const RequestPtr req)
{
PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
pkt->refineCommand();
@@ -725,33 +725,6 @@
}
/**
- * Reinitialize packet address and size from the associated
- * Request object, and reset other fields that may have been
- * modified by a previous transaction. Typically called when a
- * statically allocated Request/Packet pair is reused for multiple
- * transactions.
- */
- void
- reinitFromRequest()
- {
- assert(req->hasPaddr());
- flags = 0;
- addr = req->getPaddr();
- _isSecure = req->isSecure();
- size = req->getSize();
-
- src = InvalidPortID;
- dest = InvalidPortID;
- bytesValidStart = 0;
- bytesValidEnd = 0;
- firstWordDelay = 0;
- lastWordDelay = 0;
-
- flags.set(VALID_ADDR|VALID_SIZE);
- deleteData();
- }
-
- /**
* Take a request packet and modify it in place to be suitable for
* returning as a response to that request. The source field is
* turned into the destination, and subsequently cleared. Note
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev