Update XiZi_AIoT Kernel from tuyuyang
it is OK
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
#include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
ifneq ($(findstring $(BOARD), ok1028a-c), )
|
||||
ifneq ($(findstring $(BOARD), 3568), )
|
||||
SRC_FILES := kalloc.c pagetable.c pagetable_level3.c buddy.c object_allocator.c share_page.c
|
||||
endif
|
||||
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
|
||||
|
||||
@@ -31,6 +31,7 @@ Modification:
|
||||
#include "buddy.h"
|
||||
#include "kalloc.h"
|
||||
#include "log.h"
|
||||
#include "pagetable.h"
|
||||
|
||||
static void _buddy_split_page(struct KPage* page, uintptr_t low_order, uintptr_t high_order, struct KFreeList* list)
|
||||
{
|
||||
@@ -166,7 +167,8 @@ bool KBuddyInit(struct KBuddy* pbuddy, uintptr_t mem_start, uintptr_t mem_end)
|
||||
// total number of free pages
|
||||
pbuddy->n_pages = (pbuddy->mem_end - (uintptr_t)pbuddy->mem_start) >> LEVEL4_PTE_SHIFT;
|
||||
|
||||
memset(pbuddy->pages, 0, pbuddy->n_pages);
|
||||
memset(pbuddy->pages, 0, pbuddy->n_pages * sizeof(struct KPage));
|
||||
// memset(pbuddy->pages, 0, pbuddy->n_pages);
|
||||
|
||||
// init each free page list from 2^0 to 2^8
|
||||
for (; i < MAX_BUDDY_ORDER; i++) {
|
||||
|
||||
@@ -30,6 +30,9 @@ Modification:
|
||||
#include "kalloc.h"
|
||||
#include "assert.h"
|
||||
|
||||
#include "memlayout.h"
|
||||
#include "pagetable.h"
|
||||
|
||||
#include "actracer.h"
|
||||
#include "buddy.h"
|
||||
|
||||
@@ -43,12 +46,13 @@ bool module_phymem_init()
|
||||
uintptr_t kern_freemem_end = PHY_USER_FREEMEM_BASE;
|
||||
uintptr_t user_freemem_start = PHY_USER_FREEMEM_BASE;
|
||||
uintptr_t user_freemem_end = PHY_MEM_STOP;
|
||||
user_phy_freemem_buddy.pages = NULL;
|
||||
KBuddySysInit(&kern_virtmem_buddy, kern_freemem_start, kern_freemem_end);
|
||||
KBuddyInit(&user_phy_freemem_buddy, user_freemem_start, user_freemem_end);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* kalloc(size_t size)
|
||||
char* kalloc(uintptr_t size)
|
||||
{
|
||||
char* mem_alloc = KBuddyAlloc(&kern_virtmem_buddy, size);
|
||||
if (mem_alloc == NULL) {
|
||||
@@ -63,11 +67,42 @@ char* kalloc(size_t size)
|
||||
return mem_alloc;
|
||||
}
|
||||
|
||||
void* kalloc_by_ownership(TraceTag owner, uintptr_t size)
|
||||
{
|
||||
void* new_mem = kalloc(size);
|
||||
if (NULL == new_mem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
|
||||
if (0 != rbt_insert(&usage->mem_block_map, (uintptr_t)new_mem, NULL)) {
|
||||
kfree(new_mem);
|
||||
return NULL;
|
||||
}
|
||||
return new_mem;
|
||||
}
|
||||
|
||||
bool kfree(char* vaddr)
|
||||
{
|
||||
return KBuddyFree(&kern_virtmem_buddy, V2P_WO(vaddr));
|
||||
}
|
||||
|
||||
bool kfree_by_ownership(TraceTag owner, void* vaddr)
|
||||
{
|
||||
struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
|
||||
// DEBUG("%p %p %p %p\n", usage, usage->mem_block_root, usage->tag, vaddr);
|
||||
RbtNode* node = rbt_search(&usage->mem_block_map, (uintptr_t)vaddr);
|
||||
assert(NULL != node);
|
||||
assert(0 == rbt_delete(&usage->mem_block_map, node->key));
|
||||
|
||||
return kfree(vaddr);
|
||||
}
|
||||
|
||||
bool raw_kfree(char* paddr)
|
||||
{
|
||||
return KBuddyFree(&kern_virtmem_buddy, paddr);
|
||||
}
|
||||
|
||||
char* raw_alloc(size_t size)
|
||||
{
|
||||
char* mem_alloc = KBuddyAlloc(&user_phy_freemem_buddy, size);
|
||||
@@ -77,11 +112,36 @@ char* raw_alloc(size_t size)
|
||||
return mem_alloc;
|
||||
}
|
||||
|
||||
void* raw_alloc_by_ownership(TraceTag owner, uintptr_t size)
|
||||
{
|
||||
void* new_mem = raw_alloc(size);
|
||||
if (!new_mem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
|
||||
if (0 != rbt_insert(&usage->mem_block_map, (uintptr_t)new_mem, NULL)) {
|
||||
raw_free(new_mem);
|
||||
return NULL;
|
||||
}
|
||||
return new_mem;
|
||||
}
|
||||
|
||||
bool raw_free(char* paddr)
|
||||
{
|
||||
return KBuddyFree(&user_phy_freemem_buddy, paddr);
|
||||
}
|
||||
|
||||
bool raw_free_by_ownership(TraceTag owner, void* vaddr)
|
||||
{
|
||||
struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
|
||||
RbtNode* node = rbt_search(&usage->mem_block_map, (uintptr_t)vaddr);
|
||||
assert(NULL != node);
|
||||
assert(0 == rbt_delete(&usage->mem_block_map, node->key));
|
||||
|
||||
return raw_free(vaddr);
|
||||
}
|
||||
|
||||
void show_phymem_info()
|
||||
{
|
||||
KFreePagesInfo(&user_phy_freemem_buddy);
|
||||
|
||||
@@ -32,6 +32,7 @@ Modification:
|
||||
#include "assert.h"
|
||||
#include "kalloc.h"
|
||||
#include "object_allocator.h"
|
||||
#include "pagetable.h"
|
||||
|
||||
#define BITMAP_BITS_EMPTY_FULL ((uint64_t)0)
|
||||
#define BITMAP_FIRST_BIT ((uint64_t)1)
|
||||
@@ -44,10 +45,10 @@ Modification:
|
||||
#define LOWLEVEL_ALLOC(size) kalloc(size)
|
||||
#define LOWLEVEL_FREE(ptr) kfree(ptr)
|
||||
|
||||
#define ARENA_SIZE_PER_INCREASE PAGE_SIZE
|
||||
#define ARENA_SIZE_PER_INCREASE (2 * PAGE_SIZE)
|
||||
#define MAX_NR_ELEMENT_PER_SLABPAGE 64
|
||||
|
||||
void slab_init(struct slab_allocator* const allocator, const size_t element_size)
|
||||
void slab_init(struct slab_allocator* const allocator, const size_t element_size, char* name)
|
||||
{
|
||||
if (allocator == NULL) {
|
||||
panic("init a NULL slab_allocator\n");
|
||||
@@ -63,8 +64,11 @@ void slab_init(struct slab_allocator* const allocator, const size_t element_size
|
||||
allocator->nr_elements = allocator->nr_elements > MAX_NR_ELEMENT_PER_SLABPAGE ? MAX_NR_ELEMENT_PER_SLABPAGE : allocator->nr_elements;
|
||||
|
||||
allocator->bitmap_empty = ~BITMAP_BITS_EMPTY_FULL >> (MAX_NR_ELEMENT_PER_SLABPAGE - allocator->nr_elements);
|
||||
|
||||
allocator->partial = allocator->empty = allocator->full = NULL;
|
||||
|
||||
if (name) {
|
||||
allocator->name = name;
|
||||
}
|
||||
}
|
||||
|
||||
void* slab_alloc(struct slab_allocator* const allocator)
|
||||
@@ -107,7 +111,7 @@ void* slab_alloc(struct slab_allocator* const allocator)
|
||||
/* achieve slab from outer arena */
|
||||
allocator->partial = (struct slab_state*)LOWLEVEL_ALLOC(allocator->slabsize);
|
||||
if (UNLIKELY(allocator->partial == NULL)) {
|
||||
ERROR("no enough memory\n");
|
||||
ERROR("slab %s: no enough memory\n", allocator->name);
|
||||
return allocator->partial = NULL;
|
||||
}
|
||||
allocator->partial->prev = allocator->partial->next = NULL;
|
||||
|
||||
@@ -51,7 +51,7 @@ static bool _new_pgdir(struct TopLevelPageDirectory* pgdir)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _map_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr)
|
||||
static bool _map_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, intptr_t len, uintptr_t attr)
|
||||
{
|
||||
assert(len >= 0);
|
||||
vaddr = ALIGNDOWN(vaddr, LEVEL4_PTE_SIZE);
|
||||
@@ -61,12 +61,12 @@ static bool _map_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, int l
|
||||
while (true) {
|
||||
uintptr_t* pte = NULL;
|
||||
if ((pte = _page_walk(pgdir, vaddr, true)) == NULL) {
|
||||
ERROR("pte not found for vaddr %x.\n", vaddr);
|
||||
ERROR("pte not found for vaddr %p.\n", vaddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UNLIKELY(*pte != 0)) {
|
||||
ERROR("remapping: vaddr: %x | paddr: %x | pte: %x |\n", vaddr, paddr, *pte);
|
||||
ERROR("remapping: vaddr: %p | paddr: %p | pte: %p |\n", vaddr, paddr, *pte);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -93,12 +93,12 @@ static bool _unmap_pages(uintptr_t* pgdir, uintptr_t vaddr, int len)
|
||||
while (true) {
|
||||
uintptr_t* pte = NULL;
|
||||
if ((pte = _page_walk(pgdir, vaddr, false)) == NULL) {
|
||||
ERROR("pte not found for vaddr %x.\n", vaddr);
|
||||
ERROR("pte not found for vaddr %p.\n", vaddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*pte == 0) {
|
||||
ERROR("unmap a unmapped page, vaddr: %x, pte: %x\n", vaddr, *pte);
|
||||
ERROR("unmap a unmapped page, vaddr: %p, pte: %p\n", vaddr, *pte);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ static bool _unmap_pages(uintptr_t* pgdir, uintptr_t vaddr, int len)
|
||||
/// @param len
|
||||
/// @param is_dev
|
||||
/// @return
|
||||
static bool _map_user_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev)
|
||||
static bool _map_user_pages(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev)
|
||||
{
|
||||
if (len < 0) {
|
||||
return false;
|
||||
@@ -140,13 +140,27 @@ static bool _map_user_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr,
|
||||
_p_pgtbl_mmu_access->MmuUsrDevPteAttr(&mem_attr);
|
||||
}
|
||||
|
||||
return _map_pages(pgdir, vaddr, paddr, len, mem_attr);
|
||||
return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, mem_attr);
|
||||
}
|
||||
|
||||
bool _map_customizable_page(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr)
|
||||
{
|
||||
if (len < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UNLIKELY(vaddr >= USER_MEM_TOP)) {
|
||||
ERROR("mapping kernel space.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, attr);
|
||||
}
|
||||
|
||||
/// assume that a user pagedir is allocated from [0, size)
|
||||
/// if new_size > old_size, allocate more space,
|
||||
/// if old_size > new_size, free extra space, to avoid unnecessary alloc/free.
|
||||
static uintptr_t _resize_user_pgdir(struct TopLevelPageDirectory* pgdir, uintptr_t old_size, uintptr_t new_size)
|
||||
static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_size, uintptr_t new_size)
|
||||
{
|
||||
if (UNLIKELY(new_size > USER_MEM_TOP)) {
|
||||
ERROR("user size out of range.\n");
|
||||
@@ -158,19 +172,17 @@ static uintptr_t _resize_user_pgdir(struct TopLevelPageDirectory* pgdir, uintptr
|
||||
}
|
||||
|
||||
uintptr_t cur_size = ALIGNUP(old_size, PAGE_SIZE);
|
||||
uintptr_t size_needed = ALIGNUP(new_size, PAGE_SIZE) - cur_size;
|
||||
|
||||
while (cur_size < new_size) {
|
||||
char* new_page = kalloc(PAGE_SIZE);
|
||||
if (new_page == NULL) {
|
||||
ERROR("No memory\n");
|
||||
return cur_size;
|
||||
}
|
||||
memset(new_page, 0, PAGE_SIZE);
|
||||
|
||||
if (!xizi_pager.map_pages(pgdir->pd_addr, cur_size, V2P(new_page), PAGE_SIZE, false)) {
|
||||
return cur_size;
|
||||
}
|
||||
cur_size += PAGE_SIZE;
|
||||
// char* new_page = kalloc(size_needed);
|
||||
char* new_page = kalloc_by_ownership(pmemspace->kernspace_mem_usage.tag, size_needed);
|
||||
if (new_page == NULL) {
|
||||
ERROR("No memory\n");
|
||||
return cur_size;
|
||||
}
|
||||
memset(new_page, 0, size_needed);
|
||||
if (!xizi_pager.map_pages(pmemspace, cur_size, V2P(new_page), size_needed, false)) {
|
||||
return cur_size;
|
||||
}
|
||||
|
||||
return new_size;
|
||||
@@ -269,7 +281,7 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv
|
||||
// kern mem
|
||||
_map_pages((uintptr_t*)kern_pgdir.pd_addr, KERN_MEM_BASE, PHY_MEM_BASE, (PHY_MEM_STOP - PHY_MEM_BASE), kern_attr);
|
||||
// dev mem
|
||||
_map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SZ, dev_attr);
|
||||
_map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SIZE, dev_attr);
|
||||
|
||||
_p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr));
|
||||
}
|
||||
|
||||
@@ -65,31 +65,12 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
|
||||
|
||||
void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
|
||||
{
|
||||
uintptr_t low_bound = kern_virtmem_buddy.mem_start, high_bound = kern_virtmem_buddy.mem_end;
|
||||
uintptr_t user_low_bound = user_phy_freemem_buddy.mem_start, user_high_bound = user_phy_freemem_buddy.mem_end;
|
||||
uintptr_t end_idx = USER_MEM_TOP >> LEVEL3_PDE_SHIFT;
|
||||
|
||||
for (uintptr_t level4_entry_idx = 0; level4_entry_idx < end_idx; level4_entry_idx++) {
|
||||
// free each level4 page table
|
||||
uintptr_t* pgtbl_paddr = (uintptr_t*)LEVEL4_PTE_ADDR(pgdir->pd_addr[level4_entry_idx]);
|
||||
if (pgtbl_paddr != NULL) {
|
||||
// free each page
|
||||
for (uintptr_t page_entry_idx = 0; page_entry_idx < NUM_LEVEL4_PTE; page_entry_idx++) {
|
||||
uintptr_t vaddr = (level4_entry_idx << LEVEL3_PDE_SHIFT) | (page_entry_idx << LEVEL4_PTE_SHIFT);
|
||||
|
||||
// get page paddr
|
||||
uintptr_t* page_paddr = (uintptr_t*)ALIGNDOWN(((uintptr_t*)P2V(pgtbl_paddr))[page_entry_idx], PAGE_SIZE);
|
||||
if (page_paddr != NULL) {
|
||||
// IPC vaddr should not be addressed here.
|
||||
assert(vaddr < USER_IPC_SPACE_BASE || vaddr >= USER_IPC_SPACE_TOP);
|
||||
|
||||
if (LIKELY((uintptr_t)page_paddr >= low_bound && (uintptr_t)page_paddr < high_bound)) {
|
||||
kfree(P2V(page_paddr));
|
||||
} else if (LIKELY((uintptr_t)page_paddr >= user_low_bound && (uintptr_t)page_paddr < user_high_bound)) {
|
||||
raw_free((char*)page_paddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
kfree(P2V(pgtbl_paddr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
|
||||
|
||||
uintptr_t* l3_pde_vaddr;
|
||||
if (*l2_pde_ptr != 0) {
|
||||
uintptr_t l3_table_paddr = (*l2_pde_ptr) & ~pde_attr;
|
||||
uintptr_t l3_table_paddr = ALIGNDOWN(*l2_pde_ptr, PAGE_SIZE);
|
||||
l3_pde_vaddr = (uintptr_t*)P2V(l3_table_paddr);
|
||||
} else {
|
||||
if (!alloc || !(l3_pde_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL3_PDE))) {
|
||||
@@ -63,7 +63,7 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
|
||||
|
||||
uintptr_t* l4_pte_vaddr;
|
||||
if (*l3_pde_ptr != 0) {
|
||||
uintptr_t l4_table_paddr = (*l3_pde_ptr) & ~pde_attr;
|
||||
uintptr_t l4_table_paddr = ALIGNDOWN(*l3_pde_ptr, PAGE_SIZE);
|
||||
l4_pte_vaddr = (uintptr_t*)P2V(l4_table_paddr);
|
||||
} else {
|
||||
if (!alloc || !(l4_pte_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL4_PTE))) {
|
||||
@@ -83,8 +83,6 @@ void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
|
||||
return;
|
||||
}
|
||||
|
||||
uintptr_t low_bound = kern_virtmem_buddy.mem_start, high_bound = kern_virtmem_buddy.mem_end;
|
||||
uintptr_t user_low_bound = user_phy_freemem_buddy.mem_start, user_high_bound = user_phy_freemem_buddy.mem_end;
|
||||
uintptr_t end_idx = (USER_MEM_TOP >> LEVEL2_PDE_SHIFT) & (NUM_LEVEL2_PDE - 1);
|
||||
|
||||
for (uintptr_t l2_entry_idx = 0; l2_entry_idx < end_idx; l2_entry_idx++) {
|
||||
@@ -95,23 +93,6 @@ void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
|
||||
for (uintptr_t l3_entry_idx = 0; l3_entry_idx < NUM_LEVEL3_PDE; l3_entry_idx++) {
|
||||
uintptr_t* l4_table_paddr = (uintptr_t*)LEVEL4_PTE_ADDR(l3_table_vaddr[l3_entry_idx]);
|
||||
if (l4_table_paddr != NULL) {
|
||||
uintptr_t* l4_table_vaddr = P2V(l4_table_paddr);
|
||||
for (uintptr_t page_entry_idx = 0; page_entry_idx < NUM_LEVEL4_PTE; page_entry_idx++) {
|
||||
uintptr_t vaddr = (l2_entry_idx << LEVEL2_PDE_SHIFT) | (l3_entry_idx << LEVEL3_PDE_SHIFT) | (page_entry_idx << LEVEL4_PTE_SHIFT);
|
||||
|
||||
// get page paddr
|
||||
uintptr_t* page_paddr = (uintptr_t*)ALIGNDOWN((l4_table_vaddr)[page_entry_idx], PAGE_SIZE);
|
||||
if (page_paddr != NULL) {
|
||||
// Ensure the virtual address is not in the IPC address space
|
||||
assert(vaddr < USER_IPC_SPACE_BASE || vaddr >= USER_IPC_SPACE_TOP);
|
||||
|
||||
if (LIKELY((uintptr_t)page_paddr >= low_bound && (uintptr_t)page_paddr < high_bound)) {
|
||||
kfree(P2V(page_paddr));
|
||||
} else if (LIKELY((uintptr_t)page_paddr >= user_low_bound && (uintptr_t)page_paddr < user_high_bound)) {
|
||||
raw_free((char*)page_paddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
kfree(P2V(l4_table_paddr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ static struct slab_allocator* SessionAllocator()
|
||||
static bool init = false;
|
||||
static struct slab_allocator session_slab;
|
||||
if (!init) {
|
||||
slab_init(&session_slab, sizeof(struct session_backend));
|
||||
slab_init(&session_slab, sizeof(struct session_backend), "SessionAllocator");
|
||||
}
|
||||
return &session_slab;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ static uintptr_t map_task_share_page(struct Thread* task, const uintptr_t paddr,
|
||||
vaddr = alloc_share_page_addr(task, nr_pages * 2);
|
||||
|
||||
// time to use buddy
|
||||
if (vaddr >= USER_IPC_USE_ALLOCATOR_WATERMARK) {
|
||||
if (vaddr + (2 * nr_pages * PAGE_SIZE) >= USER_IPC_USE_ALLOCATOR_WATERMARK) {
|
||||
task->memspace->massive_ipc_allocator = (struct KBuddy*)slab_alloc(&xizi_task_manager.task_buddy_allocator);
|
||||
if (!task->memspace->massive_ipc_allocator) {
|
||||
ERROR("Alloc task buddy failed.\n");
|
||||
@@ -133,12 +133,12 @@ static uintptr_t map_task_share_page(struct Thread* task, const uintptr_t paddr,
|
||||
}
|
||||
|
||||
// map first area
|
||||
if (!xizi_pager.map_pages(task->memspace->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false)) {
|
||||
if (!xizi_pager.map_pages(task->memspace, vaddr, paddr, nr_pages * PAGE_SIZE, false)) {
|
||||
return (uintptr_t)NULL;
|
||||
}
|
||||
|
||||
// map second area
|
||||
if (!xizi_pager.map_pages(task->memspace->pgdir.pd_addr, vaddr + (nr_pages * PAGE_SIZE), paddr, nr_pages * PAGE_SIZE, false)) {
|
||||
if (!xizi_pager.map_pages(task->memspace, vaddr + (nr_pages * PAGE_SIZE), paddr, nr_pages * PAGE_SIZE, false)) {
|
||||
xizi_pager.unmap_pages(task->memspace->pgdir.pd_addr, vaddr, nr_pages * PAGE_SIZE);
|
||||
return (uintptr_t)NULL;
|
||||
}
|
||||
@@ -161,9 +161,9 @@ uintptr_t task_map_pages(struct Thread* task, const uintptr_t vaddr, const uintp
|
||||
|
||||
bool ret = false;
|
||||
if (is_dev) {
|
||||
ret = xizi_pager.map_pages(task->memspace->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, true);
|
||||
ret = xizi_pager.map_pages(task->memspace, vaddr, paddr, nr_pages * PAGE_SIZE, true);
|
||||
} else {
|
||||
ret = xizi_pager.map_pages(task->memspace->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false);
|
||||
ret = xizi_pager.map_pages(task->memspace, vaddr, paddr, nr_pages * PAGE_SIZE, false);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@@ -207,11 +207,34 @@ void unmap_task_share_pages(struct Thread* task, const uintptr_t task_vaddr, con
|
||||
static int next_session_id = 1;
|
||||
struct session_backend* create_share_pages(struct Thread* client, struct Thread* server, const int capacity)
|
||||
{
|
||||
|
||||
/* alloc session backend */
|
||||
struct session_backend* session_backend = (struct session_backend*)slab_alloc(SessionAllocator());
|
||||
if (UNLIKELY(session_backend == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
session_backend->session_id = next_session_id++;
|
||||
|
||||
if (0 != rbt_insert(&client->cli_sess_map, session_backend->session_id, &session_backend->client_side)) {
|
||||
DEBUG("Rbt of %s no memory\n", client->name);
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != rbt_insert(&server->svr_sess_map, session_backend->session_id, &session_backend->server_side)) {
|
||||
DEBUG("Rbt of %s no memory\n", server->name);
|
||||
rbt_delete(&client->cli_sess_map, session_backend->session_id);
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sem_id_t new_sem_id = ksemaphore_alloc(&xizi_task_manager.semaphore_pool, 0);
|
||||
if (new_sem_id == INVALID_SEM_ID) {
|
||||
ERROR("No memory to alloc sem\n");
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
return NULL;
|
||||
}
|
||||
session_backend->client_sem_to_wait = new_sem_id;
|
||||
|
||||
int true_capacity = ALIGNUP(capacity, PAGE_SIZE);
|
||||
int nr_pages = true_capacity / PAGE_SIZE;
|
||||
@@ -220,6 +243,7 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
|
||||
if (UNLIKELY(kern_vaddr == (uintptr_t)NULL)) {
|
||||
ERROR("No memory for session\n");
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -229,6 +253,7 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
|
||||
if (UNLIKELY(client_vaddr == (uintptr_t)NULL)) {
|
||||
kfree((char*)kern_vaddr);
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -238,11 +263,11 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
|
||||
unmap_task_share_pages(client, client_vaddr, nr_pages);
|
||||
kfree((char*)kern_vaddr);
|
||||
slab_free(SessionAllocator(), session_backend);
|
||||
ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* build session_backend */
|
||||
session_backend->session_id = next_session_id++;
|
||||
session_backend->buf_kernel_addr = kern_vaddr;
|
||||
session_backend->nr_pages = nr_pages;
|
||||
session_backend->client = client;
|
||||
@@ -286,24 +311,39 @@ int delete_share_pages(struct session_backend* session_backend)
|
||||
// close ssesion in server's perspective
|
||||
if (session_backend->server_side.closed && session_backend->server != NULL) {
|
||||
xizi_share_page_manager.unmap_task_share_pages(session_backend->server, session_backend->server_side.buf_addr, session_backend->nr_pages);
|
||||
doubleListDel(&session_backend->server_side.node);
|
||||
session_backend->server->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
|
||||
session_backend->server = NULL;
|
||||
|
||||
ERROR_FREE
|
||||
{
|
||||
assert(0 == rbt_delete(&session_backend->server->svr_sess_map, session_backend->session_id));
|
||||
doubleListDel(&session_backend->server_side.node);
|
||||
session_backend->server->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
|
||||
session_backend->server = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// close ssesion in client's perspective
|
||||
if (session_backend->client_side.closed && session_backend->client != NULL) {
|
||||
xizi_share_page_manager.unmap_task_share_pages(session_backend->client, session_backend->client_side.buf_addr, session_backend->nr_pages);
|
||||
doubleListDel(&session_backend->client_side.node);
|
||||
session_backend->client->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
|
||||
session_backend->client = NULL;
|
||||
|
||||
ERROR_FREE
|
||||
{
|
||||
assert(0 == rbt_delete(&session_backend->client->cli_sess_map, session_backend->session_id));
|
||||
doubleListDel(&session_backend->client_side.node);
|
||||
session_backend->client->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
|
||||
session_backend->client = NULL;
|
||||
|
||||
assert(ksemaphore_free(&xizi_task_manager.semaphore_pool, session_backend->client_sem_to_wait));
|
||||
}
|
||||
}
|
||||
|
||||
/* free seesion backend */
|
||||
if (session_backend->server_side.closed && session_backend->client_side.closed) {
|
||||
assert(session_backend->client == NULL && session_backend->server == NULL);
|
||||
kfree((void*)session_backend->buf_kernel_addr);
|
||||
slab_free(SessionAllocator(), (void*)session_backend);
|
||||
ERROR_FREE
|
||||
{
|
||||
assert(session_backend->client == NULL && session_backend->server == NULL);
|
||||
assert(kfree((void*)session_backend->buf_kernel_addr));
|
||||
slab_free(SessionAllocator(), (void*)session_backend);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user