Kernel: Replace CriticalScopes with SpinLocks in networking code
This commit is contained in:
parent
7f028f70d5
commit
90878a7c2b
|
@ -52,6 +52,7 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
SpinLock m_table_lock;
|
||||
SpinLock m_pending_lock;
|
||||
|
||||
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_rx_descriptor_region;
|
||||
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
||||
SpinLock m_lock;
|
||||
|
||||
BAN::MACAddress m_mac_address {};
|
||||
bool m_link_up { false };
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace Kernel
|
|||
BAN::UniqPtr<VirtualRange> m_pending_packet_buffer;
|
||||
BAN::CircularQueue<PendingIPv4Packet, 128> m_pending_packets;
|
||||
Semaphore m_pending_semaphore;
|
||||
SpinLock m_pending_lock;
|
||||
size_t m_pending_total_size { 0 };
|
||||
|
||||
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
||||
|
|
|
@ -145,24 +145,22 @@ namespace Kernel
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
BAN::Optional<PendingArpPacket> pending;
|
||||
|
||||
{
|
||||
CriticalScope _;
|
||||
if (!m_pending_packets.empty())
|
||||
PendingArpPacket pending = ({
|
||||
auto state = m_pending_lock.lock();
|
||||
while (m_pending_packets.empty())
|
||||
{
|
||||
pending = m_pending_packets.front();
|
||||
m_pending_packets.pop();
|
||||
m_pending_lock.unlock(state);
|
||||
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())
|
||||
{
|
||||
m_pending_semaphore.block_indefinite();
|
||||
continue;
|
||||
}
|
||||
packet;
|
||||
});
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +169,8 @@ namespace Kernel
|
|||
{
|
||||
auto& arp_packet = buffer.as<const ARPPacket>();
|
||||
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
|
||||
if (m_pending_packets.full())
|
||||
{
|
||||
dprintln("arp packet queue full");
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace Kernel
|
|||
{
|
||||
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;
|
||||
|
||||
|
@ -291,6 +291,8 @@ namespace Kernel
|
|||
if (read32(REG_ICR) & ICR_RxQ0)
|
||||
return;
|
||||
|
||||
SpinLockGuard _(m_lock);
|
||||
|
||||
for (;;) {
|
||||
uint32_t rx_current = (read32(REG_RDT0) + 1) % E1000_RX_DESCRIPTOR_COUNT;
|
||||
|
||||
|
|
|
@ -287,30 +287,28 @@ namespace Kernel
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
BAN::Optional<PendingIPv4Packet> pending;
|
||||
|
||||
{
|
||||
CriticalScope _;
|
||||
if (!m_pending_packets.empty())
|
||||
PendingIPv4Packet pending = ({
|
||||
auto state = m_pending_lock.lock();
|
||||
while (m_pending_packets.empty())
|
||||
{
|
||||
pending = m_pending_packets.front();
|
||||
m_pending_packets.pop();
|
||||
m_pending_lock.unlock(state);
|
||||
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())
|
||||
{
|
||||
m_pending_semaphore.block_indefinite();
|
||||
continue;
|
||||
}
|
||||
packet;
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
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());
|
||||
|
||||
CriticalScope _;
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
m_pending_total_size -= ipv4_packet_size;
|
||||
if (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)
|
||||
{
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
|
||||
if (m_pending_packets.full())
|
||||
{
|
||||
dwarnln("IPv4 packet queue full");
|
||||
|
|
Loading…
Reference in New Issue