From bb8a920b63d6d287dba8ec42e298329b933f9654 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 11 Aug 2021 16:50:33 -0300 Subject: [PATCH] Do not dirty memory tracking region handles if they are partially unmapped (#2536) --- Ryujinx.Memory/Tracking/RegionHandle.cs | 30 ++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index 69d779770..2e45ef801 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -43,7 +43,26 @@ namespace Ryujinx.Memory.Tracking private int _volatileCount = 0; private bool _volatile; - internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read); + internal MemoryPermission RequiredPermission + { + get + { + // If this is unmapped, allow reprotecting as RW as it can't be dirtied. + // This is required for the partial unmap cases where part of the data are still being accessed. + if (Unmapped) + { + return MemoryPermission.ReadAndWrite; + } + + if (_preAction != null) + { + return MemoryPermission.None; + } + + return Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read; + } + } + internal RegionSignal PreAction => _preAction; /// @@ -96,6 +115,15 @@ namespace Ryujinx.Memory.Tracking internal void Signal(ulong address, ulong size, bool write) { RegionSignal action = Interlocked.Exchange(ref _preAction, null); + + // If this handle was already unmapped (even if just partially), + // then we have nothing to do until it is mapped again. + // The pre-action should be still consumed to avoid flushing on remap. + if (Unmapped) + { + return; + } + action?.Invoke(address, size); if (write)