summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorPankaj Raghav <p.raghav@samsung.com>2023-04-12 22:49:07 +0200
committerAndreas Kling <kling@serenityos.org>2023-04-25 10:18:39 +0200
commit756a73471e1ac700c0a7635cffe2166ea2376e36 (patch)
treeebe29454d3cb905320388a6fe513d8fbf2c2bca6 /Kernel
parentfd8a154f8cfe64cf8b0055969ccee1d33a8c6344 (diff)
downloadserenity-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')
-rw-r--r--Kernel/Interrupts/SharedIRQHandler.cpp21
-rw-r--r--Kernel/Interrupts/SharedIRQHandler.h8
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;
};
}