Kernel: Only send one smp message when reserving a range

This was causing some kernel panic because processors ran out of smp
message storage when reserving large areas.

Also most of the time there is no need to actually send the SMP message.
If process is mapping something to just its own address space, there is
no need for a TLB shootdown. Maybe this should be only limited to kernel
memory and threads across the same process. I'm not sure what the best
approach here and it is better to send too many invalidations that too
few!
This commit is contained in:
Bananymous 2025-08-07 16:39:02 +03:00
parent 2980173c8e
commit f5bbcc017c
3 changed files with 21 additions and 7 deletions

View File

@ -497,13 +497,13 @@ namespace Kernel
return true;
}
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message)
{
SpinLockGuard _(m_lock);
ASSERT(vaddr % PAGE_SIZE == 0);
if (only_free && !is_page_free(vaddr))
return false;
map_page_at(0, vaddr, Flags::Reserved);
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message);
return true;
}
@ -517,7 +517,14 @@ namespace Kernel
if (only_free && !is_range_free(vaddr, bytes))
return false;
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
reserve_page(vaddr + offset);
reserve_page(vaddr + offset, true, false);
Processor::broadcast_smp_message({
.type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = {
.vaddr = vaddr,
.page_count = bytes / PAGE_SIZE,
}
});
return true;
}

View File

@ -814,13 +814,13 @@ namespace Kernel
return page_data & s_page_addr_mask;
}
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message)
{
SpinLockGuard _(m_lock);
ASSERT(vaddr % PAGE_SIZE == 0);
if (only_free && !is_page_free(vaddr))
return false;
map_page_at(0, vaddr, Flags::Reserved);
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message);
return true;
}
@ -834,7 +834,14 @@ namespace Kernel
if (only_free && !is_range_free(vaddr, bytes))
return false;
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
reserve_page(vaddr + offset);
reserve_page(vaddr + offset, true, false);
Processor::broadcast_smp_message({
.type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = {
.vaddr = vaddr,
.page_count = bytes / PAGE_SIZE,
}
});
return true;
}

View File

@ -112,7 +112,7 @@ namespace Kernel
bool is_page_free(vaddr_t) const;
bool is_range_free(vaddr_t, size_t bytes) const;
bool reserve_page(vaddr_t, bool only_free = true);
bool reserve_page(vaddr_t, bool only_free = true, bool send_smp_message = true);
bool reserve_range(vaddr_t, size_t bytes, bool only_free = true);
vaddr_t reserve_free_page(vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX);