2cd7361294
Switch xz to memusage(2) and fix native self-cross issue. This is a compatible ABI change.
104 lines
3.3 KiB
C++
104 lines
3.3 KiB
C++
/*
|
|
* Copyright (c) 2015 Meisaka Yukara.
|
|
* Copyright (c) 2016, 2017, 2022 Jonas 'Sortie' Termansen.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* net/packet.cpp
|
|
* Reference counted network packets.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
|
|
#include <sortix/kernel/kernel.h>
|
|
#include <sortix/kernel/kthread.h>
|
|
#include <sortix/kernel/memorymanagement.h>
|
|
#include <sortix/kernel/packet.h>
|
|
#include <sortix/kernel/pci-mmio.h>
|
|
|
|
namespace Sortix {
|
|
|
|
// Limit the memory usage of network packets to this fraction of total memory.
|
|
// This constant is documented in if(4) under NOTES.
|
|
static const size_t MAX_PACKET_FRACTION = 16;
|
|
|
|
// Keep this amount of virtually mapped buffers around at all times.
|
|
// This constant is documented in if(4) under NOTES.
|
|
static const size_t PACKET_CACHE_TARGET_SIZE = 384;
|
|
|
|
// A cache of physical memory allocations for quick allocation to new packets.
|
|
static kthread_mutex_t packet_cache_lock = KTHREAD_MUTEX_INITIALIZER;
|
|
static paddrmapped_t* packet_cache = NULL;
|
|
static size_t packet_cache_used = 0;
|
|
static size_t packet_cache_allocated = 0;
|
|
static size_t packet_count = 0;
|
|
|
|
Packet::Packet(paddrmapped_t _pmap) : pmap(_pmap)
|
|
{
|
|
from = (unsigned char*) pmap.from;
|
|
length = 0;
|
|
offset = 0;
|
|
netif = NULL;
|
|
packet_count++;
|
|
}
|
|
|
|
Packet::~Packet()
|
|
{
|
|
// Refuse to do recursive destructor calls that could stack overflow.
|
|
assert(!next);
|
|
ScopedLock lock(&packet_cache_lock);
|
|
if ( packet_cache_used < packet_cache_allocated )
|
|
packet_cache[packet_cache_used++] = pmap;
|
|
else
|
|
FreeAllocatedAndMappedPage(&pmap);
|
|
packet_count--;
|
|
}
|
|
|
|
Ref<Packet> GetPacket()
|
|
{
|
|
ScopedLock lock(&packet_cache_lock);
|
|
if ( packet_cache == NULL )
|
|
{
|
|
size_t new_allocated = PACKET_CACHE_TARGET_SIZE;
|
|
packet_cache = new paddrmapped_t[new_allocated];
|
|
if ( !packet_cache )
|
|
return errno = ENOBUFS, Ref<Packet>(NULL);
|
|
packet_cache_allocated = new_allocated;
|
|
}
|
|
paddrmapped_t pmap;
|
|
// Fast reuse of an existing physical allocation if available.
|
|
if ( 0 < packet_cache_used )
|
|
pmap = packet_cache[--packet_cache_used];
|
|
// Otherwise make a new physical allocation for the packet.
|
|
else
|
|
{
|
|
size_t total_memory;
|
|
Memory::Statistics(NULL, &total_memory, NULL);
|
|
size_t total_pages = total_memory / Page::Size();
|
|
size_t max_packets = total_pages / MAX_PACKET_FRACTION;
|
|
if ( max_packets <= packet_count )
|
|
return errno = ENOBUFS, Ref<Packet>(NULL);
|
|
if ( !AllocateAndMapPage(&pmap, PAGE_USAGE_NETWORK_PACKET) )
|
|
return errno = ENOBUFS, Ref<Packet>(NULL);
|
|
}
|
|
Ref<Packet> pkt = Ref<Packet>(new Packet(pmap));
|
|
if ( !pkt )
|
|
{
|
|
FreeAllocatedAndMappedPage(&pmap);
|
|
return errno = ENOBUFS, Ref<Packet>(NULL);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
} // namespace Sortix
|