|
@@ -42,7 +42,8 @@ void PhysicalRegion::initialize_zones()
|
|
|
size_t remaining_pages = m_pages;
|
|
|
auto base_address = m_lower;
|
|
|
|
|
|
- auto make_zones = [&](size_t pages_per_zone) {
|
|
|
+ auto make_zones = [&](size_t zone_size) {
|
|
|
+ size_t pages_per_zone = zone_size / PAGE_SIZE;
|
|
|
size_t zone_count = 0;
|
|
|
auto first_address = base_address;
|
|
|
while (remaining_pages >= pages_per_zone) {
|
|
@@ -57,10 +58,10 @@ void PhysicalRegion::initialize_zones()
|
|
|
};
|
|
|
|
|
|
// First make 16 MiB zones (with 4096 pages each)
|
|
|
- make_zones(4096);
|
|
|
+ make_zones(large_zone_size);
|
|
|
|
|
|
// Then divide any remaining space into 1 MiB zones (with 256 pages each)
|
|
|
- make_zones(256);
|
|
|
+ make_zones(small_zone_size);
|
|
|
}
|
|
|
|
|
|
OwnPtr<PhysicalRegion> PhysicalRegion::try_take_pages_from_beginning(unsigned page_count)
|
|
@@ -122,11 +123,20 @@ RefPtr<PhysicalPage> PhysicalRegion::take_free_page()
|
|
|
|
|
|
void PhysicalRegion::return_page(PhysicalAddress paddr)
|
|
|
{
|
|
|
- // FIXME: Find a way to avoid looping over the zones here.
|
|
|
- // (Do some math on the address to find the right zone index.)
|
|
|
- // The main thing that gets in the way of this is non-uniform zone sizes.
|
|
|
- // Perhaps it would be better if all zones had the same size.
|
|
|
- for (auto& zone : m_zones) {
|
|
|
+ size_t full_size_zone_index = (paddr.get() - lower().get()) / large_zone_size;
|
|
|
+ size_t large_zone_count = m_pages / (large_zone_size / PAGE_SIZE);
|
|
|
+
|
|
|
+ if (full_size_zone_index < large_zone_count) {
|
|
|
+ auto& zone = m_zones[full_size_zone_index];
|
|
|
+ VERIFY(zone.contains(paddr));
|
|
|
+ zone.deallocate_block(paddr, 0);
|
|
|
+ if (m_full_zones.contains(zone))
|
|
|
+ m_usable_zones.append(zone);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = large_zone_count; i < m_zones.size(); ++i) {
|
|
|
+ auto& zone = m_zones[i];
|
|
|
if (zone.contains(paddr)) {
|
|
|
zone.deallocate_block(paddr, 0);
|
|
|
if (m_full_zones.contains(zone))
|