From 065ddf759fbde9b5a17bf9b149aa18cd8e5146c3 Mon Sep 17 00:00:00 2001 From: Matt Sinclair Date: Sun, 5 Nov 2023 02:34:22 -0600 Subject: [PATCH] mem-ruby, gpu-compute: fix bug with GPU bypassing loads The current GPU TCP (L1D$) Ruby SLICC code had a bug where a GPU load that wants to bypass the L1D$ (e.g., GLC or SLC bit was set) but the line is in Invalid when that request arrives, results in a non-bypassing load being sent to the GPU TCC (L2$) instead of a bypassing load. This issue was not caught by currently nightly or weekly tests, because the tests do not test for correctness in terms of hits and misses in the caches. However, tests for these corner cases expose this issue. To fix, this, this patch removes the check that the entry is valid when deciding what to do with a bypassing GPU load -- since the TCP Ruby code has transitions for bypassing loads in both I and V, we can simply call the LoadBypassEvict event in both cases and the appropriate transition will handle the bypassing load given the cache line's current state in the TCP. Change-Id: Ia224cefdf56b4318b2bcbd0bed995fc8d3b62a14 --- src/mem/ruby/protocol/GPU_VIPER-TCP.sm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mem/ruby/protocol/GPU_VIPER-TCP.sm b/src/mem/ruby/protocol/GPU_VIPER-TCP.sm index ee49d859a8..ae35d4c5f7 100644 --- a/src/mem/ruby/protocol/GPU_VIPER-TCP.sm +++ b/src/mem/ruby/protocol/GPU_VIPER-TCP.sm @@ -292,10 +292,13 @@ machine(MachineType:TCP, "GPU TCP (L1 Data Cache)") TBE tbe := TBEs.lookup(in_msg.LineAddress); DPRINTF(RubySlicc, "%s\n", in_msg); if (in_msg.Type == RubyRequestType:LD) { - if ((in_msg.isGLCSet || in_msg.isSLCSet) && is_valid(cache_entry)) { - // Read requests with GLC or SLC bit set should not cache in the L1. - // They need to bypass the L1 and go to the L2. If an entry exists - // in the L1, it needs to be evicted + // Read requests with GLC or SLC bit set should not cache in the L1. + // They need to bypass the L1 and go to the L2. If an entry exists in + // the L1, it needs to be evicted, and if no entry or invalid entry in + // the L1, still need to bypass. The LoadBypassEvict Event handles + // both cases in its transitions below, so call LoadBypassEvict for + // both. + if ((in_msg.isGLCSet || in_msg.isSLCSet)) { trigger(Event:LoadBypassEvict, in_msg.LineAddress, cache_entry, tbe); } else {