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
|
// to an existing MSHR. If an outstanding request is already
|
||||||
// in progress, there is nothing for the prefetch to do.
|
// in progress, there is nothing for the prefetch to do.
|
||||||
// If this is the case, we don't even create a request at all.
|
// 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) {
|
if (!mshr) {
|
||||||
pf->req = new Request(pkt->req->getPaddr(),
|
// copy the request and create a new SoftPFReq packet
|
||||||
|
RequestPtr req = new Request(pkt->req->getPaddr(),
|
||||||
pkt->req->getSize(),
|
pkt->req->getSize(),
|
||||||
pkt->req->getFlags(),
|
pkt->req->getFlags(),
|
||||||
pkt->req->masterId());
|
pkt->req->masterId());
|
||||||
// The core will clean up prior senderState; we need our own.
|
pf = new Packet(req, pkt->cmd);
|
||||||
pf->senderState = NULL;
|
pf->allocate();
|
||||||
|
assert(pf->getAddr() == pkt->getAddr());
|
||||||
|
assert(pf->getSize() == pkt->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt->makeTimingResponse();
|
pkt->makeTimingResponse();
|
||||||
|
@ -632,6 +635,8 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt)
|
||||||
std::memset(pkt->getPtr<uint8_t>(), 0xFF, pkt->getSize());
|
std::memset(pkt->getPtr<uint8_t>(), 0xFF, pkt->getSize());
|
||||||
cpuSidePort->schedTimingResp(pkt, clockEdge(lat));
|
cpuSidePort->schedTimingResp(pkt, clockEdge(lat));
|
||||||
|
|
||||||
|
// If an outstanding request is in progress (we found an
|
||||||
|
// MSHR) this is set to null
|
||||||
pkt = pf;
|
pkt = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ class Packet : public Printable
|
||||||
MemCmd cmd;
|
MemCmd cmd;
|
||||||
|
|
||||||
/// A pointer to the original request.
|
/// A pointer to the original request.
|
||||||
RequestPtr req;
|
const RequestPtr req;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -600,7 +600,7 @@ class Packet : public Printable
|
||||||
* first, but the Requests's physical address and size fields need
|
* first, but the Requests's physical address and size fields need
|
||||||
* not be valid. The command must be supplied.
|
* 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),
|
: cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
|
||||||
size(0), src(InvalidPortID), dest(InvalidPortID),
|
size(0), src(InvalidPortID), dest(InvalidPortID),
|
||||||
bytesValidStart(0), bytesValidEnd(0),
|
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
|
* a request that is for a whole block, not the address from the
|
||||||
* req. this allows for overriding the size/addr of the req.
|
* 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),
|
: cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
|
||||||
src(InvalidPortID), dest(InvalidPortID),
|
src(InvalidPortID), dest(InvalidPortID),
|
||||||
bytesValidStart(0), bytesValidEnd(0),
|
bytesValidStart(0), bytesValidEnd(0),
|
||||||
|
@ -646,7 +646,7 @@ class Packet : public Printable
|
||||||
* less than that of the original packet. In this case the new
|
* less than that of the original packet. In this case the new
|
||||||
* packet should allocate its own data.
|
* packet should allocate its own data.
|
||||||
*/
|
*/
|
||||||
Packet(Packet *pkt, bool clearFlags = false)
|
Packet(PacketPtr pkt, bool clearFlags = false)
|
||||||
: cmd(pkt->cmd), req(pkt->req),
|
: cmd(pkt->cmd), req(pkt->req),
|
||||||
data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
|
data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
|
||||||
addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
|
addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
|
||||||
|
@ -696,7 +696,7 @@ class Packet : public Printable
|
||||||
* vanilla read or write.
|
* vanilla read or write.
|
||||||
*/
|
*/
|
||||||
static PacketPtr
|
static PacketPtr
|
||||||
createRead(Request *req)
|
createRead(const RequestPtr req)
|
||||||
{
|
{
|
||||||
PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
|
PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
|
||||||
pkt->refineCommand();
|
pkt->refineCommand();
|
||||||
|
@ -704,7 +704,7 @@ class Packet : public Printable
|
||||||
}
|
}
|
||||||
|
|
||||||
static PacketPtr
|
static PacketPtr
|
||||||
createWrite(Request *req)
|
createWrite(const RequestPtr req)
|
||||||
{
|
{
|
||||||
PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
|
PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
|
||||||
pkt->refineCommand();
|
pkt->refineCommand();
|
||||||
|
@ -724,33 +724,6 @@ class Packet : public Printable
|
||||||
deleteData();
|
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
|
* Take a request packet and modify it in place to be suitable for
|
||||||
* returning as a response to that request. The source field is
|
* returning as a response to that request. The source field is
|
||||||
|
|
Loading…
Reference in a new issue