Fix handling of writeback-induced writebacks in atomic mode.
--HG-- extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c
This commit is contained in:
3
src/mem/cache/cache.hh
vendored
3
src/mem/cache/cache.hh
vendored
@@ -162,7 +162,8 @@ class Cache : public BaseCache
|
||||
* @return Pointer to the cache block touched by the request. NULL if it
|
||||
* was a miss.
|
||||
*/
|
||||
bool access(PacketPtr pkt, BlkType *&blk, int &lat);
|
||||
bool access(PacketPtr pkt, BlkType *&blk,
|
||||
int &lat, PacketList &writebacks);
|
||||
|
||||
/**
|
||||
*Handle doing the Compare and Swap function for SPARC.
|
||||
|
||||
50
src/mem/cache/cache_impl.hh
vendored
50
src/mem/cache/cache_impl.hh
vendored
@@ -260,7 +260,8 @@ Cache<TagStore>::squash(int threadNum)
|
||||
|
||||
template<class TagStore>
|
||||
bool
|
||||
Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
|
||||
Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
|
||||
int &lat, PacketList &writebacks)
|
||||
{
|
||||
if (pkt->req->isUncacheable()) {
|
||||
blk = NULL;
|
||||
@@ -308,7 +309,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
|
||||
// into the cache without having a writeable copy (or any copy at
|
||||
// all).
|
||||
if (pkt->cmd == MemCmd::Writeback) {
|
||||
PacketList writebacks;
|
||||
assert(blkSize == pkt->getSize());
|
||||
if (blk == NULL) {
|
||||
// need to do a replacement
|
||||
@@ -323,12 +323,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
|
||||
}
|
||||
std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
|
||||
blk->status |= BlkDirty;
|
||||
// copy writebacks from replacement to write buffer
|
||||
while (!writebacks.empty()) {
|
||||
PacketPtr wbPkt = writebacks.front();
|
||||
allocateWriteBuffer(wbPkt, curTick + hitLatency, true);
|
||||
writebacks.pop_front();
|
||||
}
|
||||
// nothing else to do; writeback doesn't expect response
|
||||
assert(!pkt->needsResponse());
|
||||
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
|
||||
@@ -427,13 +421,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
|
||||
|
||||
int lat = hitLatency;
|
||||
BlkType *blk = NULL;
|
||||
bool satisfied = access(pkt, blk, lat);
|
||||
PacketList writebacks;
|
||||
|
||||
bool satisfied = access(pkt, blk, lat, writebacks);
|
||||
|
||||
#if 0
|
||||
/** @todo make the fast write alloc (wh64) work with coherence. */
|
||||
|
||||
PacketList writebacks;
|
||||
|
||||
// If this is a block size write/hint (WH64) allocate the block here
|
||||
// if the coherence protocol allows it.
|
||||
if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
|
||||
@@ -451,13 +445,6 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
|
||||
++fastWrites;
|
||||
}
|
||||
}
|
||||
|
||||
// copy writebacks to write buffer
|
||||
while (!writebacks.empty()) {
|
||||
PacketPtr wbPkt = writebacks.front();
|
||||
allocateWriteBuffer(wbPkt, time, true);
|
||||
writebacks.pop_front();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool needsResponse = pkt->needsResponse();
|
||||
@@ -527,6 +514,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
|
||||
}
|
||||
}
|
||||
|
||||
// copy writebacks to write buffer
|
||||
while (!writebacks.empty()) {
|
||||
PacketPtr wbPkt = writebacks.front();
|
||||
allocateWriteBuffer(wbPkt, time, true);
|
||||
writebacks.pop_front();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -614,8 +608,9 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
|
||||
// access in timing mode
|
||||
|
||||
BlkType *blk = NULL;
|
||||
PacketList writebacks;
|
||||
|
||||
if (!access(pkt, blk, lat)) {
|
||||
if (!access(pkt, blk, lat, writebacks)) {
|
||||
// MISS
|
||||
PacketPtr busPkt = getBusPacket(pkt, blk, pkt->needsExclusive());
|
||||
|
||||
@@ -646,21 +641,20 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
|
||||
pkt->makeAtomicResponse();
|
||||
pkt->copyError(busPkt);
|
||||
} else if (isCacheFill && !is_error) {
|
||||
PacketList writebacks;
|
||||
blk = handleFill(busPkt, blk, writebacks);
|
||||
satisfyCpuSideRequest(pkt, blk);
|
||||
delete busPkt;
|
||||
|
||||
// Handle writebacks if needed
|
||||
while (!writebacks.empty()){
|
||||
PacketPtr wbPkt = writebacks.front();
|
||||
memSidePort->sendAtomic(wbPkt);
|
||||
writebacks.pop_front();
|
||||
delete wbPkt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle writebacks if needed
|
||||
while (!writebacks.empty()){
|
||||
PacketPtr wbPkt = writebacks.front();
|
||||
memSidePort->sendAtomic(wbPkt);
|
||||
writebacks.pop_front();
|
||||
delete wbPkt;
|
||||
}
|
||||
|
||||
// We now have the block one way or another (hit or completed miss)
|
||||
|
||||
if (pkt->needsResponse()) {
|
||||
|
||||
Reference in New Issue
Block a user