Skip to content

Commit ce29770

Browse files
Extend PhysicalAddressAllocator with page size and alignement
- this allows for reserving 64k pages or bigger with specified alignement if required Change-Id: I256d6c0d9e7fee0e2bac5f4ab5e4fd49ea9d8d50
1 parent ec48cce commit ce29770

File tree

6 files changed

+89
-37
lines changed

6 files changed

+89
-37
lines changed

runtime/memory_manager/memory_constants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#pragma once
99
#include <cstdint>
1010
#include <cstddef>
11+
#include <limits>
1112

1213
namespace MemoryConstants {
1314
static const uint64_t zoneHigh = ~(uint64_t)0xFFFFFFFF;
@@ -30,6 +31,8 @@ static const uint64_t max64BitAppAddress = ((1ULL << 47) - 1);
3031
static const uint32_t sizeOf4GBinPageEntities = (MemoryConstants::gigaByte * 4 - MemoryConstants::pageSize) / MemoryConstants::pageSize;
3132
static const uint64_t max32BitAddress = ((1ULL << 32) - 1);
3233
static const uint64_t max48BitAddress = ((1ULL << 48) - 1);
34+
static const uintptr_t page4kEntryMask = std::numeric_limits<uintptr_t>::max() & ~MemoryConstants::pageMask;
35+
static const uintptr_t page64kEntryMask = std::numeric_limits<uintptr_t>::max() & ~MemoryConstants::page64kMask;
3336
} // namespace MemoryConstants
3437

3538
const bool is32bit = (sizeof(void *) == 4) ? true : false;

runtime/memory_manager/page_table.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@ uintptr_t PTE::map(uintptr_t vm, size_t size, uint64_t entryBits, uint32_t memor
1818
size_t indexEnd = ((vm + size - 1) >> shift) & mask;
1919
uintptr_t res = -1;
2020
bool updateEntryBits = entryBits != PageTableEntry::nonValidBits;
21-
uint64_t newEntryBits = entryBits & 0xfff;
22-
auto entriesMask = std::numeric_limits<uintptr_t>::max() & ~MemoryConstants::pageMask;
21+
uint64_t newEntryBits = entryBits & MemoryConstants::pageMask;
2322
newEntryBits |= 0x1;
2423

2524
for (size_t index = indexStart; index <= indexEnd; index++) {
2625
if (entries[index] == 0x0) {
27-
uint64_t tmp = allocator->reservePage(memoryBank);
26+
uint64_t tmp = allocator->reserve4kPage(memoryBank);
2827
entries[index] = reinterpret_cast<void *>(tmp | newEntryBits);
2928
} else if (updateEntryBits) {
30-
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & entriesMask) | newEntryBits);
29+
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & MemoryConstants::page4kEntryMask) | newEntryBits);
3130
}
32-
res = std::min(reinterpret_cast<uintptr_t>(entries[index]) & entriesMask, res);
31+
res = std::min(reinterpret_cast<uintptr_t>(entries[index]) & MemoryConstants::page4kEntryMask, res);
3332
}
3433
return (res & ~newEntryBits) + (vm & (pageSize - 1));
3534
}
@@ -43,21 +42,20 @@ void PTE::pageWalk(uintptr_t vm, size_t size, size_t offset, uint64_t entryBits,
4342
uint64_t res = -1;
4443
uintptr_t rem = vm & (pageSize - 1);
4544
bool updateEntryBits = entryBits != PageTableEntry::nonValidBits;
46-
uint64_t newEntryBits = entryBits & 0xfff;
47-
auto entriesMask = std::numeric_limits<uintptr_t>::max() & ~MemoryConstants::pageMask;
45+
uint64_t newEntryBits = entryBits & MemoryConstants::pageMask;
4846
newEntryBits |= 0x1;
4947

5048
for (size_t index = indexStart; index <= indexEnd; index++) {
5149
if (entries[index] == 0x0) {
52-
uint64_t tmp = allocator->reservePage(memoryBank);
50+
uint64_t tmp = allocator->reserve4kPage(memoryBank);
5351
entries[index] = reinterpret_cast<void *>(tmp | newEntryBits);
5452
} else if (updateEntryBits) {
55-
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & entriesMask) | newEntryBits);
53+
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & MemoryConstants::page4kEntryMask) | newEntryBits);
5654
}
57-
res = reinterpret_cast<uintptr_t>(entries[index]) & entriesMask;
55+
res = reinterpret_cast<uintptr_t>(entries[index]) & MemoryConstants::page4kEntryMask;
5856

5957
size_t lSize = std::min(pageSize - rem, size);
60-
pageWalker((res & ~0x1) + rem, lSize, offset, reinterpret_cast<uintptr_t>(entries[index]) & 0xfffu);
58+
pageWalker((res & ~0x1) + rem, lSize, offset, reinterpret_cast<uintptr_t>(entries[index]) & MemoryConstants::pageMask);
6159

6260
size -= lSize;
6361
offset += lSize;

runtime/memory_manager/physical_address_allocator.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
*/
77

88
#pragma once
9+
#include "runtime/helpers/aligned_memory.h"
910
#include "runtime/helpers/debug_helpers.h"
1011
#include "runtime/memory_manager/memory_banks.h"
1112
#include "runtime/memory_manager/memory_constants.h"
1213
#include <atomic>
14+
#include <mutex>
1315

1416
namespace OCLRT {
1517

@@ -21,13 +23,28 @@ class PhysicalAddressAllocator {
2123

2224
virtual ~PhysicalAddressAllocator() = default;
2325

24-
virtual uint64_t reservePage(uint32_t memoryBank) {
26+
uint64_t reserve4kPage(uint32_t memoryBank) {
27+
return reservePage(memoryBank, MemoryConstants::pageSize, MemoryConstants::pageSize);
28+
}
29+
30+
uint64_t reserve64kPage(uint32_t memoryBank) {
31+
return reservePage(memoryBank, MemoryConstants::pageSize64k, MemoryConstants::pageSize64k);
32+
}
33+
34+
virtual uint64_t reservePage(uint32_t memoryBank, size_t pageSize, size_t alignement) {
2535
UNRECOVERABLE_IF(memoryBank != MemoryBanks::MainBank);
26-
return mainAllocator.fetch_add(MemoryConstants::pageSize);
36+
37+
std::unique_lock<std::mutex> lock(pageReserveMutex);
38+
39+
auto currentAddress = mainAllocator.load();
40+
auto alignmentSize = alignUp(currentAddress, alignement) - currentAddress;
41+
mainAllocator += alignmentSize;
42+
return mainAllocator.fetch_add(pageSize);
2743
}
2844

2945
protected:
3046
std::atomic<uint64_t> mainAllocator;
47+
std::mutex pageReserveMutex;
3148
const uint64_t initialPageAddress = 0x1000;
3249
};
3350

runtime/os_interface/windows/hw_info_config.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
#include "runtime/gen_common/hw_cmds.h"
1010
#include "runtime/helpers/hw_info.h"
1111
#include "runtime/helpers/hw_helper.h"
12-
#include "instrumentation.h"
1312
#include "runtime/memory_manager/memory_constants.h"
1413
#include "runtime/os_interface/hw_info_config.h"
1514
#include "runtime/os_interface/debug_settings_manager.h"
1615

16+
#include "instrumentation.h"
17+
1718
namespace OCLRT {
1819

1920
HwInfoConfig *hwInfoConfigFactory[IGFX_MAX_PRODUCT] = {};

unit_tests/memory_manager/physical_address_allocator_tests.cpp

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,65 @@ using namespace OCLRT;
1414

1515
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingFirstPageThenNonZeroAddressIsReturned) {
1616
MockPhysicalAddressAllocator allocator;
17-
auto physAddress = allocator.reservePage(MemoryBanks::MainBank);
17+
auto physAddress = allocator.reserve4kPage(MemoryBanks::MainBank);
1818
EXPECT_NE(0u, physAddress);
1919
}
2020

21-
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingConsecutivePagesThenReturnedAddressesAreDifferent) {
21+
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingConsecutive4kPagesThenReturnedAddressesAreDifferentAndAligned) {
2222
MockPhysicalAddressAllocator allocator;
2323

24-
auto physAddress = allocator.reservePage(MemoryBanks::MainBank);
24+
auto physAddress = allocator.reserve4kPage(MemoryBanks::MainBank);
2525
EXPECT_NE(0u, physAddress);
26-
auto physAddress1 = allocator.reservePage(MemoryBanks::MainBank);
26+
EXPECT_EQ(0u, physAddress & MemoryConstants::pageMask);
27+
28+
auto physAddress1 = allocator.reserve4kPage(MemoryBanks::MainBank);
29+
EXPECT_NE(physAddress, physAddress1);
30+
EXPECT_EQ(0u, physAddress1 & MemoryConstants::pageMask);
31+
32+
auto physAddress2 = allocator.reserve4kPage(MemoryBanks::MainBank);
33+
EXPECT_NE(physAddress1, physAddress2);
34+
EXPECT_EQ(0u, physAddress2 & MemoryConstants::pageMask);
35+
}
36+
37+
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingFirst64kPageThen64kAlignedIsReturned) {
38+
MockPhysicalAddressAllocator allocator;
39+
auto physAddress = allocator.reserve64kPage(MemoryBanks::MainBank);
40+
EXPECT_NE(0u, physAddress);
41+
EXPECT_EQ(0u, physAddress & MemoryConstants::page64kMask);
42+
}
43+
44+
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingConsecutive64kPagesThenReturnedAddressesAreDifferentAndAligned) {
45+
MockPhysicalAddressAllocator allocator;
46+
47+
auto physAddress = allocator.reserve64kPage(MemoryBanks::MainBank);
48+
EXPECT_NE(0u, physAddress);
49+
EXPECT_EQ(0u, physAddress & MemoryConstants::page64kMask);
50+
51+
auto physAddress1 = allocator.reserve64kPage(MemoryBanks::MainBank);
2752
EXPECT_NE(physAddress, physAddress1);
28-
auto physAddress2 = allocator.reservePage(MemoryBanks::MainBank);
53+
EXPECT_EQ(0u, physAddress & MemoryConstants::page64kMask);
54+
55+
auto physAddress2 = allocator.reserve64kPage(MemoryBanks::MainBank);
2956
EXPECT_NE(physAddress1, physAddress2);
57+
EXPECT_EQ(0u, physAddress & MemoryConstants::page64kMask);
58+
}
59+
60+
TEST(PhysicalAddressAllocator, givenPhysicalAddressesAllocatorWhenReservingInterleaving4kPagesAnd64kPagesThenReturnedAddressesAreCorrectlyAligned) {
61+
MockPhysicalAddressAllocator allocator;
62+
63+
auto physAddress = allocator.reserve4kPage(MemoryBanks::MainBank);
64+
EXPECT_NE(0u, physAddress);
65+
EXPECT_EQ(0u, physAddress & MemoryConstants::pageMask);
66+
67+
auto physAddress1 = allocator.reserve64kPage(MemoryBanks::MainBank);
68+
EXPECT_NE(physAddress, physAddress1);
69+
EXPECT_EQ(0u, physAddress1 & MemoryConstants::page64kMask);
70+
71+
auto physAddress2 = allocator.reserve4kPage(MemoryBanks::MainBank);
72+
EXPECT_NE(physAddress1, physAddress2);
73+
EXPECT_EQ(0u, physAddress2 & MemoryConstants::pageMask);
74+
75+
auto physAddress3 = allocator.reserve64kPage(MemoryBanks::MainBank);
76+
EXPECT_NE(physAddress, physAddress1);
77+
EXPECT_EQ(0u, physAddress3 & MemoryConstants::page64kMask);
3078
}

unit_tests/os_interface/windows/ult_dxgi_factory.cpp

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,12 @@
11
/*
2-
* Copyright (c) 2017, Intel Corporation
2+
* Copyright (C) 2017-2018 Intel Corporation
33
*
4-
* Permission is hereby granted, free of charge, to any person obtaining a
5-
* copy of this software and associated documentation files (the "Software"),
6-
* to deal in the Software without restriction, including without limitation
7-
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8-
* and/or sell copies of the Software, and to permit persons to whom the
9-
* Software is furnished to do so, subject to the following conditions:
4+
* SPDX-License-Identifier: MIT
105
*
11-
* The above copyright notice and this permission notice shall be included
12-
* in all copies or substantial portions of the Software.
13-
*
14-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15-
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17-
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18-
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19-
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20-
* OTHER DEALINGS IN THE SOFTWARE.
216
*/
227

23-
#include "unit_tests/os_interface/windows/ult_dxgi_factory.h"
248
#include "runtime/memory_manager/memory_constants.h"
9+
#include "unit_tests/os_interface/windows/ult_dxgi_factory.h"
2510

2611
namespace OCLRT {
2712

0 commit comments

Comments
 (0)