mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 01:20:25 +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 RecursiveSpinLock s_lock; // needs to be recursive because of dump_backtrace()
|
||||||
|
|
||||||
|
static void kmalloc_allocate_backup_memory();
|
||||||
|
|
||||||
struct KmallocGlobalHeap {
|
struct KmallocGlobalHeap {
|
||||||
struct ExpandGlobalHeap {
|
struct ExpandGlobalHeap {
|
||||||
KmallocGlobalHeap& m_global_heap;
|
KmallocGlobalHeap& m_global_heap;
|
||||||
|
@ -94,7 +96,11 @@ struct KmallocGlobalHeap {
|
||||||
// backup heap before returning. Otherwise we potentially lose
|
// backup heap before returning. Otherwise we potentially lose
|
||||||
// the ability to expand the heap next time we get called.
|
// the ability to expand the heap next time we get called.
|
||||||
ScopeGuard guard([&]() {
|
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
|
// 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_next_eternal_ptr;
|
||||||
static u8* s_end_of_eternal_range;
|
static u8* s_end_of_eternal_range;
|
||||||
|
|
||||||
|
static void kmalloc_allocate_backup_memory()
|
||||||
|
{
|
||||||
|
g_kmalloc_global->allocate_backup_memory();
|
||||||
|
}
|
||||||
|
|
||||||
void kmalloc_enable_expand()
|
void kmalloc_enable_expand()
|
||||||
{
|
{
|
||||||
g_kmalloc_global->allocate_backup_memory();
|
g_kmalloc_global->allocate_backup_memory();
|
||||||
|
|
Loading…
Reference in a new issue