cpu-o3: Fix discarded requests str-ld forwarding (#614)

With the use of large RVV vectors (i.e., 8K or 16K bits) and a limited
number of cacheLoadPorts, some loads take multiple cycles to execute.
This triggered certain conditions when store-to-load forwarding happens
in the middle of the execution of a load that already has outstanding
packets.

First, after store-to-load forwarding the request is marked as discarded
and the load is immediately writtenback, which triggers a writebackDone
that tries to delete the request, triggering an assert as it still has
outstanding packets. This patch avoid deleting the request leaving it
self owned, it will be deleted when the last packet arrives in
packetReplied.

Second, this patch avoid checking snoops on discarded requests by
checking if the request exists.

Change-Id: Icea0add0327929d3a6af7e6dd0af9945cb0d0970

Co-authored-by: Adrià Armejach <adria.armejach@bsc.es>
This commit is contained in:
Adrià Armejach
2023-11-29 17:45:03 +01:00
committed by GitHub
parent 089b82b2e9
commit eb13b32314
2 changed files with 5 additions and 3 deletions

View File

@@ -541,7 +541,7 @@ class LSQ
{
flags.set(Flag::WritebackDone);
/* If the lsq resources are already free */
if (isReleased()) {
if (_numOutstandingPackets == 0 && isReleased()) {
delete this;
}
}

View File

@@ -451,7 +451,7 @@ LSQUnit::checkSnoop(PacketPtr pkt)
LSQRequest *request = iter->request();
// Check that this snoop didn't just invalidate our lock flag
if (ld_inst->effAddrValid() &&
if (ld_inst->effAddrValid() && request &&
request->isCacheBlockHit(invalidate_addr, cacheBlockMask)
&& ld_inst->memReqFlags & Request::LLSC) {
ld_inst->tcBase()->getIsaPtr()->handleLockedSnoopHit(ld_inst.get());
@@ -463,7 +463,7 @@ LSQUnit::checkSnoop(PacketPtr pkt)
ld_inst = iter->instruction();
assert(ld_inst);
request = iter->request();
if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered())
if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered() || !request)
continue;
DPRINTF(LSQUnit, "-- inst [sn:%lli] to pktAddr:%#x\n",
@@ -1510,6 +1510,8 @@ LSQUnit::read(LSQRequest *request, ssize_t load_idx)
// first time this load got executed. Signal the senderSate
// that response packets should be discarded.
request->discard();
// Avoid checking snoops on this discarded request.
load_entry.setRequest(nullptr);
}
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt,