summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-12-02 09:41:52 -0700
committerAndreas Kling <kling@serenityos.org>2020-12-02 23:19:59 +0100
commit5e08ae4e14009d40ecd5f5428c6801eaeeffd125 (patch)
tree5271e3f26c8cc69b4815a9dd66ff1ac1ad291eda
parentaec8983819fa0cd23ce251f91305a8c2cb4450dc (diff)
downloadserenity-5e08ae4e14009d40ecd5f5428c6801eaeeffd125.zip
Kernel: Fix counting interrupts
Move counting interrupts out of the handle_interrupt method so that it is done in all cases without the interrupt handler having to implement it explicitly. Also make the counter an atomic value as e.g. the LocalAPIC interrupts may be triggered on multiple processors simultaneously. Fixes #4297
-rw-r--r--Kernel/Arch/i386/CPU.cpp8
-rw-r--r--Kernel/Interrupts/GenericInterruptHandler.cpp5
-rw-r--r--Kernel/Interrupts/GenericInterruptHandler.h9
-rw-r--r--Kernel/Interrupts/SharedIRQHandler.cpp1
4 files changed, 12 insertions, 11 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp
index 0de723d461..eff69f9658 100644
--- a/Kernel/Arch/i386/CPU.cpp
+++ b/Kernel/Arch/i386/CPU.cpp
@@ -857,9 +857,11 @@ void handle_interrupt(TrapFrame* trap)
auto& regs = *trap->regs;
ASSERT(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
u8 irq = (u8)(regs.isr_number - 0x50);
- ASSERT(s_interrupt_handler[irq]);
- s_interrupt_handler[irq]->handle_interrupt(regs);
- s_interrupt_handler[irq]->eoi();
+ auto* handler = s_interrupt_handler[irq];
+ ASSERT(handler);
+ handler->increment_invoking_counter();
+ handler->handle_interrupt(regs);
+ handler->eoi();
}
void enter_trap_no_irq(TrapFrame* trap)
diff --git a/Kernel/Interrupts/GenericInterruptHandler.cpp b/Kernel/Interrupts/GenericInterruptHandler.cpp
index 5fbcb3347e..9e51cb78f0 100644
--- a/Kernel/Interrupts/GenericInterruptHandler.cpp
+++ b/Kernel/Interrupts/GenericInterruptHandler.cpp
@@ -62,8 +62,5 @@ void GenericInterruptHandler::change_interrupt_number(u8 number)
m_interrupt_number = number;
register_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this);
}
-void GenericInterruptHandler::increment_invoking_counter()
-{
- m_invoking_count++;
-}
+
}
diff --git a/Kernel/Interrupts/GenericInterruptHandler.h b/Kernel/Interrupts/GenericInterruptHandler.h
index 991a1337de..143bb87137 100644
--- a/Kernel/Interrupts/GenericInterruptHandler.h
+++ b/Kernel/Interrupts/GenericInterruptHandler.h
@@ -48,7 +48,7 @@ public:
u8 interrupt_number() const { return m_interrupt_number; }
- size_t get_invoking_count() const { return m_invoking_count; }
+ size_t get_invoking_count() const { return m_invoking_count.load(AK::MemoryOrder::memory_order_relaxed); }
virtual size_t sharing_devices_count() const = 0;
virtual bool is_shared_handler() const = 0;
@@ -59,7 +59,10 @@ public:
virtual const char* controller() const = 0;
virtual bool eoi() = 0;
- void increment_invoking_counter();
+ ALWAYS_INLINE void increment_invoking_counter()
+ {
+ m_invoking_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed);
+ }
protected:
void change_interrupt_number(u8 number);
@@ -68,7 +71,7 @@ protected:
void disable_remap() { m_disable_remap = true; }
private:
- size_t m_invoking_count { 0 };
+ Atomic<u32> m_invoking_count { 0 };
u8 m_interrupt_number { 0 };
bool m_disable_remap { false };
};
diff --git a/Kernel/Interrupts/SharedIRQHandler.cpp b/Kernel/Interrupts/SharedIRQHandler.cpp
index 59334012cd..6dee8047f9 100644
--- a/Kernel/Interrupts/SharedIRQHandler.cpp
+++ b/Kernel/Interrupts/SharedIRQHandler.cpp
@@ -87,7 +87,6 @@ SharedIRQHandler::~SharedIRQHandler()
void SharedIRQHandler::handle_interrupt(const RegisterState& regs)
{
ASSERT_INTERRUPTS_DISABLED();
- increment_invoking_counter();
#ifdef INTERRUPT_DEBUG
dbg() << "Interrupt @ " << interrupt_number();
dbg() << "Interrupt Handlers registered - " << m_handlers.size();