mem-cache: Allow clflush's uncacheable requests on classic cache

When a linux kernel changes a page property, it flushes the related cache
lines. The kernel might change the page property before flushing the
cache lines. This results in the clflush might occur in an uncacheable region.

Currently, an uncacheable request must be a read or a write. However,
clflush request is neither of them.

This change aims to allow clflush requests to work on uncacheable regions.
Since there is no straightforward way to check if a packet is from a clflush
instruction, this change permits all Clean Invalidate Requests, which is
the type of request produced by clflush, to work on uncacheable regions.

Change-Id: Ib3ec01d9281d3dfe565a0ced773ed912edb32b8f
Signed-off-by: Hoa Nguyen <hn@hnpl.org>
This commit is contained in:
Hoa Nguyen
2023-08-19 18:19:41 +00:00
parent d7d441becb
commit 98daec7d99
2 changed files with 19 additions and 3 deletions

View File

@@ -338,15 +338,22 @@ Cache::handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time,
if (pkt->isWrite()) {
allocateWriteBuffer(pkt, forward_time);
} else {
assert(pkt->isRead());
} else if (pkt->isRead() {
// uncacheable accesses always allocate a new MSHR
// Here we are using forward_time, modelling the latency of
// a miss (outbound) just as forwardLatency, neglecting the
// lookupLatency component.
allocateMissBuffer(pkt, forward_time);
} else {
// When a linux kernel wants to change a page property,
// it flushes the related cache lines. The kernel might change
// the page property before flushing the cache. This results in
// the clflush might occur in an uncacheable region.
// clflush results in a CleanInvalidReq, which is neither read
// nor write.
assert(pkt->req->isCleanInvalidateRequest());
allocateWriteBuffer(pkt, forward_time);
}
return;

View File

@@ -1437,6 +1437,15 @@ class Packet : public Printable, public Extensible<Packet>
return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
}
/**
* Is this packet a clean invalidate request, e.g., clflush/clflushopt?
*/
bool
isCleanInvalidateRequst() const
{
return cmd == MemCmd::CleanInvalidReq;
}
bool
isMaskedWrite() const
{