From eb13b3231427b6e86c2714515d8f9fbccc66bfb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Armejach?= <66964292+aarmejach@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:45:03 +0100 Subject: [PATCH] cpu-o3: Fix discarded requests str-ld forwarding (#614) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/cpu/o3/lsq.hh | 2 +- src/cpu/o3/lsq_unit.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index 130c3479fa..2ed1342eb0 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -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; } } diff --git a/src/cpu/o3/lsq_unit.cc b/src/cpu/o3/lsq_unit.cc index 139e0de337..68fd464627 100644 --- a/src/cpu/o3/lsq_unit.cc +++ b/src/cpu/o3/lsq_unit.cc @@ -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,