mirror of
https://github.com/drasko/codezero.git
synced 2026-02-28 17:53:13 +01:00
Forks and COW situations show that we need vm objects rather than vm_files.
This is the first commit towards implementing vm object based paging with right COW methods.
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
#ifndef __MM0_PROC__
|
||||
#define __MM0_PROC__
|
||||
|
||||
#include <vm_area.h>
|
||||
|
||||
struct proc_files {
|
||||
struct vm_file *stackfile; /* ZI, private, devzero, then autogenerated */
|
||||
struct vm_file *envfile; /* NON-ZI, private, autogenerated, then autogenerated */
|
||||
struct vm_file *datafile; /* NON-ZI, private, real file, then autogenerated */
|
||||
struct vm_file *bssfile; /* ZI private, devzero, then autogenerated */
|
||||
struct vm_object *stack_file; /* ZI, RO: devzero, RW: private */
|
||||
struct vm_object *env_file; /* NON-ZI, RO: private, RW: private */
|
||||
struct vm_object *data_file; /* NON-ZI, RO: shared, RW: private */
|
||||
struct vm_object *bss_file; /* ZI, RO: devzero, RW: private */
|
||||
};
|
||||
|
||||
int task_prepare_procfiles(struct tcb *t);
|
||||
int task_setup_vm_objects(struct tcb *t);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Thread control block.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#ifndef __TASK_H__
|
||||
#define __TASK_H__
|
||||
@@ -18,9 +18,6 @@
|
||||
|
||||
#define TASK_OFILES_MAX 32
|
||||
|
||||
/* Allow per-task anonymous memory to grow as much as 1 MB for now. */
|
||||
#define TASK_SWAPFILE_MAXSIZE SZ_1MB
|
||||
|
||||
struct vm_file;
|
||||
|
||||
struct file_descriptor {
|
||||
@@ -78,12 +75,6 @@ struct tcb {
|
||||
|
||||
/* File descriptors for this task */
|
||||
struct file_descriptor fd[TASK_OFILES_MAX];
|
||||
|
||||
/* Per-task swap file for now */
|
||||
struct vm_file *swap_file;
|
||||
|
||||
/* Pool to generate swap file offsets for fileless anonymous regions */
|
||||
struct address_pool swap_file_offset_pool;
|
||||
};
|
||||
|
||||
struct tcb *find_task(int tid);
|
||||
@@ -95,7 +86,4 @@ void dump_tasks(void);
|
||||
|
||||
void send_task_data(l4id_t requester);
|
||||
|
||||
/* Used by servers that have a reference to tcbs (e.g. a pager) */
|
||||
#define current ((struct ktcb *)__L4_ARM_Utcb()->usr_handle)
|
||||
|
||||
#endif /* __TASK_H__ */
|
||||
|
||||
@@ -28,15 +28,16 @@
|
||||
#define VMA_ANON (1 << 4)
|
||||
/* Private copy of a file VMA, can be ZI */
|
||||
#define VMA_COW (1 << 5)
|
||||
/* This marks shadow vmas */
|
||||
#define VMA_SHADOW (1 << 6)
|
||||
|
||||
/* VMA object type flags */
|
||||
#define VMOBJ_SHADOW (1 << 6)
|
||||
|
||||
struct page {
|
||||
int count; /* Refcount */
|
||||
struct spinlock lock; /* Page lock. */
|
||||
struct list_head list; /* For list of a file's in-memory pages */
|
||||
struct list_head list; /* For list of a vm_object's in-memory pages */
|
||||
struct vm_object *owner;/* The vm_object the page belongs to */
|
||||
unsigned long virtual; /* If refs >1, first mapper's virtual address */
|
||||
struct vm_file *owner; /* The file it belongs to */
|
||||
unsigned int flags; /* Flags associated with the page. */
|
||||
unsigned long f_offset; /* The offset page resides in its owner */
|
||||
};
|
||||
@@ -59,8 +60,8 @@ struct fault_data {
|
||||
};
|
||||
|
||||
struct vm_pager_ops {
|
||||
int (*read_page)(struct vm_file *f, unsigned long f_offset, void *pagebuf);
|
||||
int (*write_page)(struct vm_file *f, unsigned long f_offset, void *pagebuf);
|
||||
int (*page_in)(struct vm_object *vm_obj, unsigned long f_offset);
|
||||
int (*page_out)(struct vm_object *vm_obj, unsigned long f_offset);
|
||||
};
|
||||
|
||||
/* Describes the pager task that handles a vm_area. */
|
||||
@@ -69,35 +70,57 @@ struct vm_pager {
|
||||
};
|
||||
|
||||
/*
|
||||
* Describes the in-memory representation of a file. This could
|
||||
* point at a file or another resource, e.g. a device area or swapper space.
|
||||
* Describes the in-memory representation of a resource. This could
|
||||
* point at a file or another resource, e.g. a device area, swapper space,
|
||||
* the anonymous internal state of a process, etc. This covers more than
|
||||
* just files, e.g. during a fork, captures the state of internal shared
|
||||
* copy of private pages for a process, which is really not a file.
|
||||
*/
|
||||
struct vm_file {
|
||||
int refcnt;
|
||||
unsigned long vnum; /* Vnode number */
|
||||
unsigned long length;
|
||||
struct list_head list; /* List of all vm files in memory */
|
||||
|
||||
/* This is the cache of physical pages that this file has in memory. */
|
||||
struct list_head page_cache_list;
|
||||
struct vm_pager *pager;
|
||||
struct vm_object {
|
||||
int npages; /* Number of pages in memory */
|
||||
int vma_refcnt; /* Number of vmas that refer */
|
||||
int shadow_refcnt; /* Number of shadows that refer */
|
||||
struct list_head shadows; /* List of vm objects that shadow this one */
|
||||
struct vm_object *orig_vma; /* Original object that this one shadows */
|
||||
unsigned int type; /* Defines the type of the object */
|
||||
struct list_head list; /* List of all vm objects in memory */
|
||||
struct list_head page_cache;/* List of in-memory pages */
|
||||
struct vm_pager *pager; /* The pager for this object */
|
||||
union private_data { /* Private data about the object */
|
||||
struct vm_file *file; /* VFS file-specific information */
|
||||
} priv;
|
||||
};
|
||||
|
||||
/* In memory representation of a vfs file. */
|
||||
struct vm_file {
|
||||
unsigned long vnum;
|
||||
unsigned long length;
|
||||
};
|
||||
|
||||
/* To create per-vma vm_object lists */
|
||||
struct vma_obj_list {
|
||||
struct list_head list;
|
||||
struct vm_object *obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Describes a virtually contiguous chunk of memory region in a task. It covers
|
||||
* a unique virtual address area within its task, meaning that it does not
|
||||
* overlap with other regions in the same task. The region could be backed by a
|
||||
* file or various other resources. This is managed by the region's pager.
|
||||
*
|
||||
* COW: Upon copy-on-write, each copy-on-write instance creates a shadow of the
|
||||
* original vma which supersedes the original vma with its copied modified pages.
|
||||
* This creates a stack of shadow vmas, where the top vma's copy of pages
|
||||
* supersede the ones lower in the stack.
|
||||
*/
|
||||
struct vm_area {
|
||||
struct list_head list; /* Vma list */
|
||||
struct list_head shadow_list; /* Head for shadow list. See fault.c */
|
||||
struct list_head list; /* Per-task vma list */
|
||||
struct list_head vm_obj_list; /* Head for vm_object list. */
|
||||
unsigned long pfn_start; /* Region start virtual pfn */
|
||||
unsigned long pfn_end; /* Region end virtual pfn, exclusive */
|
||||
unsigned long flags; /* Protection flags. */
|
||||
unsigned long f_offset; /* File offset in pfns */
|
||||
struct vm_file *owner; /* File that backs the area. */
|
||||
};
|
||||
|
||||
static inline struct vm_area *find_vma(unsigned long addr,
|
||||
@@ -112,8 +135,8 @@ static inline struct vm_area *find_vma(unsigned long addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Adds a page to its vmfile's page cache in order of offset. */
|
||||
int insert_page_olist(struct page *this, struct vm_file *f);
|
||||
/* Adds a page to its vm_objects's page cache in order of offset. */
|
||||
int insert_page_olist(struct page *this, struct vm_object *vm_obj);
|
||||
|
||||
/* Pagers */
|
||||
extern struct vm_pager default_file_pager;
|
||||
|
||||
Reference in New Issue
Block a user