Kernel: Replace CriticalScopes with SpinLocks in networking code
This commit is contained in:
parent
7f028f70d5
commit
90878a7c2b
|
@ -52,6 +52,7 @@ namespace Kernel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpinLock m_table_lock;
|
SpinLock m_table_lock;
|
||||||
|
SpinLock m_pending_lock;
|
||||||
|
|
||||||
BAN::HashMap<BAN::IPv4Address, BAN::MACAddress> m_arp_table;
|
BAN::HashMap<BAN::IPv4Address, BAN::MACAddress> m_arp_table;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace Kernel
|
||||||
BAN::UniqPtr<DMARegion> m_tx_buffer_region;
|
BAN::UniqPtr<DMARegion> m_tx_buffer_region;
|
||||||
BAN::UniqPtr<DMARegion> m_rx_descriptor_region;
|
BAN::UniqPtr<DMARegion> m_rx_descriptor_region;
|
||||||
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
||||||
|
SpinLock m_lock;
|
||||||
|
|
||||||
BAN::MACAddress m_mac_address {};
|
BAN::MACAddress m_mac_address {};
|
||||||
bool m_link_up { false };
|
bool m_link_up { false };
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace Kernel
|
||||||
BAN::UniqPtr<VirtualRange> m_pending_packet_buffer;
|
BAN::UniqPtr<VirtualRange> m_pending_packet_buffer;
|
||||||
BAN::CircularQueue<PendingIPv4Packet, 128> m_pending_packets;
|
BAN::CircularQueue<PendingIPv4Packet, 128> m_pending_packets;
|
||||||
Semaphore m_pending_semaphore;
|
Semaphore m_pending_semaphore;
|
||||||
|
SpinLock m_pending_lock;
|
||||||
size_t m_pending_total_size { 0 };
|
size_t m_pending_total_size { 0 };
|
||||||
|
|
||||||
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
||||||
|
|
|
@ -145,24 +145,22 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
BAN::Optional<PendingArpPacket> pending;
|
PendingArpPacket pending = ({
|
||||||
|
auto state = m_pending_lock.lock();
|
||||||
{
|
while (m_pending_packets.empty())
|
||||||
CriticalScope _;
|
|
||||||
if (!m_pending_packets.empty())
|
|
||||||
{
|
{
|
||||||
pending = m_pending_packets.front();
|
m_pending_lock.unlock(state);
|
||||||
m_pending_packets.pop();
|
m_pending_semaphore.block_indefinite();
|
||||||
|
state = m_pending_lock.lock();
|
||||||
}
|
}
|
||||||
}
|
auto packet = m_pending_packets.front();
|
||||||
|
m_pending_packets.pop();
|
||||||
|
m_pending_lock.unlock(state);
|
||||||
|
|
||||||
if (!pending.has_value())
|
packet;
|
||||||
{
|
});
|
||||||
m_pending_semaphore.block_indefinite();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto ret = handle_arp_packet(pending->interface, pending->packet); ret.is_error())
|
if (auto ret = handle_arp_packet(pending.interface, pending.packet); ret.is_error())
|
||||||
dwarnln("{}", ret.error());
|
dwarnln("{}", ret.error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,6 +169,8 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto& arp_packet = buffer.as<const ARPPacket>();
|
auto& arp_packet = buffer.as<const ARPPacket>();
|
||||||
|
|
||||||
|
SpinLockGuard _(m_pending_lock);
|
||||||
|
|
||||||
if (m_pending_packets.full())
|
if (m_pending_packets.full())
|
||||||
{
|
{
|
||||||
dprintln("arp packet queue full");
|
dprintln("arp packet queue full");
|
||||||
|
|
|
@ -261,7 +261,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ASSERT_LTE(buffer.size() + sizeof(EthernetHeader), E1000_TX_BUFFER_SIZE);
|
ASSERT_LTE(buffer.size() + sizeof(EthernetHeader), E1000_TX_BUFFER_SIZE);
|
||||||
|
|
||||||
CriticalScope _;
|
SpinLockGuard _(m_lock);
|
||||||
|
|
||||||
size_t tx_current = read32(REG_TDT) % E1000_TX_DESCRIPTOR_COUNT;
|
size_t tx_current = read32(REG_TDT) % E1000_TX_DESCRIPTOR_COUNT;
|
||||||
|
|
||||||
|
@ -291,6 +291,8 @@ namespace Kernel
|
||||||
if (read32(REG_ICR) & ICR_RxQ0)
|
if (read32(REG_ICR) & ICR_RxQ0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SpinLockGuard _(m_lock);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uint32_t rx_current = (read32(REG_RDT0) + 1) % E1000_RX_DESCRIPTOR_COUNT;
|
uint32_t rx_current = (read32(REG_RDT0) + 1) % E1000_RX_DESCRIPTOR_COUNT;
|
||||||
|
|
||||||
|
|
|
@ -287,30 +287,28 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
BAN::Optional<PendingIPv4Packet> pending;
|
PendingIPv4Packet pending = ({
|
||||||
|
auto state = m_pending_lock.lock();
|
||||||
{
|
while (m_pending_packets.empty())
|
||||||
CriticalScope _;
|
|
||||||
if (!m_pending_packets.empty())
|
|
||||||
{
|
{
|
||||||
pending = m_pending_packets.front();
|
m_pending_lock.unlock(state);
|
||||||
m_pending_packets.pop();
|
m_pending_semaphore.block_indefinite();
|
||||||
|
state = m_pending_lock.lock();
|
||||||
}
|
}
|
||||||
}
|
auto packet = m_pending_packets.front();
|
||||||
|
m_pending_packets.pop();
|
||||||
|
m_pending_lock.unlock(state);
|
||||||
|
|
||||||
if (!pending.has_value())
|
packet;
|
||||||
{
|
});
|
||||||
m_pending_semaphore.block_indefinite();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* buffer_start = reinterpret_cast<uint8_t*>(m_pending_packet_buffer->vaddr());
|
uint8_t* buffer_start = reinterpret_cast<uint8_t*>(m_pending_packet_buffer->vaddr());
|
||||||
const size_t ipv4_packet_size = reinterpret_cast<const IPv4Header*>(buffer_start)->total_length;
|
const size_t ipv4_packet_size = reinterpret_cast<const IPv4Header*>(buffer_start)->total_length;
|
||||||
|
|
||||||
if (auto ret = handle_ipv4_packet(pending->interface, BAN::ByteSpan(buffer_start, ipv4_packet_size)); ret.is_error())
|
if (auto ret = handle_ipv4_packet(pending.interface, BAN::ByteSpan(buffer_start, ipv4_packet_size)); ret.is_error())
|
||||||
dwarnln("{}", ret.error());
|
dwarnln("{}", ret.error());
|
||||||
|
|
||||||
CriticalScope _;
|
SpinLockGuard _(m_pending_lock);
|
||||||
m_pending_total_size -= ipv4_packet_size;
|
m_pending_total_size -= ipv4_packet_size;
|
||||||
if (m_pending_total_size)
|
if (m_pending_total_size)
|
||||||
memmove(buffer_start, buffer_start + ipv4_packet_size, m_pending_total_size);
|
memmove(buffer_start, buffer_start + ipv4_packet_size, m_pending_total_size);
|
||||||
|
@ -319,6 +317,8 @@ namespace Kernel
|
||||||
|
|
||||||
void IPv4Layer::add_ipv4_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
void IPv4Layer::add_ipv4_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
SpinLockGuard _(m_pending_lock);
|
||||||
|
|
||||||
if (m_pending_packets.full())
|
if (m_pending_packets.full())
|
||||||
{
|
{
|
||||||
dwarnln("IPv4 packet queue full");
|
dwarnln("IPv4 packet queue full");
|
||||||
|
|
Loading…
Reference in New Issue