summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/cache.cc5
-rw-r--r--src/mem/cache/mshr.cc37
-rw-r--r--src/mem/cache/mshr.hh45
3 files changed, 59 insertions, 28 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index e3f2777ef..db982c1f0 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -1318,7 +1318,7 @@ Cache::recvTimingResp(PacketPtr pkt)
DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
pkt->getAddr());
- blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill);
+ blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill());
assert(blk != nullptr);
}
@@ -1369,7 +1369,8 @@ Cache::recvTimingResp(PacketPtr pkt)
// any deferred targets if possible
mshr->promoteWritable();
// NB: we use the original packet here and not the response!
- blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
+ blk = handleFill(tgt_pkt, blk, writebacks,
+ mshr->allocOnFill());
assert(blk != nullptr);
// treat as a fill, and discard the invalidation
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc
index dd827ae12..86e77b186 100644
--- a/src/mem/cache/mshr.cc
+++ b/src/mem/cache/mshr.cc
@@ -65,17 +65,18 @@ using namespace std;
MSHR::MSHR() : downstreamPending(false),
pendingModified(false),
postInvalidate(false), postDowngrade(false),
- isForward(false), allocOnFill(false)
+ isForward(false)
{
}
MSHR::TargetList::TargetList()
- : needsWritable(false), hasUpgrade(false)
+ : needsWritable(false), hasUpgrade(false), allocOnFill(false)
{}
void
-MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source)
+MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source,
+ bool alloc_on_fill)
{
if (source != Target::FromSnoop) {
if (pkt->needsWritable()) {
@@ -88,6 +89,10 @@ MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source)
if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) {
hasUpgrade = true;
}
+
+ // potentially re-evaluate whether we should allocate on a fill or
+ // not
+ allocOnFill = allocOnFill || alloc_on_fill;
}
}
@@ -96,15 +101,16 @@ MSHR::TargetList::populateFlags()
{
resetFlags();
for (auto& t: *this) {
- updateFlags(t.pkt, t.source);
+ updateFlags(t.pkt, t.source, t.allocOnFill);
}
}
inline void
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
- Counter order, Target::Source source, bool markPending)
+ Counter order, Target::Source source, bool markPending,
+ bool alloc_on_fill)
{
- updateFlags(pkt, source);
+ updateFlags(pkt, source, alloc_on_fill);
if (markPending) {
// Iterate over the SenderState stack and see if we find
// an MSHR entry. If we do, set the downstreamPending
@@ -119,7 +125,7 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
}
}
- emplace_back(pkt, readyTime, order, source, markPending);
+ emplace_back(pkt, readyTime, order, source, markPending, alloc_on_fill);
}
@@ -239,7 +245,6 @@ MSHR::allocate(Addr blk_addr, unsigned blk_size, PacketPtr target,
order = _order;
assert(target);
isForward = false;
- allocOnFill = alloc_on_fill;
_isUncacheable = target->req->isUncacheable();
inService = false;
downstreamPending = false;
@@ -248,7 +253,7 @@ MSHR::allocate(Addr blk_addr, unsigned blk_size, PacketPtr target,
// snoop (mem-side request), so set source according to request here
Target::Source source = (target->cmd == MemCmd::HardPFReq) ?
Target::FromPrefetcher : Target::FromCPU;
- targets.add(target, when_ready, _order, source, true);
+ targets.add(target, when_ready, _order, source, true, alloc_on_fill);
assert(deferredTargets.isReset());
}
@@ -305,10 +310,6 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order,
// have targets addded if originally allocated uncacheable
assert(!_isUncacheable);
- // potentially re-evaluate whether we should allocate on a fill or
- // not
- allocOnFill = allocOnFill || alloc_on_fill;
-
// if there's a request already in service for this MSHR, we will
// have to defer the new target until after the response if any of
// the following are true:
@@ -326,13 +327,15 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order,
// need to put on deferred list
if (hasPostInvalidate())
replaceUpgrade(pkt);
- deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true);
+ deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true,
+ alloc_on_fill);
} else {
// No request outstanding, or still OK to append to
// outstanding request: append to regular target list. Only
// mark pending if current request hasn't been issued yet
// (isn't in service).
- targets.add(pkt, whenReady, _order, Target::FromCPU, !inService);
+ targets.add(pkt, whenReady, _order, Target::FromCPU, !inService,
+ alloc_on_fill);
}
}
@@ -431,7 +434,7 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order)
// recipient does not care there is no harm in doing so
}
targets.add(cp_pkt, curTick(), _order, Target::FromSnoop,
- downstreamPending && targets.needsWritable);
+ downstreamPending && targets.needsWritable, false);
if (pkt->needsWritable()) {
// This transaction will take away our pending copy
@@ -527,7 +530,7 @@ MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
prefix, blkAddr, blkAddr + blkSize - 1,
isSecure ? "s" : "ns",
isForward ? "Forward" : "",
- allocOnFill ? "AllocOnFill" : "",
+ allocOnFill() ? "AllocOnFill" : "",
needsWritable() ? "Wrtbl" : "",
_isUncacheable ? "Unc" : "",
inService ? "InSvc" : "",
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh
index 253f5f388..437f8d4e4 100644
--- a/src/mem/cache/mshr.hh
+++ b/src/mem/cache/mshr.hh
@@ -128,11 +128,14 @@ class MSHR : public QueueEntry, public Printable
const Source source; //!< Request from cpu, memory, or prefetcher?
const bool markedPending; //!< Did we mark upstream MSHR
//!< as downstreamPending?
+ const bool allocOnFill; //!< Should the response servicing this
+ //!< target list allocate in the cache?
Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
- Source _source, bool _markedPending)
+ Source _source, bool _markedPending, bool alloc_on_fill)
: recvTime(curTick()), readyTime(_readyTime), order(_order),
- pkt(_pkt), source(_source), markedPending(_markedPending)
+ pkt(_pkt), source(_source), markedPending(_markedPending),
+ allocOnFill(alloc_on_fill)
{}
};
@@ -141,6 +144,8 @@ class MSHR : public QueueEntry, public Printable
public:
bool needsWritable;
bool hasUpgrade;
+ /** Set when the response should allocate on fill */
+ bool allocOnFill;
TargetList();
@@ -150,10 +155,12 @@ class MSHR : public QueueEntry, public Printable
*
* @param pkt Packet considered for the flag update
* @param source Indicates the source of the packet
+ * @param alloc_on_fill Whether the pkt would allocate on a fill
*/
- void updateFlags(PacketPtr pkt, Target::Source source);
+ void updateFlags(PacketPtr pkt, Target::Source source,
+ bool alloc_on_fill);
- void resetFlags() { needsWritable = hasUpgrade = false; }
+ void resetFlags() { needsWritable = hasUpgrade = allocOnFill = false; }
/**
* Goes through the list of targets and uses them to populate
@@ -163,9 +170,29 @@ class MSHR : public QueueEntry, public Printable
*/
void populateFlags();
- bool isReset() const { return !needsWritable && !hasUpgrade; }
+ /**
+ * Tests if the flags of this TargetList have their default
+ * values.
+ */
+ bool isReset() const {
+ return !needsWritable && !hasUpgrade && !allocOnFill;
+ }
+
+ /**
+ * Add the specified packet in the TargetList. This function
+ * stores information related to the added packet and updates
+ * accordingly the flags.
+ *
+ * @param pkt Packet considered for adding
+ * @param readTime Tick at which the packet is processed by this cache
+ * @param order A counter giving a unique id to each target
+ * @param source Indicates the source agent of the packet
+ * @param markPending Set for deferred targets or pending MSHRs
+ * @param alloc_on_fill Whether it should allocate on a fill
+ */
void add(PacketPtr pkt, Tick readyTime, Counter order,
- Target::Source source, bool markPending);
+ Target::Source source, bool markPending,
+ bool alloc_on_fill);
/**
* Convert upgrades to the equivalent request if the cache line they
@@ -184,9 +211,6 @@ class MSHR : public QueueEntry, public Printable
/** MSHR list iterator. */
typedef List::iterator Iterator;
- /** Keep track of whether we should allocate on fill or not */
- bool allocOnFill;
-
/** The pending* and post* flags are only valid if inService is
* true. Using the accessor functions lets us detect if these
* flags are accessed improperly.
@@ -209,6 +233,9 @@ class MSHR : public QueueEntry, public Printable
bool sendPacket(Cache &cache);
+ bool allocOnFill() const {
+ return targets.allocOnFill;
+ }
private:
/**