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