diff options
author | Pankaj Raghav <p.raghav@samsung.com> | 2023-04-12 22:49:07 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-04-25 10:18:39 +0200 |
commit | 756a73471e1ac700c0a7635cffe2166ea2376e36 (patch) | |
tree | ebe29454d3cb905320388a6fe513d8fbf2c2bca6 /Kernel/Interrupts | |
parent | fd8a154f8cfe64cf8b0055969ccee1d33a8c6344 (diff) | |
download | serenity-756a73471e1ac700c0a7635cffe2166ea2376e36.zip |
Kernel: Use SpinlockProtected list in SharedIRQHandler
Adding handlers to the SharedIRQHandler without any lock is not thread
safe. Use SpinlockProtected list instead.
Diffstat (limited to 'Kernel/Interrupts')
-rw-r--r-- | Kernel/Interrupts/SharedIRQHandler.cpp | 21 | ||||
-rw-r--r-- | Kernel/Interrupts/SharedIRQHandler.h | 8 |
2 files changed, 17 insertions, 12 deletions
diff --git a/Kernel/Interrupts/SharedIRQHandler.cpp b/Kernel/Interrupts/SharedIRQHandler.cpp index a232faad27..64212e2971 100644 --- a/Kernel/Interrupts/SharedIRQHandler.cpp +++ b/Kernel/Interrupts/SharedIRQHandler.cpp @@ -23,15 +23,17 @@ UNMAP_AFTER_INIT void SharedIRQHandler::initialize(u8 interrupt_number) void SharedIRQHandler::register_handler(GenericInterruptHandler& handler) { dbgln_if(INTERRUPT_DEBUG, "Interrupt Handler registered @ Shared Interrupt Handler {}", interrupt_number()); - m_handlers.append(handler); + m_handlers.with([&handler](auto& list) { list.append(handler); }); enable_interrupt_vector(); } void SharedIRQHandler::unregister_handler(GenericInterruptHandler& handler) { dbgln_if(INTERRUPT_DEBUG, "Interrupt Handler unregistered @ Shared Interrupt Handler {}", interrupt_number()); - m_handlers.remove(handler); - if (m_handlers.is_empty()) - disable_interrupt_vector(); + m_handlers.with([&handler, this](auto& list) { + list.remove(handler); + if (list.is_empty()) + disable_interrupt_vector(); + }); } bool SharedIRQHandler::eoi() @@ -43,9 +45,7 @@ bool SharedIRQHandler::eoi() void SharedIRQHandler::enumerate_handlers(Function<void(GenericInterruptHandler&)>& callback) { - for (auto& handler : m_handlers) { - callback(handler); - } + m_handlers.for_each([&](auto& handler) { callback(handler); }); } SharedIRQHandler::SharedIRQHandler(u8 irq) @@ -67,11 +67,11 @@ bool SharedIRQHandler::handle_interrupt(RegisterState const& regs) if constexpr (INTERRUPT_DEBUG) { dbgln("Interrupt @ {}", interrupt_number()); - dbgln("Interrupt Handlers registered - {}", m_handlers.size_slow()); + dbgln("Interrupt Handlers registered - {}", sharing_devices_count()); } int i = 0; bool was_handled = false; - for (auto& handler : m_handlers) { + m_handlers.for_each([&](auto& handler) { dbgln_if(INTERRUPT_DEBUG, "Going for Interrupt Handling @ {}, Shared Interrupt {}", i, interrupt_number()); if (handler.handle_interrupt(regs)) { handler.increment_call_count(); @@ -79,7 +79,8 @@ bool SharedIRQHandler::handle_interrupt(RegisterState const& regs) } dbgln_if(INTERRUPT_DEBUG, "Going for Interrupt Handling @ {}, Shared Interrupt {} - End", i, interrupt_number()); i++; - } + }); + return was_handled; } diff --git a/Kernel/Interrupts/SharedIRQHandler.h b/Kernel/Interrupts/SharedIRQHandler.h index 6f942fc6ae..85741e77d1 100644 --- a/Kernel/Interrupts/SharedIRQHandler.h +++ b/Kernel/Interrupts/SharedIRQHandler.h @@ -11,6 +11,7 @@ #include <Kernel/Arch/IRQController.h> #include <Kernel/Interrupts/GenericInterruptHandler.h> #include <Kernel/Library/LockRefPtr.h> +#include <Kernel/Locking/SpinlockProtected.h> namespace Kernel { class IRQHandler; @@ -27,7 +28,10 @@ public: void enumerate_handlers(Function<void(GenericInterruptHandler&)>&); - virtual size_t sharing_devices_count() const override { return m_handlers.size_slow(); } + virtual size_t sharing_devices_count() const override + { + return m_handlers.with([](auto& list) { return list.size_slow(); }); + } virtual bool is_shared_handler() const override { return true; } virtual bool is_sharing_with_others() const override { return false; } @@ -40,7 +44,7 @@ private: void disable_interrupt_vector(); explicit SharedIRQHandler(u8 interrupt_number); bool m_enabled { true }; - GenericInterruptHandler::List m_handlers; + SpinlockProtected<GenericInterruptHandler::List, LockRank::None> m_handlers; NonnullLockRefPtr<IRQController> m_responsible_irq_controller; }; } |