Jelajahi Sumber

Kernel: Remove the kmalloc_eternal heap :^)

This was a premature optimization from the early days of SerenityOS.
The eternal heap was a simple bump pointer allocator over a static
byte array. My original idea was to avoid heap fragmentation and improve
data locality, but both ideas were rooted in cargo culting, not data.

We would reserve 4 MiB at boot and only ended up using ~256 KiB, wasting
the rest.

This patch replaces all kmalloc_eternal() usage by regular kmalloc().
Andreas Kling 3 tahun lalu
induk
melakukan
ac7ce12123
46 mengubah file dengan 5 tambahan dan 82 penghapusan
  1. 0 11
      AK/kmalloc.h
  2. 0 1
      Kernel/Bus/USB/USBManagement.h
  3. 0 1
      Kernel/CommandLine.h
  4. 0 1
      Kernel/Devices/ConsoleDevice.h
  5. 0 1
      Kernel/Devices/DeviceManagement.h
  6. 0 1
      Kernel/Devices/FullDevice.h
  7. 0 1
      Kernel/Devices/HID/HIDManagement.h
  8. 0 1
      Kernel/Devices/KCOVDevice.h
  9. 0 1
      Kernel/Devices/MemoryDevice.h
  10. 0 1
      Kernel/Devices/NullDevice.h
  11. 1 1
      Kernel/Devices/PCISerialDevice.cpp
  12. 0 1
      Kernel/Devices/PCISerialDevice.h
  13. 0 1
      Kernel/Devices/RandomDevice.h
  14. 0 1
      Kernel/Devices/SerialDevice.h
  15. 0 1
      Kernel/Devices/VMWareBackdoor.h
  16. 0 1
      Kernel/Devices/ZeroDevice.h
  17. 0 1
      Kernel/FileSystem/VirtualFileSystem.h
  18. 0 1
      Kernel/GlobalProcessExposed.cpp
  19. 0 1
      Kernel/Graphics/Bochs/GraphicsAdapter.h
  20. 0 1
      Kernel/Graphics/FramebufferDevice.h
  21. 0 1
      Kernel/Graphics/GenericFramebufferDevice.h
  22. 0 1
      Kernel/Graphics/GraphicsManagement.h
  23. 0 1
      Kernel/Graphics/Intel/NativeGraphicsAdapter.h
  24. 0 1
      Kernel/Graphics/VGACompatibleAdapter.h
  25. 0 1
      Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h
  26. 0 25
      Kernel/Heap/kmalloc.cpp
  27. 0 2
      Kernel/Heap/kmalloc.h
  28. 1 1
      Kernel/KSyms.cpp
  29. 0 1
      Kernel/Memory/MemoryManager.h
  30. 0 1
      Kernel/Memory/PhysicalRegion.h
  31. 0 1
      Kernel/Memory/PhysicalZone.h
  32. 0 2
      Kernel/Net/LoopbackAdapter.h
  33. 0 1
      Kernel/Net/NetworkingManagement.h
  34. 0 1
      Kernel/Random.h
  35. 1 1
      Kernel/Storage/ATA/AHCIController.h
  36. 1 1
      Kernel/Storage/ATA/IDEChannel.h
  37. 0 1
      Kernel/Storage/ATA/IDEController.h
  38. 0 1
      Kernel/Storage/RamdiskController.h
  39. 1 1
      Kernel/Storage/RamdiskDevice.h
  40. 0 1
      Kernel/Storage/StorageController.h
  41. 0 1
      Kernel/Storage/StorageManagement.h
  42. 0 1
      Kernel/TTY/ConsoleManagement.h
  43. 0 1
      Kernel/TTY/PTYMultiplexer.h
  44. 0 1
      Kernel/TTY/VirtualConsole.h
  45. 0 1
      Kernel/Time/TimeManagement.h
  46. 0 1
      Userland/Applications/SystemMonitor/MemoryStatsWidget.cpp

+ 0 - 11
AK/kmalloc.h

@@ -38,17 +38,6 @@ inline size_t malloc_good_size(size_t size) { return size; }
 #    endif
 #endif
 
-#ifdef KERNEL
-#    define AK_MAKE_ETERNAL                                               \
-    public:                                                               \
-        void* operator new(size_t size) { return kmalloc_eternal(size); } \
-        void operator delete(void*, size_t) { VERIFY_NOT_REACHED(); }     \
-                                                                          \
-    private:
-#else
-#    define AK_MAKE_ETERNAL
-#endif
-
 using std::nothrow;
 
 inline void* kmalloc_array(Checked<size_t> a, Checked<size_t> b)

+ 0 - 1
Kernel/Bus/USB/USBManagement.h

@@ -13,7 +13,6 @@
 namespace Kernel::USB {
 
 class USBManagement {
-    AK_MAKE_ETERNAL;
 
 public:
     USBManagement();

+ 0 - 1
Kernel/CommandLine.h

@@ -42,7 +42,6 @@ enum class AHCIResetMode {
 };
 
 class CommandLine {
-    AK_MAKE_ETERNAL;
 
 public:
     static void early_initialize(const char* cmd_line);

+ 0 - 1
Kernel/Devices/ConsoleDevice.h

@@ -13,7 +13,6 @@
 namespace Kernel {
 
 class ConsoleDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/DeviceManagement.h

@@ -24,7 +24,6 @@
 namespace Kernel {
 
 class DeviceManagement {
-    AK_MAKE_ETERNAL;
 
 public:
     DeviceManagement();

+ 0 - 1
Kernel/Devices/FullDevice.h

@@ -11,7 +11,6 @@
 namespace Kernel {
 
 class FullDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/HID/HIDManagement.h

@@ -31,7 +31,6 @@ class KeyboardClient;
 class HIDManagement {
     friend class KeyboardDevice;
     friend class MouseDevice;
-    AK_MAKE_ETERNAL;
 
 public:
     HIDManagement();

+ 0 - 1
Kernel/Devices/KCOVDevice.h

@@ -11,7 +11,6 @@
 
 namespace Kernel {
 class KCOVDevice final : public BlockDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/MemoryDevice.h

@@ -13,7 +13,6 @@
 namespace Kernel {
 
 class MemoryDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/NullDevice.h

@@ -11,7 +11,6 @@
 namespace Kernel {
 
 class NullDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 1 - 1
Kernel/Devices/PCISerialDevice.cpp

@@ -30,7 +30,7 @@ UNMAP_AFTER_INIT void PCISerialDevice::detect()
                 // If this is the first port of the first pci serial device, store it as the debug PCI serial port (TODO: Make this configurable somehow?)
                 if (!is_available())
                     s_the = serial_device;
-                // NOTE: We intentionally leak the reference to serial_device here, as it is eternal
+                // NOTE: We intentionally leak the reference to serial_device here.
             }
 
             dmesgln("PCISerialDevice: Found {} @ {}", board_definition.name, device_identifier.address());

+ 0 - 1
Kernel/Devices/PCISerialDevice.h

@@ -14,7 +14,6 @@
 namespace Kernel {
 
 class PCISerialDevice {
-    AK_MAKE_ETERNAL
 public:
     static void detect();
     static SerialDevice& the();

+ 0 - 1
Kernel/Devices/RandomDevice.h

@@ -11,7 +11,6 @@
 namespace Kernel {
 
 class RandomDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/SerialDevice.h

@@ -12,7 +12,6 @@
 namespace Kernel {
 
 class SerialDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Devices/VMWareBackdoor.h

@@ -39,7 +39,6 @@ struct VMWareCommand {
 };
 
 class VMWareBackdoor {
-    AK_MAKE_ETERNAL;
 
 public:
     VMWareBackdoor();

+ 0 - 1
Kernel/Devices/ZeroDevice.h

@@ -11,7 +11,6 @@
 namespace Kernel {
 
 class ZeroDevice final : public CharacterDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/FileSystem/VirtualFileSystem.h

@@ -33,7 +33,6 @@ struct UidAndGid {
 };
 
 class VirtualFileSystem {
-    AK_MAKE_ETERNAL
 public:
     // Required to be at least 8 by POSIX
     // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

+ 0 - 1
Kernel/GlobalProcessExposed.cpp

@@ -403,7 +403,6 @@ private:
         JsonObjectSerializer<KBufferBuilder> json { builder };
         json.add("kmalloc_allocated", stats.bytes_allocated);
         json.add("kmalloc_available", stats.bytes_free);
-        json.add("kmalloc_eternal_allocated", stats.bytes_eternal);
         json.add("user_physical_allocated", system_memory.user_physical_pages_used);
         json.add("user_physical_available", system_memory.user_physical_pages - system_memory.user_physical_pages_used);
         json.add("user_physical_committed", system_memory.user_physical_pages_committed);

+ 0 - 1
Kernel/Graphics/Bochs/GraphicsAdapter.h

@@ -21,7 +21,6 @@ struct BochsDisplayMMIORegisters;
 
 class BochsGraphicsAdapter final : public GenericGraphicsAdapter
     , public PCI::Device {
-    AK_MAKE_ETERNAL
     friend class GraphicsManagement;
 
 private:

+ 0 - 1
Kernel/Graphics/FramebufferDevice.h

@@ -17,7 +17,6 @@
 namespace Kernel {
 
 class FramebufferDevice final : public GenericFramebufferDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Graphics/GenericFramebufferDevice.h

@@ -16,7 +16,6 @@
 namespace Kernel {
 
 class GenericFramebufferDevice : public BlockDevice {
-    AK_MAKE_ETERNAL
     friend class DeviceManagement;
 
 public:

+ 0 - 1
Kernel/Graphics/GraphicsManagement.h

@@ -27,7 +27,6 @@ class GraphicsManagement {
     friend class IntelNativeGraphicsAdapter;
     friend class VGACompatibleAdapter;
     friend class Graphics::VirtIOGPU::GraphicsAdapter;
-    AK_MAKE_ETERNAL
 
 public:
     static GraphicsManagement& the();

+ 0 - 1
Kernel/Graphics/Intel/NativeGraphicsAdapter.h

@@ -47,7 +47,6 @@ enum RegisterIndex {
 
 class IntelNativeGraphicsAdapter final
     : public VGACompatibleAdapter {
-    AK_MAKE_ETERNAL
 public:
     struct PLLSettings {
         bool is_valid() const { return (n != 0 && m1 != 0 && m2 != 0 && p1 != 0 && p2 != 0); }

+ 0 - 1
Kernel/Graphics/VGACompatibleAdapter.h

@@ -17,7 +17,6 @@ namespace Kernel {
 
 class VGACompatibleAdapter : public GenericGraphicsAdapter
     , public PCI::Device {
-    AK_MAKE_ETERNAL
 public:
     static NonnullRefPtr<VGACompatibleAdapter> initialize_with_preset_resolution(PCI::DeviceIdentifier const&, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
     static NonnullRefPtr<VGACompatibleAdapter> initialize(PCI::DeviceIdentifier const&);

+ 0 - 1
Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h

@@ -35,7 +35,6 @@ class FramebufferDevice;
 class GraphicsAdapter final
     : public GenericGraphicsAdapter
     , public VirtIO::Device {
-    AK_MAKE_ETERNAL
     friend class FramebufferDevice;
 
 public:

+ 0 - 25
Kernel/Heap/kmalloc.cpp

@@ -29,7 +29,6 @@ static constexpr size_t CHUNK_SIZE = 64;
 #endif
 
 #define POOL_SIZE (2 * MiB)
-#define ETERNAL_RANGE_SIZE (4 * MiB)
 
 namespace std {
 const nothrow_t nothrow;
@@ -307,18 +306,13 @@ READONLY_AFTER_INIT static KmallocGlobalData* g_kmalloc_global;
 alignas(KmallocGlobalData) static u8 g_kmalloc_global_heap[sizeof(KmallocGlobalData)];
 
 // Treat the heap as logically separate from .bss
-__attribute__((section(".heap"))) static u8 kmalloc_eternal_heap[ETERNAL_RANGE_SIZE];
 __attribute__((section(".heap"))) static u8 kmalloc_pool_heap[POOL_SIZE];
 
-static size_t g_kmalloc_bytes_eternal = 0;
 static size_t g_kmalloc_call_count;
 static size_t g_kfree_call_count;
 static size_t g_nested_kfree_calls;
 bool g_dump_kmalloc_stacks;
 
-static u8* s_next_eternal_ptr;
-READONLY_AFTER_INIT static u8* s_end_of_eternal_range;
-
 void kmalloc_enable_expand()
 {
     g_kmalloc_global->enable_expansion();
@@ -335,28 +329,10 @@ static inline void kmalloc_verify_nospinlock_held()
 UNMAP_AFTER_INIT void kmalloc_init()
 {
     // Zero out heap since it's placed after end_of_kernel_bss.
-    memset(kmalloc_eternal_heap, 0, sizeof(kmalloc_eternal_heap));
     memset(kmalloc_pool_heap, 0, sizeof(kmalloc_pool_heap));
     g_kmalloc_global = new (g_kmalloc_global_heap) KmallocGlobalData(kmalloc_pool_heap, sizeof(kmalloc_pool_heap));
 
     s_lock.initialize();
-
-    s_next_eternal_ptr = kmalloc_eternal_heap;
-    s_end_of_eternal_range = s_next_eternal_ptr + sizeof(kmalloc_eternal_heap);
-}
-
-void* kmalloc_eternal(size_t size)
-{
-    kmalloc_verify_nospinlock_held();
-
-    size = round_up_to_power_of_two(size, sizeof(void*));
-
-    SpinlockLocker lock(s_lock);
-    void* ptr = s_next_eternal_ptr;
-    s_next_eternal_ptr += size;
-    VERIFY(s_next_eternal_ptr < s_end_of_eternal_range);
-    g_kmalloc_bytes_eternal += size;
-    return ptr;
 }
 
 void* kmalloc(size_t size)
@@ -493,7 +469,6 @@ void get_kmalloc_stats(kmalloc_stats& stats)
     SpinlockLocker lock(s_lock);
     stats.bytes_allocated = g_kmalloc_global->allocated_bytes();
     stats.bytes_free = g_kmalloc_global->free_bytes();
-    stats.bytes_eternal = g_kmalloc_bytes_eternal;
     stats.kmalloc_call_count = g_kmalloc_call_count;
     stats.kfree_call_count = g_kfree_call_count;
 }

+ 0 - 2
Kernel/Heap/kmalloc.h

@@ -39,14 +39,12 @@ enum class align_val_t : size_t {};
 };
 
 void kmalloc_init();
-[[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_eternal(size_t);
 
 void kfree_sized(void*, size_t);
 
 struct kmalloc_stats {
     size_t bytes_allocated;
     size_t bytes_free;
-    size_t bytes_eternal;
     size_t kmalloc_call_count;
     size_t kfree_call_count;
 };

+ 1 - 1
Kernel/KSyms.cpp

@@ -65,7 +65,7 @@ UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(Bytes buffer)
 
     for (size_t i = 0; i < 8; ++i)
         s_symbol_count = (s_symbol_count << 4) | parse_hex_digit(*(bufptr++));
-    s_symbols = static_cast<KernelSymbol*>(kmalloc_eternal(sizeof(KernelSymbol) * s_symbol_count));
+    s_symbols = static_cast<KernelSymbol*>(kmalloc(sizeof(KernelSymbol) * s_symbol_count));
     ++bufptr; // skip newline
 
     dmesgln("Loading kernel symbol table...");

+ 0 - 1
Kernel/Memory/MemoryManager.h

@@ -137,7 +137,6 @@ private:
 };
 
 class MemoryManager {
-    AK_MAKE_ETERNAL
     friend class PageDirectory;
     friend class AnonymousVMObject;
     friend class Region;

+ 0 - 1
Kernel/Memory/PhysicalRegion.h

@@ -13,7 +13,6 @@
 namespace Kernel::Memory {
 
 class PhysicalRegion {
-    AK_MAKE_ETERNAL;
     AK_MAKE_NONCOPYABLE(PhysicalRegion);
     AK_MAKE_NONMOVABLE(PhysicalRegion);
 

+ 0 - 1
Kernel/Memory/PhysicalZone.h

@@ -17,7 +17,6 @@ namespace Kernel::Memory {
 // The allocator uses a buddy block scheme internally.
 
 class PhysicalZone {
-    AK_MAKE_ETERNAL;
     AK_MAKE_NONCOPYABLE(PhysicalZone);
     AK_MAKE_NONMOVABLE(PhysicalZone);
 

+ 0 - 2
Kernel/Net/LoopbackAdapter.h

@@ -11,8 +11,6 @@
 namespace Kernel {
 
 class LoopbackAdapter final : public NetworkAdapter {
-    AK_MAKE_ETERNAL
-
 private:
     LoopbackAdapter(NonnullOwnPtr<KString>);
 

+ 0 - 1
Kernel/Net/NetworkingManagement.h

@@ -20,7 +20,6 @@ namespace Kernel {
 class NetworkAdapter;
 class NetworkingManagement {
     friend class NetworkAdapter;
-    AK_MAKE_ETERNAL
 
 public:
     static NetworkingManagement& the();

+ 0 - 1
Kernel/Random.h

@@ -120,7 +120,6 @@ private:
 };
 
 class KernelRng : public FortunaPRNG<Crypto::Cipher::AESCipher, Crypto::Hash::SHA256, 256> {
-    AK_MAKE_ETERNAL;
 
 public:
     KernelRng();

+ 1 - 1
Kernel/Storage/ATA/AHCIController.h

@@ -23,7 +23,7 @@ class AHCIController final : public ATAController
     , public PCI::Device {
     friend class AHCIPortHandler;
     friend class AHCIPort;
-    AK_MAKE_ETERNAL
+
 public:
     UNMAP_AFTER_INIT static NonnullRefPtr<AHCIController> initialize(PCI::DeviceIdentifier const& pci_device_identifier);
     virtual ~AHCIController() override;

+ 1 - 1
Kernel/Storage/ATA/IDEChannel.h

@@ -37,7 +37,7 @@ class IDEController;
 class IDEChannel : public RefCounted<IDEChannel>
     , public IRQHandler {
     friend class IDEController;
-    AK_MAKE_ETERNAL
+
 public:
     enum class ChannelType : u8 {
         Primary,

+ 0 - 1
Kernel/Storage/ATA/IDEController.h

@@ -19,7 +19,6 @@ class AsyncBlockDeviceRequest;
 
 class IDEController final : public ATAController
     , public PCI::Device {
-    AK_MAKE_ETERNAL
 public:
     static NonnullRefPtr<IDEController> initialize(PCI::DeviceIdentifier const&, bool force_pio);
     virtual ~IDEController() override;

+ 0 - 1
Kernel/Storage/RamdiskController.h

@@ -18,7 +18,6 @@ namespace Kernel {
 class AsyncBlockDeviceRequest;
 
 class RamdiskController final : public StorageController {
-    AK_MAKE_ETERNAL
 public:
 public:
     static NonnullRefPtr<RamdiskController> initialize();

+ 1 - 1
Kernel/Storage/RamdiskDevice.h

@@ -16,7 +16,7 @@ class RamdiskController;
 class RamdiskDevice final : public StorageDevice {
     friend class RamdiskController;
     friend class DeviceManagement;
-    AK_MAKE_ETERNAL
+
 public:
     static NonnullRefPtr<RamdiskDevice> create(const RamdiskController&, NonnullOwnPtr<Memory::Region>&& region, int major, int minor);
     virtual ~RamdiskDevice() override;

+ 0 - 1
Kernel/Storage/StorageController.h

@@ -22,7 +22,6 @@ namespace Kernel {
 class AsyncBlockDeviceRequest;
 class StorageDevice;
 class StorageController : public RefCounted<StorageController> {
-    AK_MAKE_ETERNAL
 
 public:
     virtual ~StorageController() = default;

+ 0 - 1
Kernel/Storage/StorageManagement.h

@@ -19,7 +19,6 @@ namespace Kernel {
 
 class PartitionTable;
 class StorageManagement {
-    AK_MAKE_ETERNAL;
 
 public:
     StorageManagement();

+ 0 - 1
Kernel/TTY/ConsoleManagement.h

@@ -14,7 +14,6 @@
 namespace Kernel {
 
 class ConsoleManagement {
-    AK_MAKE_ETERNAL;
     friend class VirtualConsole;
 
 public:

+ 0 - 1
Kernel/TTY/PTYMultiplexer.h

@@ -15,7 +15,6 @@ namespace Kernel {
 class MasterPTY;
 
 class PTYMultiplexer final : public CharacterDevice {
-    AK_MAKE_ETERNAL
 public:
     PTYMultiplexer();
     virtual ~PTYMultiplexer() override;

+ 0 - 1
Kernel/TTY/VirtualConsole.h

@@ -47,7 +47,6 @@ private:
 class VirtualConsole final : public TTY
     , public KeyboardClient
     , public VT::TerminalClient {
-    AK_MAKE_ETERNAL
     friend class ConsoleManagement;
     friend class DeviceManagement;
     friend class ConsoleImpl;

+ 0 - 1
Kernel/Time/TimeManagement.h

@@ -29,7 +29,6 @@ enum class TimePrecision {
 };
 
 class TimeManagement {
-    AK_MAKE_ETERNAL;
 
 public:
     TimeManagement();

+ 0 - 1
Userland/Applications/SystemMonitor/MemoryStatsWidget.cpp

@@ -87,7 +87,6 @@ void MemoryStatsWidget::refresh()
     auto json_result = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
     auto const& json = json_result.as_object();
 
-    [[maybe_unused]] u32 kmalloc_eternal_allocated = json.get("kmalloc_eternal_allocated").to_u32();
     u32 kmalloc_allocated = json.get("kmalloc_allocated").to_u32();
     u32 kmalloc_available = json.get("kmalloc_available").to_u32();
     u64 user_physical_allocated = json.get("user_physical_allocated").to_u64();