Support multi page task mapping

This commit is contained in:
tuyuyang 2024-07-28 14:02:14 +08:00
parent 19d467463b
commit 4716a4e018
13 changed files with 41 additions and 48 deletions

View File

@ -50,7 +50,7 @@ int main(void)
shellInit(&shell, shellBuffer, 512); shellInit(&shell, shellBuffer, 512);
while (connect_session(&session_fs, "MemFS", 8092) < 0) while (connect_session(&session_fs, "MemFS", 0x10000) < 0)
; ;
if (!session_fs.buf) { if (!session_fs.buf) {
printf("session connect faield\n"); printf("session connect faield\n");

View File

@ -108,7 +108,7 @@ int main(int argc, char** argv)
struct Session fs_session; struct Session fs_session;
static char id_buf[33] = { 0 }; static char id_buf[33] = { 0 };
if (id > 1) { if (id > 1) {
if (connect_session(&fs_session, "MemFS", 8192) < 0) { if (connect_session(&fs_session, "MemFS", 0x2000) < 0) {
printf("connect fs_session failed\n"); printf("connect fs_session failed\n");
} else { } else {
int fd; int fd;

View File

@ -15,11 +15,12 @@
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv) int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
{ {
/* read elf image */ /* read elf image */
int max_communicate_size = session->capacity - 0x1000;
int file_size = ipc_fsize(session, fd); int file_size = ipc_fsize(session, fd);
void* img = malloc(file_size); void* img = malloc(file_size);
int read_len = 0; int read_len = 0;
while (read_len < file_size) { while (read_len < file_size) {
int cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096; int cur_read_len = file_size - read_len < max_communicate_size ? file_size - read_len : max_communicate_size;
if (cur_read_len < 0) { if (cur_read_len < 0) {
return -1; return -1;
} }

View File

@ -36,7 +36,7 @@ Modification:
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define MAX_BUDDY_ORDER (12) #define MAX_BUDDY_ORDER (20)
#define FREE_LIST_INDEX(order) \ #define FREE_LIST_INDEX(order) \
(1 << order) (1 << order)

View File

@ -158,21 +158,18 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
} }
uintptr_t cur_size = ALIGNUP(old_size, PAGE_SIZE); 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(size_needed);
char* new_page = kalloc(PAGE_SIZE); if (new_page == NULL) {
if (new_page == NULL) { ERROR("No memory\n");
ERROR("No memory\n"); return cur_size;
return cur_size;
}
memset(new_page, 0, PAGE_SIZE);
if (!xizi_pager.map_pages(pmemspace, cur_size, V2P(new_page), PAGE_SIZE, false)) {
return cur_size;
}
CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P(new_page));
cur_size += PAGE_SIZE;
} }
memset(new_page, 0, size_needed);
if (!xizi_pager.map_pages(pmemspace, cur_size, V2P(new_page), size_needed, false)) {
return cur_size;
}
CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page));
return new_size; return new_size;
} }

View File

@ -65,8 +65,6 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
void _free_user_pgdir(struct TopLevelPageDirectory* pgdir) 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; 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++) { for (uintptr_t level4_entry_idx = 0; level4_entry_idx < end_idx; level4_entry_idx++) {

View File

@ -83,8 +83,6 @@ void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
return; 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); 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++) { for (uintptr_t l2_entry_idx = 0; l2_entry_idx < end_idx; l2_entry_idx++) {

View File

@ -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); vaddr = alloc_share_page_addr(task, nr_pages * 2);
// time to use buddy // 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); task->memspace->massive_ipc_allocator = (struct KBuddy*)slab_alloc(&xizi_task_manager.task_buddy_allocator);
if (!task->memspace->massive_ipc_allocator) { if (!task->memspace->massive_ipc_allocator) {
ERROR("Alloc task buddy failed.\n"); ERROR("Alloc task buddy failed.\n");

View File

@ -53,22 +53,17 @@ int sys_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, int is_dev)
return -1; return -1;
} }
} else { } else {
int load_len = 0;
uintptr_t load_vaddr = *vaddr; uintptr_t load_vaddr = *vaddr;
while (load_len < true_len) { char* new_paddr = raw_alloc(true_len);
char* new_paddr = raw_alloc(PAGE_SIZE); if (new_paddr == NULL) {
CreateResourceTag(NULL, &cur_task->memspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, new_paddr); return -1;
if (new_paddr == NULL) {
return -1;
}
if (xizi_share_page_manager.task_map_pages(cur_task, load_vaddr, (uintptr_t)new_paddr, 1, false) == (uintptr_t)NULL) {
raw_free(new_paddr);
return -1;
}
load_vaddr += PAGE_SIZE;
load_len += PAGE_SIZE;
*paddr = (uintptr_t)new_paddr;
} }
if (xizi_share_page_manager.task_map_pages(cur_task, load_vaddr, (uintptr_t)new_paddr, true_len / PAGE_SIZE, false) == (uintptr_t)NULL) {
raw_free(new_paddr);
return -1;
}
CreateResourceTag(NULL, &cur_task->memspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, new_paddr);
*paddr = (uintptr_t)new_paddr;
} }
cur_task->memspace->mem_size += true_len; cur_task->memspace->mem_size += true_len;

View File

@ -52,6 +52,7 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
struct double_list_node* cur_node = NULL; struct double_list_node* cur_node = NULL;
struct server_session* server_session = NULL; struct server_session* server_session = NULL;
/* update old sessions */ /* update old sessions */
for (int i = 0; i < arr_capacity; i++) { for (int i = 0; i < arr_capacity; i++) {
if (UNLIKELY(userland_session_arr[i].buf == NULL)) { if (UNLIKELY(userland_session_arr[i].buf == NULL)) {
@ -111,12 +112,13 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
}; };
struct IpcMsg* msg = IPCSESSION_MSG(&userland_session_arr[session_idx]); struct IpcMsg* msg = IPCSESSION_MSG(&userland_session_arr[session_idx]);
if (is_msg_needed(msg)) { if (msg != NULL && is_msg_needed(msg)) {
nr_sessions_need_to_handle++; nr_sessions_need_to_handle++;
} }
session_idx++; session_idx++;
} }
if (session_idx < arr_capacity) { if (session_idx < arr_capacity) {
userland_session_arr[session_idx].buf = NULL; userland_session_arr[session_idx].buf = NULL;
if (!has_middle_delete && nr_sessions_need_to_handle == 0) { if (!has_middle_delete && nr_sessions_need_to_handle == 0) {

View File

@ -42,19 +42,20 @@ int sys_yield(task_yield_reason reason)
if ((reason & SYS_TASK_YIELD_BLOCK_IPC) != 0) { if ((reason & SYS_TASK_YIELD_BLOCK_IPC) != 0) {
if (cur_task->advance_unblock) { if (cur_task->advance_unblock) {
cur_task->advance_unblock = false; cur_task->advance_unblock = false;
return 0;
} else { } else {
xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task); xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task);
} }
}
// wake up all possible server // wake up all possible server
struct client_session* client_session = NULL; struct client_session* client_session = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node) DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node)
{ {
assert(client_session != NULL); assert(client_session != NULL);
struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session); struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session);
if (session_backend->server->state == BLOCKED) { if (session_backend->server->state == BLOCKED) {
xizi_task_manager.task_unblock(session_backend->server); xizi_task_manager.task_unblock(session_backend->server);
}
} }
} }

View File

@ -146,6 +146,7 @@ uintptr_t* load_memspace(struct MemSpace* pmemspace, char* img_start)
if (ph.vaddr % PAGE_SIZE != 0) { if (ph.vaddr % PAGE_SIZE != 0) {
LOG("Unsupported elf file, try use flag -N to compile.\n"); LOG("Unsupported elf file, try use flag -N to compile.\n");
} }
for (int addr_offset = 0; addr_offset < ph.filesz; addr_offset += PAGE_SIZE) { for (int addr_offset = 0; addr_offset < ph.filesz; addr_offset += PAGE_SIZE) {
uintptr_t page_paddr = xizi_pager.address_translate(&pmemspace->pgdir, ph.vaddr + addr_offset); uintptr_t page_paddr = xizi_pager.address_translate(&pmemspace->pgdir, ph.vaddr + addr_offset);
if (page_paddr == 0) { if (page_paddr == 0) {
@ -257,8 +258,8 @@ struct ThreadStackPointer load_user_stack(struct MemSpace* pmemspace, char** arg
pmemspace->mem_size += USER_STACK_SIZE; pmemspace->mem_size += USER_STACK_SIZE;
loaded_sp.argc = argc; loaded_sp.argc = argc;
loaded_sp.stack_idx = stack_idx;
loaded_sp.user_sp = user_vspace_sp; loaded_sp.user_sp = user_vspace_sp;
loaded_sp.user_stack_vaddr = (uintptr_t)stack_bottom; loaded_sp.user_stack_vaddr = (uintptr_t)stack_bottom;
loaded_sp.stack_idx = stack_idx;
return loaded_sp; return loaded_sp;
} }

View File

@ -350,7 +350,7 @@ static void _task_unblock(struct Thread* task)
assert(task->state == BLOCKED); assert(task->state == BLOCKED);
task_node_leave_list(task); task_node_leave_list(task);
task->state = READY; task->state = READY;
task_node_add_to_ready_list_head(task); task_node_add_to_ready_list_back(task);
} }
/// @brief @warning not tested function /// @brief @warning not tested function