From b6ba0f9fad93f7062098420602d407f9baeec775 Mon Sep 17 00:00:00 2001 From: drblah Date: Fri, 31 Dec 2021 12:56:15 +0100 Subject: [PATCH] Kernel: Update E1000 link state using interrupt Calls to link_up() in the E1000 driver would read the link state directly from the hardware on every call. This had negative performance impact in high throughput situations since link_up() is called every time an IP packet's route is resolved. This patch takes inspiration from the RTL8139 network adapter where the link state is stored in a bool and only updated when the hardware generates an interrupt related to link state change. After this change I measured a ~9% increase in TCP Tx throughput using: cat /dev/zero | nc from the Serenity VM to my host machine --- Kernel/Net/Intel/E1000NetworkAdapter.cpp | 10 +++++----- Kernel/Net/Intel/E1000NetworkAdapter.h | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 0f6240c5fb..8d3db08ae8 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -221,6 +221,9 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() setup_link(); setup_interrupts(); + + m_link_up = ((in32(REG_STATUS) & STATUS_LU) != 0); + return true; } @@ -249,6 +252,8 @@ bool E1000NetworkAdapter::handle_irq(const RegisterState&) if (status & INTERRUPT_LSC) { u32 flags = in32(REG_CTRL); out32(REG_CTRL, flags | ECTRL_SLU); + + m_link_up = ((in32(REG_STATUS) & STATUS_LU) != 0); } if (status & INTERRUPT_RXDMT0) { // Threshold OK? @@ -315,11 +320,6 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::read_mac_address() } } -bool E1000NetworkAdapter::link_up() -{ - return (in32(REG_STATUS) & STATUS_LU); -} - UNMAP_AFTER_INIT void E1000NetworkAdapter::initialize_rx_descriptors() { auto* rx_descriptors = (e1000_tx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.h b/Kernel/Net/Intel/E1000NetworkAdapter.h index 8ed931c563..0ce4806b6c 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.h +++ b/Kernel/Net/Intel/E1000NetworkAdapter.h @@ -27,7 +27,7 @@ public: virtual ~E1000NetworkAdapter() override; virtual void send_raw(ReadonlyBytes) override; - virtual bool link_up() override; + virtual bool link_up() override { return m_link_up; }; virtual i32 link_speed() override; virtual bool link_full_duplex() override; @@ -93,6 +93,7 @@ protected: OwnPtr m_mmio_region; bool m_has_eeprom { false }; bool m_use_mmio { false }; + bool m_link_up { false }; EntropySource m_entropy_source; WaitQueue m_wait_queue;