From 756a73471e1ac700c0a7635cffe2166ea2376e36 Mon Sep 17 00:00:00 2001 From: Pankaj Raghav Date: Wed, 12 Apr 2023 22:49:07 +0200 Subject: Kernel: Use SpinlockProtected list in SharedIRQHandler Adding handlers to the SharedIRQHandler without any lock is not thread safe. Use SpinlockProtected list instead. --- Kernel/Interrupts/SharedIRQHandler.cpp | 21 +++++++++++---------- Kernel/Interrupts/SharedIRQHandler.h | 8 ++++++-- 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'Kernel/Interrupts') 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& 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 #include #include +#include namespace Kernel { class IRQHandler; @@ -27,7 +28,10 @@ public: void enumerate_handlers(Function&); - 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 m_handlers; NonnullLockRefPtr m_responsible_irq_controller; }; } -- cgit v1.2.3