mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Kernel: Fix heap expansions deadlock
If a heap expansion is triggered by allocating from e.g. the RangeAllocator, which may be holding a spin lock, we cannot immediately allocate another block of backup memory, which could require the same locks to be acquired. So, defer allocating the backup memory Fixes #4675
This commit is contained in:
parent
4f1db41a6c
commit
22250780ff
Notes:
sideshowbarker
2024-07-19 00:19:34 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/22250780ffa Pull-request: https://github.com/SerenityOS/serenity/pull/4677 Issue: https://github.com/SerenityOS/serenity/issues/4675 Reviewed-by: https://github.com/awesomekling
1 changed files with 12 additions and 1 deletions
|
@ -52,6 +52,8 @@
|
|||
|
||||
static RecursiveSpinLock s_lock; // needs to be recursive because of dump_backtrace()
|
||||
|
||||
static void kmalloc_allocate_backup_memory();
|
||||
|
||||
struct KmallocGlobalHeap {
|
||||
struct ExpandGlobalHeap {
|
||||
KmallocGlobalHeap& m_global_heap;
|
||||
|
@ -94,7 +96,11 @@ struct KmallocGlobalHeap {
|
|||
// backup heap before returning. Otherwise we potentially lose
|
||||
// the ability to expand the heap next time we get called.
|
||||
ScopeGuard guard([&]() {
|
||||
m_global_heap.allocate_backup_memory();
|
||||
// We may need to defer allocating backup memory because the
|
||||
// heap expansion may have been triggered while holding some
|
||||
// other spinlock. If the expansion happens to need the same
|
||||
// spinlock we would deadlock. So, if we're in any lock, defer
|
||||
Processor::current().deferred_call_queue(kmalloc_allocate_backup_memory);
|
||||
});
|
||||
|
||||
// Now that we added our backup memory, check if the backup heap
|
||||
|
@ -197,6 +203,11 @@ bool g_dump_kmalloc_stacks;
|
|||
static u8* s_next_eternal_ptr;
|
||||
static u8* s_end_of_eternal_range;
|
||||
|
||||
static void kmalloc_allocate_backup_memory()
|
||||
{
|
||||
g_kmalloc_global->allocate_backup_memory();
|
||||
}
|
||||
|
||||
void kmalloc_enable_expand()
|
||||
{
|
||||
g_kmalloc_global->allocate_backup_memory();
|
||||
|
|
Loading…
Reference in a new issue