dcache: Update PLRU on misses as well as hits
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 2 Oct 2022 06:43:58 +0000 (17:43 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 2 Oct 2022 06:43:58 +0000 (17:43 +1100)
The current dcache will not update the PLRU on a cache miss which is later
satisfied during the reload process. Thus subsequent misses will potentially
evict the same cache line. The same issue happens with dcbz which are
treated more/less as load misses.

This fixes it by triggering a PLRU update when r1.choose_victim, which is
set on a miss for one cycle to snapshot the PLRU output. This means we will
update the PLRU on the same cycle as we capture its output, which is fine
(the new value will be visible on the next cycle).

That way, a "miss" will result in a PLRU update to reflect that the entry
being refilled is actually used (and will be used to serve subsequent
load operations from the same cache line while being refilled).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
dcache.vhdl

index f24e9ecea462654855b6858512c6de4665d5a895..08b17f819d42b8d5afbae469667cc04fe0e496bc 100644 (file)
@@ -818,7 +818,12 @@ begin
         process(clk)
         begin
             if rising_edge(clk) then
-                if r1.cache_hit = '1' then
+                -- We update the PLRU when hitting the cache or when replacing
+                -- an entry. The PLRU update will be "visible" on the next cycle
+                -- so the victim selection will correctly see the *old* value.
+                if r1.cache_hit = '1' or r1.choose_victim = '1' then
+                    report "PLRU update, index=" & to_hstring(r1.hit_index) &
+                        " way=" & to_hstring(r1.hit_way);
                     assert not is_X(r1.hit_index) severity failure;
                     plru_ram(to_integer(r1.hit_index)) <= plru_upd;
                 end if;
@@ -1336,6 +1341,8 @@ begin
            else
                r1.hit_load_valid <= '0';
            end if;
+
+            -- The cache hit indication is used for PLRU updates
             if req_op = OP_LOAD_HIT or req_op = OP_STORE_HIT then
                 r1.cache_hit <= '1';
             else