예제 #1
0
        public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size)
        {
            bool[] Modified = Memory.IsRegionModified(PA, Size);

            if (Modified == null)
            {
                return(true);
            }

            ClearCachedPagesIfNeeded();

            long PageSize = Memory.GetHostPageSize();

            long Mask = PageSize - 1;

            long PAEnd = PA + Size;

            bool RegMod = false;

            int Index = 0;

            while (PA < PAEnd)
            {
                long Key = PA & ~Mask;

                long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd);

                bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp);

                if (IsCached)
                {
                    CpCount -= Cp.GetTotalCount();

                    SortedCache.Remove(Cp.Node);
                }
                else
                {
                    Cp = new CachedPage();

                    Cache.Add(Key, Cp);
                }

                if (Modified[Index++] && IsCached)
                {
                    Cp = new CachedPage();

                    Cache[Key] = Cp;
                }

                Cp.Node = SortedCache.AddLast(Key);

                RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType);

                CpCount += Cp.GetTotalCount();

                PA = PAPgEnd;
            }

            return(RegMod);
        }
예제 #2
0
            public bool AddRange(long Start, long End, NvGpuBufferType BufferType)
            {
                List <Range> BtRegions = Regions[(int)BufferType];

                for (int Index = 0; Index < BtRegions.Count; Index++)
                {
                    Range Rg = BtRegions[Index];

                    if (Start >= Rg.Start && End <= Rg.End)
                    {
                        return(false);
                    }

                    if (Start <= Rg.End && Rg.Start <= End)
                    {
                        long MinStart = Math.Min(Rg.Start, Start);
                        long MaxEnd   = Math.Max(Rg.End, End);

                        BtRegions[Index] = new Range(MinStart, MaxEnd);

                        Timestamp = Environment.TickCount;

                        return(true);
                    }
                }

                BtRegions.Add(new Range(Start, End));

                Timestamp = Environment.TickCount;

                return(true);
            }
예제 #3
0
            public CachedPage(long PABase, NvGpuBufferType BufferType)
            {
                this.PABase     = PABase;
                this.BufferType = BufferType;

                Regions = new List <(long, long)>();
            }
예제 #4
0
        public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
        {
            long va = position;

            long pa = _memory.GetPhysicalAddress(va);

            long endAddr = (va + size + PageMask) & ~PageMask;

            long addrTruncated = va & ~PageMask;

            bool modified = _memory.IsRegionModified(addrTruncated, endAddr - addrTruncated);

            int newBuffMask = 1 << (int)bufferType;

            long cachedPagesCount = 0;

            while (va < endAddr)
            {
                long page = _memory.GetPhysicalAddress(va) >> PageBits;

                ConcurrentDictionary <long, int> dictionary = _cachedPages[page];

                if (dictionary == null)
                {
                    dictionary = new ConcurrentDictionary <long, int>();

                    _cachedPages[page] = dictionary;
                }
                else if (modified)
                {
                    _cachedPages[page].Clear();
                }

                if (dictionary.TryGetValue(pa, out int currBuffMask))
                {
                    if ((currBuffMask & newBuffMask) != 0)
                    {
                        cachedPagesCount++;
                    }
                    else
                    {
                        dictionary[pa] |= newBuffMask;
                    }
                }
                else
                {
                    dictionary[pa] = newBuffMask;
                }

                va += PageSize;
            }

            return(cachedPagesCount != (endAddr - addrTruncated) >> PageBits);
        }
예제 #5
0
        public bool MemoryRegionModified(NvGpuVmm Vmm, long Position, long Size, NvGpuBufferType Type)
        {
            HashSet <long> Uploaded = UploadedKeys[(int)Type];

            if (!Uploaded.Add(Position))
            {
                return(false);
            }

            return(Vmm.IsRegionModified(Position, Size, Type));
        }
예제 #6
0
        public bool MemoryRegionModified(NvGpuVmm vmm, long position, long size, NvGpuBufferType type)
        {
            HashSet <long> uploaded = _uploadedKeys[(int)type];

            if (!uploaded.Add(position))
            {
                return(false);
            }

            return(vmm.IsRegionModified(position, size, type));
        }
예제 #7
0
        private bool QueryKeyUpload(NvGpuVmm Vmm, long Key, long Size, NvGpuBufferType Type)
        {
            List <long> Uploaded = UploadedKeys[(int)Type];

            if (Uploaded.Contains(Key))
            {
                return(false);
            }

            Uploaded.Add(Key);

            return(Vmm.IsRegionModified(Key, Size, Type));
        }
예제 #8
0
        public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
        {
            long pa = _memory.GetPhysicalAddress(position);

            long addr = pa;

            long endAddr = (addr + size + PageMask) & ~PageMask;

            int newBuffMask = 1 << (int)bufferType;

            _memory.StartObservingRegion(position, size);

            long cachedPagesCount = 0;

            while (addr < endAddr)
            {
                long page = addr >> PageBits;

                ConcurrentDictionary <long, int> dictionary = CachedPages[page];

                if (dictionary == null)
                {
                    dictionary = new ConcurrentDictionary <long, int>();

                    CachedPages[page] = dictionary;
                }

                if (dictionary.TryGetValue(pa, out int currBuffMask))
                {
                    if ((currBuffMask & newBuffMask) != 0)
                    {
                        cachedPagesCount++;
                    }
                    else
                    {
                        dictionary[pa] |= newBuffMask;
                    }
                }
                else
                {
                    dictionary[pa] = newBuffMask;
                }

                addr += PageSize;
            }

            return(cachedPagesCount != (endAddr - pa + PageMask) >> PageBits);
        }
예제 #9
0
 public bool IsRegionModified(long pa, long size, NvGpuBufferType bufferType)
 {
     return(_cache.IsRegionModified(pa, size, bufferType));
 }
예제 #10
0
 public bool IsRegionModified(long PA, long Size, NvGpuBufferType BufferType)
 {
     return(Cache.IsRegionModified(Memory, BufferType, PA, Size));
 }
예제 #11
0
 public void ClearPbCache(NvGpuBufferType Type)
 {
     UploadedKeys[(int)Type].Clear();
 }
예제 #12
0
        public bool IsRegionModified(MemoryManager Memory, NvGpuBufferType BufferType, long Start, long Size)
        {
            (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(Start, Size);

            //Remove all modified ranges.
            int Index = 0;

            long Position = Start & ~NvGpuVmm.PageMask;

            while (ModifiedCount > 0)
            {
                if (Modified[Index++])
                {
                    CachedRanges.Remove(new ValueRange <CachedResource>(Position, Position + NvGpuVmm.PageSize));

                    ModifiedCount--;
                }

                Position += NvGpuVmm.PageSize;
            }

            //Mask has the bit set for the current resource type.
            //If the region is not yet present on the list, then a new ValueRange
            //is directly added with the current resource type as the only bit set.
            //Otherwise, it just sets the bit for this new resource type on the current mask.
            //The physical address of the resource is used as key, those keys are used to keep
            //track of resources that are already on the cache. A resource may be inside another
            //resource, and in this case we should return true if the "sub-resource" was not
            //yet cached.
            int Mask = 1 << (int)BufferType;

            CachedResource NewCachedValue = new CachedResource(Start, Mask);

            ValueRange <CachedResource> NewCached = new ValueRange <CachedResource>(Start, Start + Size);

            ValueRange <CachedResource>[] Ranges = CachedRanges.GetAllIntersections(NewCached);

            bool IsKeyCached = Ranges.Length > 0 && Ranges[0].Value.Key == Start;

            long LastEnd = NewCached.Start;

            long Coverage = 0;

            for (Index = 0; Index < Ranges.Length; Index++)
            {
                ValueRange <CachedResource> Current = Ranges[Index];

                CachedResource Cached = Current.Value;

                long RgStart = Math.Max(Current.Start, NewCached.Start);
                long RgEnd   = Math.Min(Current.End, NewCached.End);

                if ((Cached.Mask & Mask) != 0)
                {
                    Coverage += RgEnd - RgStart;
                }

                //Highest key value has priority, this prevents larger resources
                //for completely invalidating smaller ones on the cache. For example,
                //consider that a resource in the range [100, 200) was added, and then
                //another one in the range [50, 200). We prevent the new resource from
                //completely replacing the old one by spliting it like this:
                //New resource key is added at [50, 100), old key is still present at [100, 200).
                if (Cached.Key < Start)
                {
                    Cached.Key = Start;
                }

                Cached.Mask |= Mask;

                CachedRanges.Add(new ValueRange <CachedResource>(RgStart, RgEnd, Cached));

                if (RgStart > LastEnd)
                {
                    CachedRanges.Add(new ValueRange <CachedResource>(LastEnd, RgStart, NewCachedValue));
                }

                LastEnd = RgEnd;
            }

            if (LastEnd < NewCached.End)
            {
                CachedRanges.Add(new ValueRange <CachedResource>(LastEnd, NewCached.End, NewCachedValue));
            }

            return(!IsKeyCached || Coverage != Size);
        }
예제 #13
0
 public void ClearPbCache(NvGpuBufferType type)
 {
     _uploadedKeys[(int)type].Clear();
 }
예제 #14
0
        public bool IsRegionModified(long Position, long Size, NvGpuBufferType BufferType)
        {
            long PA = GetPhysicalAddress(Position);

            return(Cache.IsRegionModified(Memory, BufferType, Position, PA, Size));
        }
예제 #15
0
        public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size)
        {
            (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size);

            PA = Memory.GetPhysicalAddress(PA);

            ClearCachedPagesIfNeeded();

            long PageSize = AMemory.PageSize;

            EnsureResidencyInitialized(PageSize);

            bool HasResidents = AddResidency(PA, Size);

            if (!HasResidents && ModifiedCount == 0)
            {
                return(false);
            }

            long Mask = PageSize - 1;

            long ResidencyKey = PA;

            long PAEnd = PA + Size;

            bool RegMod = false;

            int Index = 0;

            while (PA < PAEnd)
            {
                long Key = PA & ~AMemory.PageMask;

                long PAPgEnd = Math.Min((PA + AMemory.PageSize) & ~AMemory.PageMask, PAEnd);

                bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp);

                if (IsCached)
                {
                    CpCount -= Cp.GetTotalCount();

                    SortedCache.Remove(Cp.Node);
                }
                else
                {
                    Cp = new CachedPage();

                    Cache.Add(Key, Cp);
                }

                if (Modified[Index++] && IsCached)
                {
                    Cp = new CachedPage();

                    Cache[Key] = Cp;
                }

                Cp.AddResidency(ResidencyKey);

                Cp.Node = SortedCache.AddLast(Key);

                RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType);

                CpCount += Cp.GetTotalCount();

                PA = PAPgEnd;
            }

            return(RegMod);
        }
예제 #16
0
        public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size)
        {
            (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size);

            //Remove all modified ranges.
            int Index = 0;

            long Position = PA & ~NvGpuVmm.PageMask;

            while (ModifiedCount > 0)
            {
                if (Modified[Index++])
                {
                    CachedRanges.Remove(new ValueRange <int>(Position, Position + NvGpuVmm.PageSize));

                    ModifiedCount--;
                }

                Position += NvGpuVmm.PageSize;
            }

            //Mask has the bit set for the current resource type.
            //If the region is not yet present on the list, then a new ValueRange
            //is directly added with the current resource type as the only bit set.
            //Otherwise, it just sets the bit for this new resource type on the current mask.
            int Mask = 1 << (int)BufferType;

            ValueRange <int> NewCached = new ValueRange <int>(PA, PA + Size);

            ValueRange <int>[] Ranges = CachedRanges.GetAllIntersections(NewCached);

            long LastEnd = NewCached.Start;

            long Coverage = 0;

            for (Index = 0; Index < Ranges.Length; Index++)
            {
                ValueRange <int> Current = Ranges[Index];

                long RgStart = Math.Max(Current.Start, NewCached.Start);
                long RgEnd   = Math.Min(Current.End, NewCached.End);

                if ((Current.Value & Mask) == 0)
                {
                    CachedRanges.Add(new ValueRange <int>(RgStart, RgEnd, Current.Value | Mask));
                }
                else
                {
                    Coverage += RgEnd - RgStart;
                }

                if (RgStart > LastEnd)
                {
                    CachedRanges.Add(new ValueRange <int>(LastEnd, RgStart, Mask));
                }

                LastEnd = RgEnd;
            }

            if (LastEnd < NewCached.End)
            {
                CachedRanges.Add(new ValueRange <int>(LastEnd, NewCached.End, Mask));
            }

            return(Coverage != Size);
        }