[kernel] Replace buffer_cache with vm_area_buffers

In order to reduce the amount of tracked state, now use the
vm_area_buffers instead of a VMA with buffer_cache on top.
This commit is contained in:
2020-09-27 15:34:24 -07:00
parent 67ebc58812
commit f7f8bb3f45
14 changed files with 161 additions and 120 deletions

View File

@@ -1,16 +1,16 @@
#include "kutil/assert.h"
#include "buffer_cache.h"
#include "kernel_memory.h"
#include "objects/channel.h"
#include "objects/vm_area.h"
using memory::frame_size;
using memory::kernel_buffer_pages;
static constexpr size_t buffer_bytes = kernel_buffer_pages * frame_size;
extern vm_area_buffers g_kernel_buffers;
constexpr size_t buffer_bytes = memory::kernel_buffer_pages * memory::frame_size;
channel::channel() :
m_len(0),
m_data(g_kbuffer_cache.get_buffer()),
m_data(g_kernel_buffers.get_buffer()),
m_buffer(reinterpret_cast<uint8_t*>(m_data), buffer_bytes),
kobject(kobject::type::channel, j6_signal_channel_can_send)
{
@@ -78,7 +78,7 @@ channel::dequeue(size_t *len, void *data)
void
channel::close()
{
g_kbuffer_cache.return_buffer(m_data);
g_kernel_buffers.return_buffer(m_data);
assert_signal(j6_signal_channel_closed);
}

View File

@@ -4,6 +4,7 @@
#include "cpu.h"
#include "objects/process.h"
#include "objects/thread.h"
#include "objects/vm_area.h"
// This object is initialized _before_ global constructors are called,
// so we don't want it to have a global constructor at all, lest it
@@ -94,7 +95,11 @@ process::create_thread(uint8_t priority, bool user)
if (user) {
uintptr_t stack_top = stacks_top - (m_threads.count() * stack_size);
m_space.allow(stack_top - stack_size, stack_size, true);
vm_area *vma = new vm_area_open(stack_size, m_space,
vm_flags::zero|vm_flags::write);
m_space.add(stack_top - stack_size, vma);
th->tcb()->rsp3 = stack_top;
}

View File

@@ -3,12 +3,14 @@
#include "log.h"
#include "objects/thread.h"
#include "objects/process.h"
#include "objects/vm_area.h"
#include "scheduler.h"
#include "buffer_cache.h"
extern "C" void kernel_to_user_trampoline();
static constexpr j6_signal_t thread_default_signals = 0;
extern vm_area_buffers g_kernel_stacks;
thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) :
kobject(kobject::type::thread, thread_default_signals),
m_parent(parent),
@@ -30,7 +32,7 @@ thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) :
thread::~thread()
{
g_kstack_cache.return_buffer(m_tcb.kernel_stack);
g_kernel_stacks.return_buffer(m_tcb.kernel_stack);
}
thread *
@@ -179,7 +181,7 @@ thread::setup_kernel_stack()
constexpr unsigned null_frame_entries = 2;
constexpr size_t null_frame_size = null_frame_entries * sizeof(uint64_t);
uintptr_t stack_addr = g_kstack_cache.get_buffer();
uintptr_t stack_addr = g_kernel_stacks.get_buffer();
uintptr_t stack_end = stack_addr + stack_bytes;
uint64_t *null_frame = reinterpret_cast<uint64_t*>(stack_end - null_frame_size);

View File

@@ -211,3 +211,51 @@ vm_area_open::uncommit(uintptr_t offset, size_t count)
m_mapper.unmap(offset, count);
}
vm_area_buffers::vm_area_buffers(size_t size, vm_space &space, vm_flags flags, size_t buf_pages) :
m_mapper {*this, space},
m_pages {buf_pages},
m_next {memory::frame_size},
vm_area {size, flags}
{
}
uintptr_t
vm_area_buffers::get_buffer()
{
if (m_cache.count() > 0) {
return m_cache.pop();
}
uintptr_t addr = m_next;
m_next += (m_pages + 1) * memory::frame_size;
return m_mapper.space().lookup(*this, addr);
}
void
vm_area_buffers::return_buffer(uintptr_t addr)
{
m_cache.append(addr);
}
bool
vm_area_buffers::allowed(uintptr_t offset) const
{
if (offset >= m_next) return false;
// Buffers are m_pages big plus 1 leading guard page
return memory::page_align_down(offset) % (m_pages+1);
}
void
vm_area_buffers::commit(uintptr_t phys, uintptr_t offset, size_t count)
{
m_mapper.map(offset, count, phys);
}
void
vm_area_buffers::uncommit(uintptr_t offset, size_t count)
{
m_mapper.unmap(offset, count);
}

View File

@@ -124,8 +124,9 @@ private:
kutil::vector<mapping> m_mappings;
};
/// Area split into standard-sized segments
class vm_area_buffers :
/// Area that allows open allocation (eg, kernel heap)
class vm_area_open :
public vm_area
{
public:
@@ -133,7 +134,40 @@ public:
/// \arg size Initial virtual size of the memory area
/// \arg space The address space this area belongs to
/// \arg flags Flags for this memory area
vm_area_buffers(size_t size, vm_space &space, vm_flags flags);
vm_area_open(size_t size, vm_space &space, vm_flags flags);
virtual vm_mapper & mapper() override { return m_mapper; }
virtual const vm_mapper & mapper() const override { return m_mapper; }
virtual void commit(uintptr_t phys, uintptr_t offset, size_t count) override;
virtual void uncommit(uintptr_t offset, size_t count) override;
private:
vm_mapper_single m_mapper;
};
/// Area split into standard-sized segments
class vm_area_buffers :
public vm_area
{
public:
/// Constructor.
/// \arg size Initial virtual size of the memory area
/// \arg space The address space this area belongs to
/// \arg flags Flags for this memory area
/// \arg buf_pages Pages in an individual buffer
vm_area_buffers(
size_t size,
vm_space &space,
vm_flags flags,
size_t buf_pages);
/// Get an available stack address
uintptr_t get_buffer();
/// Return a buffer address to the available pool
void return_buffer(uintptr_t addr);
virtual vm_mapper & mapper() override { return m_mapper; }
virtual const vm_mapper & mapper() const override { return m_mapper; }
@@ -144,6 +178,9 @@ public:
private:
vm_mapper_single m_mapper;
kutil::vector<uintptr_t> m_cache;
size_t m_pages;
uintptr_t m_next;
};
@@ -167,26 +204,4 @@ private:
vm_mapper_multi m_mapper;
};
/// Area that allows open allocation (eg, kernel heap)
class vm_area_open :
public vm_area
{
public:
/// Constructor.
/// \arg size Initial virtual size of the memory area
/// \arg space The address space this area belongs to
/// \arg flags Flags for this memory area
vm_area_open(size_t size, vm_space &space, vm_flags flags);
virtual vm_mapper & mapper() override { return m_mapper; }
virtual const vm_mapper & mapper() const override { return m_mapper; }
virtual void commit(uintptr_t phys, uintptr_t offset, size_t count) override;
virtual void uncommit(uintptr_t offset, size_t count) override;
private:
vm_mapper_single m_mapper;
};
IS_BITFIELD(vm_flags);