mirror of
https://github.com/drasko/codezero.git
synced 2026-04-18 01:39:05 +02:00
read_cache_pages() also working copied from write_cache_pages()
- Need to remove old versions - Need to merge the two. - Need to investigate occasional page fault on NMOP sequence. (resembles an error ipc_extended test) Could be related to new page cache read/write routines.
This commit is contained in:
@@ -510,6 +510,67 @@ int new_file_pages(struct vm_file *f, unsigned long start, unsigned long end)
|
|||||||
|
|
||||||
#define page_offset(x) ((unsigned long)(x) & PAGE_MASK)
|
#define page_offset(x) ((unsigned long)(x) & PAGE_MASK)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes user data in buffer into pages in cache. If a page is not
|
||||||
|
* found, it's a bug. The writeable page range must have been readied
|
||||||
|
* by read_file_pages()/new_file_pages().
|
||||||
|
*/
|
||||||
|
int read_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
||||||
|
unsigned long pfn_start, unsigned long pfn_end,
|
||||||
|
unsigned long cursor_offset, int count)
|
||||||
|
{
|
||||||
|
struct page *file_page;
|
||||||
|
unsigned long task_offset; /* Current copy offset on the task buffer */
|
||||||
|
unsigned long file_offset; /* Current copy offset on the file */
|
||||||
|
int copysize, left;
|
||||||
|
int empty;
|
||||||
|
|
||||||
|
task_offset = (unsigned long)buf;
|
||||||
|
file_offset = cursor_offset;
|
||||||
|
left = count;
|
||||||
|
|
||||||
|
/* Find the head of consecutive pages */
|
||||||
|
list_foreach_struct(file_page, &vmfile->vm_obj.page_cache, list) {
|
||||||
|
if (file_page->offset < pfn_start)
|
||||||
|
continue;
|
||||||
|
else if (file_page->offset == pfn_end || left == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
empty = PAGE_SIZE - page_offset(file_offset);
|
||||||
|
|
||||||
|
/* Copy until a single page cache page is filled */
|
||||||
|
while (empty && left) {
|
||||||
|
copysize = min(PAGE_SIZE - page_offset(file_offset), left);
|
||||||
|
copysize = min(copysize, PAGE_SIZE - page_offset(task_offset));
|
||||||
|
/*
|
||||||
|
printf("empty: %d, left: %d, copysize: "
|
||||||
|
"%d, copy to page with pfn %lx, "
|
||||||
|
"offset 0x%lx, from page with pfn "
|
||||||
|
"%lx, offset 0x%lx\n", empty, left,
|
||||||
|
copysize,
|
||||||
|
task_virt_to_page(task,task_offset)->offset,
|
||||||
|
page_offset(task_offset),
|
||||||
|
file_page->offset,
|
||||||
|
page_offset(file_offset));
|
||||||
|
*/
|
||||||
|
page_copy(task_virt_to_page(task, task_offset),
|
||||||
|
file_page,
|
||||||
|
page_offset(task_offset),
|
||||||
|
page_offset(file_offset),
|
||||||
|
copysize);
|
||||||
|
|
||||||
|
empty -= copysize;
|
||||||
|
left -= copysize;
|
||||||
|
task_offset += copysize;
|
||||||
|
file_offset += copysize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BUG_ON(left != 0);
|
||||||
|
|
||||||
|
return count - left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes user data in buffer into pages in cache. If a page is not
|
* Writes user data in buffer into pages in cache. If a page is not
|
||||||
* found, it's a bug. The writeable page range must have been readied
|
* found, it's a bug. The writeable page range must have been readied
|
||||||
@@ -529,9 +590,6 @@ int write_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
|||||||
file_offset = cursor_offset;
|
file_offset = cursor_offset;
|
||||||
left = count;
|
left = count;
|
||||||
|
|
||||||
printf("%s: cursor_offset: 0x%lx, count: 0x%x, buf: %p\n",
|
|
||||||
__FUNCTION__, cursor_offset, count, buf);
|
|
||||||
|
|
||||||
/* Find the head of consecutive pages */
|
/* Find the head of consecutive pages */
|
||||||
list_foreach_struct(file_page, &vmfile->vm_obj.page_cache, list) {
|
list_foreach_struct(file_page, &vmfile->vm_obj.page_cache, list) {
|
||||||
if (file_page->offset < pfn_start)
|
if (file_page->offset < pfn_start)
|
||||||
@@ -541,15 +599,26 @@ int write_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
|||||||
|
|
||||||
empty = PAGE_SIZE - page_offset(file_offset);
|
empty = PAGE_SIZE - page_offset(file_offset);
|
||||||
|
|
||||||
/* Copy until the page is filled */
|
/* Copy until a single page cache page is filled */
|
||||||
while (empty && left) {
|
while (empty && left) {
|
||||||
copysize = min(PAGE_SIZE - page_offset(file_offset), left);
|
copysize = min(PAGE_SIZE - page_offset(file_offset), left);
|
||||||
copysize = min(copysize, PAGE_SIZE - page_offset(task_offset));
|
copysize = min(copysize, PAGE_SIZE - page_offset(task_offset));
|
||||||
//printf("empty: %d, left: %d, copysize: %d, copy to page with pfn %lx, offset 0x%lx, from page with pfn %lx, offset 0x%lx\n",
|
/*
|
||||||
// empty, left, copysize, file_page->offset, page_offset(file_offset),task_virt_to_page(task,task_offset)->offset, page_offset(task_offset));
|
printf("empty: %d, left: %d, copysize: "
|
||||||
page_copy(file_page, task_virt_to_page(task, task_offset),
|
"%d, copy to page with pfn %lx, "
|
||||||
page_offset(file_offset), page_offset(task_offset),
|
"offset 0x%lx, from page with pfn "
|
||||||
|
"%lx, offset 0x%lx\n", empty, left,
|
||||||
|
copysize, file_page->offset,
|
||||||
|
page_offset(file_offset),
|
||||||
|
task_virt_to_page(task,task_offset)->offset,
|
||||||
|
page_offset(task_offset));
|
||||||
|
*/
|
||||||
|
page_copy(file_page,
|
||||||
|
task_virt_to_page(task, task_offset),
|
||||||
|
page_offset(file_offset),
|
||||||
|
page_offset(task_offset),
|
||||||
copysize);
|
copysize);
|
||||||
|
|
||||||
empty -= copysize;
|
empty -= copysize;
|
||||||
left -= copysize;
|
left -= copysize;
|
||||||
task_offset += copysize;
|
task_offset += copysize;
|
||||||
@@ -572,7 +641,7 @@ int write_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
|||||||
* be called first and count must be checked. Since it has read-checking
|
* be called first and count must be checked. Since it has read-checking
|
||||||
* assumptions, count must be satisfied.
|
* assumptions, count must be satisfied.
|
||||||
*/
|
*/
|
||||||
int read_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
int read_cache_pages_orig(struct vm_file *vmfile, struct tcb *task, void *buf,
|
||||||
unsigned long pfn_start, unsigned long pfn_end,
|
unsigned long pfn_start, unsigned long pfn_end,
|
||||||
unsigned long cursor_offset, int count)
|
unsigned long cursor_offset, int count)
|
||||||
{
|
{
|
||||||
@@ -630,7 +699,7 @@ copy:
|
|||||||
int sys_read(struct tcb *task, int fd, void *buf, int count)
|
int sys_read(struct tcb *task, int fd, void *buf, int count)
|
||||||
{
|
{
|
||||||
unsigned long pfn_start, pfn_end;
|
unsigned long pfn_start, pfn_end;
|
||||||
unsigned long cursor, byte_offset;
|
unsigned long cursor;
|
||||||
struct vm_file *vmfile;
|
struct vm_file *vmfile;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -675,12 +744,9 @@ int sys_read(struct tcb *task, int fd, void *buf, int count)
|
|||||||
if ((ret = read_file_pages(vmfile, pfn_start, pfn_end)) < 0)
|
if ((ret = read_file_pages(vmfile, pfn_start, pfn_end)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* The offset of cursor on first page */
|
|
||||||
byte_offset = PAGE_MASK & cursor;
|
|
||||||
|
|
||||||
/* Read it into the user buffer from the cache */
|
/* Read it into the user buffer from the cache */
|
||||||
if ((count = read_cache_pages(vmfile, task, buf, pfn_start, pfn_end,
|
if ((count = read_cache_pages(vmfile, task, buf, pfn_start, pfn_end,
|
||||||
byte_offset, count)) < 0)
|
cursor, count)) < 0)
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
/* Update cursor on success */
|
/* Update cursor on success */
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ int __container_init(int argc, char **argv)
|
|||||||
__libposix_init(envp);
|
__libposix_init(envp);
|
||||||
|
|
||||||
pagerval = getenv("pagerid");
|
pagerval = getenv("pagerid");
|
||||||
printf("Pager id: %s\n", pagerval);
|
|
||||||
|
|
||||||
/* Generic L4 thread initialisation */
|
/* Generic L4 thread initialisation */
|
||||||
__l4_init();
|
__l4_init();
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ void wait_pager(l4id_t partner)
|
|||||||
// printf("Pager synced with us.\n");
|
// printf("Pager synced with us.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pid_t parent_of_all;
|
pid_t parent_of_all;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ int small_io_test(void)
|
|||||||
char strbuf[30];
|
char strbuf[30];
|
||||||
char strbuf2[30];
|
char strbuf2[30];
|
||||||
char *path = "/text.txt";
|
char *path = "/text.txt";
|
||||||
// char stackbuf[PAGE_SIZE*2];
|
char stackbuf[PAGE_SIZE*2];
|
||||||
|
|
||||||
fd1 = open(path, O_TRUNC | O_RDWR | O_CREAT, S_IRWXU);
|
fd1 = open(path, O_TRUNC | O_RDWR | O_CREAT, S_IRWXU);
|
||||||
fd2 = open(path, O_RDWR, 0);
|
fd2 = open(path, O_RDWR, 0);
|
||||||
@@ -26,7 +26,7 @@ int small_io_test(void)
|
|||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
sprintf(strbuf, "%s%d", string, i);
|
sprintf(strbuf, "%s%d", string, i);
|
||||||
printf("Writing to %s offset %x, string: %s\n",
|
test_printf("Writing to %s offset %x, string: %s\n",
|
||||||
path, i*PAGE_SIZE, strbuf);
|
path, i*PAGE_SIZE, strbuf);
|
||||||
lseek(fd1, i*PAGE_SIZE, SEEK_SET);
|
lseek(fd1, i*PAGE_SIZE, SEEK_SET);
|
||||||
write(fd1, strbuf, strlen(strbuf) + 1);
|
write(fd1, strbuf, strlen(strbuf) + 1);
|
||||||
@@ -38,19 +38,23 @@ int small_io_test(void)
|
|||||||
sprintf(strbuf2, "%s%d", string, i);
|
sprintf(strbuf2, "%s%d", string, i);
|
||||||
lseek(fd2, i*PAGE_SIZE, SEEK_SET);
|
lseek(fd2, i*PAGE_SIZE, SEEK_SET);
|
||||||
read(fd2, strbuf, 30);
|
read(fd2, strbuf, 30);
|
||||||
printf("Read %s, offset %x as %s\n",
|
test_printf("Read %s, offset %x as %s\n",
|
||||||
path, i*PAGE_SIZE, strbuf);
|
path, i*PAGE_SIZE, strbuf);
|
||||||
if (strcmp(strbuf, strbuf2))
|
if (strcmp(strbuf, strbuf2))
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/* Now read into an unaligned buffer larger than page size */
|
/* Now read into an unaligned buffer larger than page size */
|
||||||
lseek(fd2, 0, SEEK_SET);
|
lseek(fd2, 0, SEEK_SET);
|
||||||
|
|
||||||
read(fd2, stackbuf, PAGE_SIZE * 2);
|
read(fd2, stackbuf, PAGE_SIZE * 2);
|
||||||
printf("stackbuf beginning: %s\n second page beginning: %s\n",
|
|
||||||
stackbuf, &stackbuf[PAGE_SIZE]);
|
sprintf(strbuf2, "%s%d", string, 0);
|
||||||
#endif
|
if (strcmp(stackbuf, strbuf2))
|
||||||
|
goto out_err;
|
||||||
|
sprintf(strbuf2, "%s%d", string, 1);
|
||||||
|
if (strcmp(&stackbuf[PAGE_SIZE], strbuf2))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
close(fd2);
|
close(fd2);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ int forktest(void)
|
|||||||
|
|
||||||
|
|
||||||
/* 16 forks */
|
/* 16 forks */
|
||||||
for (int i = 0; i < 1; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
test_printf("%d: Forking...\n", getpid());
|
test_printf("%d: Forking...\n", getpid());
|
||||||
if (fork() < 0)
|
if (fork() < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|||||||
Reference in New Issue
Block a user