88#include " runtime/memory_manager/gfx_partition.h"
99
1010#include " runtime/helpers/aligned_memory.h"
11+ #include " runtime/os_interface/os_memory.h"
1112
1213namespace NEO {
1314
@@ -16,34 +17,116 @@ const std::array<HeapIndex, 4> GfxPartition::heap32Names{{HeapIndex::HEAP_INTERN
1617 HeapIndex::HEAP_EXTERNAL_DEVICE_MEMORY,
1718 HeapIndex::HEAP_EXTERNAL}};
1819
19- void GfxPartition::init (uint64_t gpuAddressSpace) {
20-
21- // 1) Full Range SVM gfx layout:
22- //
23- // SVM H0 H1 H2 H3 STANDARD STANDARD64K
24- // |__________________________________|____|____|____|____|________________|______________|
25- // | | | | | | | |
26- // | gfxBase gfxTop
27- // 0x0 0x0000800000000000/0x10000000 for 32 bit 0x0000FFFFFFFFFFFFFFFF
28- //
29- // 2) Limited Range gfx layout (no SVM):
30- //
31- // H0 H1 H2 H3 STANDARD STANDARD64K
32- // |____|____|____|____|____________________|__________________|
33- // | | | | | | |
34- // gfxBase gfxTop
35- // 0x0 0xFFF...FFF < 48 bit
20+ const std::array<HeapIndex, 6 > GfxPartition::heapNonSvmNames{{HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY,
21+ HeapIndex::HEAP_INTERNAL,
22+ HeapIndex::HEAP_EXTERNAL_DEVICE_MEMORY,
23+ HeapIndex::HEAP_EXTERNAL,
24+ HeapIndex::HEAP_STANDARD,
25+ HeapIndex::HEAP_STANDARD64KB}};
26+ GfxPartition::~GfxPartition () {
27+ if (reservedCpuAddressRange) {
28+ OSMemory::releaseCpuAddressRange (reservedCpuAddressRange, reservedCpuAddressRangeSize);
29+ }
30+ }
31+
32+ void GfxPartition::Heap::init (uint64_t base, uint64_t size) {
33+ this ->base = base;
34+ this ->size = size;
35+
36+ // Exclude very first and very last 64K from GPU address range allocation
37+ if (size > 2 * GfxPartition::heapGranularity) {
38+ size -= 2 * GfxPartition::heapGranularity;
39+ }
40+
41+ alloc = std::make_unique<HeapAllocator>(base + GfxPartition::heapGranularity, size);
42+ }
43+
44+ void GfxPartition::freeGpuAddressRange (uint64_t ptr, size_t size) {
45+ for (auto heapName : GfxPartition::heapNonSvmNames) {
46+ auto &heap = getHeap (heapName);
47+ if ((ptr > heap.getBase ()) && ((ptr + size) < heap.getLimit ())) {
48+ heap.free (ptr, size);
49+ break ;
50+ }
51+ }
52+ }
53+
54+ void GfxPartition::init (uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToReserve) {
55+
56+ /*
57+ * I. 64-bit builds:
58+ *
59+ * 1) 48-bit Full Range SVM gfx layout:
60+ *
61+ * SVM H0 H1 H2 H3 STANDARD STANDARD64K
62+ * |__________________________________|____|____|____|____|________________|______________|
63+ * | | | | | | | |
64+ * | gfxBase gfxTop
65+ * 0x0 0x0000800000000000 0x0000FFFFFFFFFFFF
66+ *
67+ *
68+ * 2) 47-bit Full Range SVM gfx layout:
69+ *
70+ * gfxSize = 2^47 / 4 = 0x200000000000
71+ * ________________________________________________
72+ * / \
73+ * SVM / H0 H1 H2 H3 STANDARD STANDARD64K \ SVM
74+ * |________________|____|____|____|____|________________|______________|_______________|
75+ * | | | | | | | | |
76+ * | gfxBase gfxTop |
77+ * 0x0 reserveCpuAddressRange(gfxSize) 0x00007FFFFFFFFFFF
78+ * \_____________________________________ SVM _________________________________________/
79+ *
80+ *
81+ *
82+ * 3) Limited Range gfx layout (no SVM):
83+ *
84+ * H0 H1 H2 H3 STANDARD STANDARD64K
85+ * |____|____|____|____|____________________|__________________|
86+ * | | | | | | |
87+ * gfxBase gfxTop
88+ * 0x0 0xFFF...FFF < 47 bit
89+ *
90+ *
91+ * II. 32-bit builds:
92+ *
93+ * 1) 32-bit Full Range SVM gfx layout:
94+ *
95+ * SVM H0 H1 H2 H3 STANDARD STANDARD64K
96+ * |_______|____|____|____|____|________________|______________|
97+ * | | | | | | | |
98+ * | gfxBase gfxTop
99+ * 0x0 0x100000000 gpuAddressSpace
100+ */
36101
37102 uint64_t gfxTop = gpuAddressSpace + 1 ;
38- uint64_t gfxBase = is64bit ? MemoryConstants::max64BitAppAddress + 1 : MemoryConstants::max32BitAddress + 1 ;
103+ uint64_t gfxBase = 0x0ull ;
39104 const uint64_t gfxHeap32Size = 4 * MemoryConstants::gigaByte;
40105
41- if (gpuAddressSpace < MemoryConstants::max48BitAddress) {
42- gfxBase = 0ull ;
106+ if (is32bit) {
107+ gfxBase = maxNBitValue<32 > + 1 ;
108+ heapInit (HeapIndex::HEAP_SVM, 0ull , gfxBase);
109+ } else {
110+ if (gpuAddressSpace == maxNBitValue<48 >) {
111+ gfxBase = maxNBitValue<48 - 1 > + 1 ;
112+ heapInit (HeapIndex::HEAP_SVM, 0ull , gfxBase);
113+ } else if (gpuAddressSpace == maxNBitValue<47 >) {
114+ reservedCpuAddressRangeSize = cpuAddressRangeSizeToReserve;
115+ UNRECOVERABLE_IF (reservedCpuAddressRangeSize == 0 );
116+ reservedCpuAddressRange = OSMemory::reserveCpuAddressRange (reservedCpuAddressRangeSize);
117+ UNRECOVERABLE_IF (reservedCpuAddressRange == nullptr );
118+ UNRECOVERABLE_IF (!isAligned<GfxPartition::heapGranularity>(reservedCpuAddressRange));
119+ gfxBase = reinterpret_cast <uint64_t >(reservedCpuAddressRange);
120+ gfxTop = gfxBase + reservedCpuAddressRangeSize;
121+ heapInit (HeapIndex::HEAP_SVM, 0ull , gpuAddressSpace + 1 );
122+ } else if (gpuAddressSpace < maxNBitValue<47 >) {
123+ gfxBase = 0ull ;
124+ heapInit (HeapIndex::HEAP_SVM, 0ull , 0ull );
125+ } else {
126+ UNRECOVERABLE_IF (" Invalid GPU Address Range!" );
127+ }
43128 }
44129
45- heapInit (HeapIndex::HEAP_SVM, 0ull , gfxBase);
46-
47130 for (auto heap : GfxPartition::heap32Names) {
48131 heapInit (heap, gfxBase, gfxHeap32Size);
49132 gfxBase += gfxHeap32Size;
0 commit comments