Kernel: Remove the big inode lock

This moves locking to the inodes themselves which allows reducing lock
times significantly. Main inodes (ext2 and tmpfs) still do contain a
single big mutex that gets locked during operations but now we have the
architecture to optimize these.
This commit is contained in:
2026-05-09 21:30:05 +03:00
parent a7356716ff
commit 9f4271f6d8
31 changed files with 378 additions and 189 deletions

View File

@@ -2,6 +2,7 @@
#include <BAN/HashMap.h>
#include <kernel/FS/Inode.h>
#include <kernel/Lock/Mutex.h>
#include <sys/epoll.h>
@@ -90,6 +91,7 @@ namespace Kernel
};
private:
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
SpinLock m_ready_lock;
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t> m_ready_events;

View File

@@ -1,6 +1,7 @@
#pragma once
#include <kernel/FS/Inode.h>
#include <kernel/Lock/Mutex.h>
namespace Kernel
{
@@ -44,8 +45,9 @@ namespace Kernel
private:
const bool m_is_semaphore;
uint64_t m_value;
BAN::Atomic<uint64_t> m_value;
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
};

View File

@@ -4,6 +4,7 @@
#include <BAN/StringView.h>
#include <kernel/FS/Ext2/Definitions.h>
#include <kernel/FS/Inode.h>
#include <kernel/Lock/Mutex.h>
namespace Kernel
{
@@ -110,6 +111,9 @@ namespace Kernel
Ext2::Inode m_inode;
const uint32_t m_ino;
// TODO: try to reduce locking or replace this with rwlock(?)
Mutex m_lock;
friend class Ext2FS;
friend class BAN::RefPtr<Ext2Inode>;
};

View File

@@ -10,7 +10,6 @@
#include <kernel/Credentials.h>
#include <kernel/Debug.h>
#include <kernel/Lock/Mutex.h>
#include <dirent.h>
#include <sys/socket.h>
@@ -183,11 +182,10 @@ namespace Kernel
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); }
protected:
mutable PriorityMutex m_mutex;
private:
SpinLock m_shared_region_lock;
BAN::WeakPtr<SharedFileData> m_shared_region;
SpinLock m_epoll_lock;
BAN::LinkedList<class Epoll*> m_epolls;
friend class Epoll;

View File

@@ -1,7 +1,7 @@
#pragma once
#include <BAN/Array.h>
#include <kernel/FS/Inode.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/ByteRingBuffer.h>
#include <kernel/ThreadBlocker.h>
@@ -53,6 +53,8 @@ namespace Kernel
timespec m_atime {};
timespec m_mtime {};
timespec m_ctime {};
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
BAN::UniqPtr<ByteRingBuffer> m_buffer;

View File

@@ -4,6 +4,7 @@
#include <BAN/Optional.h>
#include <kernel/FS/Inode.h>
#include <kernel/FS/TmpFS/Definitions.h>
#include <kernel/Lock/Mutex.h>
namespace Kernel
{
@@ -53,22 +54,25 @@ namespace Kernel
virtual BAN::ErrorOr<void> fsync_impl() override { return {}; }
void sync();
virtual BAN::ErrorOr<void> prepare_unlink() { return {}; };
virtual BAN::ErrorOr<void> prepare_unlink_no_lock() { return {}; };
void free_all_blocks();
void free_indirect_blocks(size_t block, uint32_t depth);
void free_indirect_blocks_no_lock(size_t block, uint32_t depth);
BAN::Optional<size_t> block_index(size_t data_block_index);
BAN::Optional<size_t> block_index_from_indirect(size_t block, size_t index, uint32_t depth);
BAN::Optional<size_t> block_index_from_indirect_no_lock(size_t block, size_t index, uint32_t depth);
BAN::ErrorOr<size_t> block_index_with_allocation(size_t data_block_index);
BAN::ErrorOr<size_t> block_index_from_indirect_with_allocation(size_t& block, size_t index, uint32_t depth);
BAN::ErrorOr<size_t> block_index_from_indirect_with_allocation_no_lock(size_t& block, size_t index, uint32_t depth);
protected:
TmpFileSystem& m_fs;
TmpInodeInfo m_inode_info;
const ino_t m_ino;
// TODO: try to reduce locking or replace this with rwlock(?)
Mutex m_lock;
// has to be able to increase link count
friend class TmpDirectoryInode;
};
@@ -149,7 +153,7 @@ namespace Kernel
protected:
TmpDirectoryInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
virtual BAN::ErrorOr<void> prepare_unlink() override;
virtual BAN::ErrorOr<void> prepare_unlink_no_lock() override;
protected:
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override final;

View File

@@ -46,7 +46,7 @@ namespace Kernel
uint32_t lock_depth() const override { return m_lock_depth; }
private:
SpinLock& m_lock;
Lock& m_lock;
uint32_t m_lock_depth { 0 };
InterruptState m_state;
const pid_t m_locker;

View File

@@ -181,6 +181,7 @@ namespace Kernel
uint64_t m_time_wait_start_ms { 0 };
mutable Mutex m_mutex;
ThreadBlocker m_thread_blocker;
RecvWindowInfo m_recv_window;

View File

@@ -66,9 +66,12 @@ namespace Kernel
SpinLock m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
SpinLock m_peer_address_lock;
sockaddr_storage m_peer_address {};
socklen_t m_peer_address_len { 0 };
Mutex m_bind_lock;
friend class BAN::RefPtr<UDPSocket>;
};

View File

@@ -43,15 +43,16 @@ namespace Kernel
UnixDomainSocket(Socket::Type, const Socket::Info&);
~UnixDomainSocket();
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
bool is_bound_to_unused() const { return !m_bound_file.inode; }
bool is_bound() const;
bool is_bound_to_unused() const;
BAN::ErrorOr<void> bind_to_unused_if_not_bound();
bool is_streaming() const;
private:
struct ConnectionInfo
{
bool listening { false };
BAN::Atomic<bool> listening { false };
BAN::Atomic<bool> connection_done { false };
mutable BAN::Atomic<bool> target_closed { false };
BAN::WeakPtr<UnixDomainSocket> connection;
@@ -62,6 +63,7 @@ namespace Kernel
struct ConnectionlessInfo
{
SpinLock lock;
BAN::String peer_address;
};
@@ -76,7 +78,9 @@ namespace Kernel
BAN::ErrorOr<size_t> add_packet(const msghdr&, PacketInfo&&, bool dont_block);
private:
const Socket::Type m_socket_type;
const Socket::Type m_socket_type;
mutable Mutex m_bind_mutex;
VirtualFileSystem::File m_bound_file;
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;

View File

@@ -67,7 +67,7 @@ namespace Kernel
bool putchar_impl(uint8_t ch) override;
bool can_write_impl() const override;
bool has_hungup_impl() const override { return !m_master.valid(); }
bool has_hungup_impl() const override { return master_has_closed(); }
private:
PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t, uid_t, gid_t);

View File

@@ -46,12 +46,14 @@ namespace Kernel
static void keyboard_task(void*);
static void initialize_devices();
bool should_receive_input() const { return m_tty_ctrl.receive_input; }
void on_key_event(LibInput::RawKeyEvent);
void on_key_event(LibInput::KeyEvent);
void handle_input_byte(uint8_t);
void get_termios(termios* termios) { *termios = m_termios; }
// FIXME: validate termios
BAN::ErrorOr<void> set_termios(const termios* termios) { m_termios = *termios; return {}; }
void get_termios(termios*);
BAN::ErrorOr<void> set_termios(const termios*);
virtual bool is_tty() const override { return true; }
@@ -85,9 +87,6 @@ namespace Kernel
bool putchar(uint8_t ch);
void do_backspace();
protected:
termios m_termios;
private:
const dev_t m_rdev;
@@ -95,23 +94,27 @@ namespace Kernel
struct tty_ctrl_t
{
bool draw_graphics { true };
bool receive_input { true };
ThreadBlocker thread_blocker;
BAN::Atomic<bool> draw_graphics { true };
BAN::Atomic<bool> receive_input { true };
};
tty_ctrl_t m_tty_ctrl;
struct Buffer
{
BAN::UniqPtr<ByteRingBuffer> buffer;
bool flush { false };
BAN::Atomic<bool> flush { false };
ThreadBlocker thread_blocker;
};
Buffer m_output;
winsize m_winsize {};
SpinLock m_termios_lock;
termios m_termios;
protected:
Mutex m_mutex;
RecursiveSpinLock m_write_lock;
ThreadBlocker m_write_blocker;
};

View File

@@ -62,8 +62,8 @@ namespace Kernel
Mutex m_command_mutex;
BAN::Atomic<bool> m_has_initialized_leds { false };
uint8_t m_led_state { 0b0001 };
uint8_t m_rumble_strength { 0x00 };
BAN::Atomic<uint8_t> m_led_state { 0b0001 };
BAN::Atomic<uint8_t> m_rumble_strength { 0x00 };
friend class BAN::RefPtr<USBJoystick>;
};