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.
This commit is contained in:
parent
fa60d5cf27
commit
a2ee51f631
2 changed files with 20 additions and 42 deletions
15
src/mem/cache/cache_impl.hh
vendored
15
src/mem/cache/cache_impl.hh
vendored
|
@ -614,15 +614,18 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt)
|
|||
// 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(),
|
||||
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());
|
||||
// The core will clean up prior senderState; we need our own.
|
||||
pf->senderState = NULL;
|
||||
pf = new Packet(req, pkt->cmd);
|
||||
pf->allocate();
|
||||
assert(pf->getAddr() == pkt->getAddr());
|
||||
assert(pf->getSize() == pkt->getSize());
|
||||
}
|
||||
|
||||
pkt->makeTimingResponse();
|
||||
|
@ -632,6 +635,8 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ class Packet : public Printable
|
|||
MemCmd cmd;
|
||||
|
||||
/// A pointer to the original request.
|
||||
RequestPtr req;
|
||||
const RequestPtr req;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -600,7 +600,7 @@ class Packet : public Printable
|
|||
* 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 @@ class Packet : public Printable
|
|||
* 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 @@ class Packet : public Printable
|
|||
* 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 @@ class Packet : public Printable
|
|||
* 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 @@ class Packet : public Printable
|
|||
}
|
||||
|
||||
static PacketPtr
|
||||
createWrite(Request *req)
|
||||
createWrite(const RequestPtr req)
|
||||
{
|
||||
PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
|
||||
pkt->refineCommand();
|
||||
|
@ -724,33 +724,6 @@ class Packet : public Printable
|
|||
deleteData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
Loading…
Reference in a new issue