Browse Source

Kernel: Handle OOM when allocating Thread FPUState

Move FPUState allocation to Thread::try_create so that allocation
failure can be observed properly by the caller.
Brian Gianforcaro 4 năm trước cách đây
mục cha
commit
60efe18a31
2 tập tin đã thay đổi với 11 bổ sung4 xóa
  1. 10 3
      Kernel/Thread.cpp
  2. 1 1
      Kernel/Thread.h

+ 10 - 3
Kernel/Thread.cpp

@@ -39,6 +39,12 @@ UNMAP_AFTER_INIT void Thread::initialize()
 
 KResultOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> process)
 {
+    // FIXME: Once we have aligned + nothrow operator new, we can avoid the manual kfree.
+    FPUState* fpu_state = (FPUState*)kmalloc_aligned<16>(sizeof(FPUState));
+    if (!fpu_state)
+        return ENOMEM;
+    ArmedScopeGuard fpu_guard([fpu_state]() { kfree_aligned(fpu_state); });
+
     auto kernel_stack_region = MM.allocate_kernel_region(default_kernel_stack_size, {}, Region::Access::Read | Region::Access::Write, AllocationStrategy::AllocateNow);
     if (!kernel_stack_region)
         return ENOMEM;
@@ -48,16 +54,18 @@ KResultOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> proce
     if (!block_timer)
         return ENOMEM;
 
-    auto thread = adopt_ref_if_nonnull(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull()));
+    auto thread = adopt_ref_if_nonnull(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull(), fpu_state));
     if (!thread)
         return ENOMEM;
+    fpu_guard.disarm();
 
     return thread.release_nonnull();
 }
 
-Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer)
+Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer, FPUState* fpu_state)
     : m_process(move(process))
     , m_kernel_stack_region(move(kernel_stack_region))
+    , m_fpu_state(fpu_state)
     , m_name(m_process->name())
     , m_block_timer(block_timer)
     , m_global_procfs_inode_index(ProcFSComponentsRegistrar::the().allocate_inode_index())
@@ -84,7 +92,6 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stac
     if constexpr (THREAD_DEBUG)
         dbgln("Created new thread {}({}:{})", m_process->name(), m_process->pid().value(), m_tid.value());
 
-    m_fpu_state = (FPUState*)kmalloc_aligned<16>(sizeof(FPUState));
     reset_fpu_state();
 
 #if ARCH(I386)

+ 1 - 1
Kernel/Thread.h

@@ -1188,7 +1188,7 @@ public:
     InodeIndex global_procfs_inode_index() const { return m_global_procfs_inode_index; }
 
 private:
-    Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
+    Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>, FPUState*);
 
     IntrusiveListNode<Thread> m_process_thread_list_node;
     int m_runnable_priority { -1 };