Another work-in-progress towards having extra structures per mapping per page:

* vm_area and vm_page now have a new field "mappings" where they will store lists
  of vm_page_mapping structures. vm_page::ref_count is gone, as it's no longer
  needed (it was never updated correctly, anyway).
* vm_caches now have a type field, ie. CACHE_TYPE_RAM for anonymous areas - this
  makes the stores a bit less independent, but is quite handy in several places.
* Added new vm_map_page() and vm_unmap_pages() functions to be used whenever you
  map in or unmap pages into/from an area. They don't do much more than handling
  vm_page::wired_count correctly right now, though (ie. B_LAZY_LOCK is now working
  as expected as well).
* Moved the device fault handler to vm_map_physical_memory(); it was not really
  used as a fault handler, anyway.
* Didn't notice Ingo's changes to the I/O space region broke lock_memory(). It
  now checks the type of the area that contains the memory, and doesn't lock
  anymore if not needed which solves the problem in a platform independent way.
* Implemented lock_memory() and unlock_memory() for real: they now change the
  vm_page::wired_count member to identify pages that shouldn't be paged out.
* vm_area_for() now uses vm_area_lookup() internally.
* Fixed various potential overflow conditions with areas that reach 0xffffffff.
* Creating anonymous areas with B_FULL_LOCK no longer causes vm_soft_fault()
  to be called, instead, the pages are allocated and mapped (via vm_map_page())
  directly.
* Removed the _vm_ prefix for create_area_struct() and create_reserved_area_struct().
* Fixed a bug in vm_page_write_modified() that would not have enqueued pages that
  failed to be written to the modified queue again when needed.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20251 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-02-28 13:24:53 +00:00
parent 91f1fe44d2
commit ca954b7816
6 changed files with 355 additions and 146 deletions
+3 -2
View File
@@ -60,10 +60,11 @@ area_id vm_clone_area(team_id team, const char *name, void **address,
status_t vm_delete_area(team_id aid, area_id id);
status_t vm_create_vnode_cache(void *vnode, vm_cache_ref **_cacheRef);
vm_area *vm_area_lookup(vm_address_space *addressSpace, addr_t address);
status_t vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type);
status_t vm_get_page_mapping(team_id team, addr_t vaddr, addr_t *paddr);
status_t vm_unmap_pages(vm_area *area, addr_t base, size_t length);
status_t vm_map_page(vm_area *area, vm_page *page, addr_t address,
uint32 protection);
status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, uint32 flags);
status_t vm_put_physical_page(addr_t vaddr);
+68 -6
View File
@@ -10,10 +10,60 @@
#include <kernel.h>
#include <sys/uio.h>
#include <arch/vm_types.h>
#include <arch/vm_translation_map.h>
#include <util/DoublyLinkedQueue.h>
#include <sys/uio.h>
#ifdef __cplusplus
struct vm_page_mapping;
typedef DoublyLinkedListLink<vm_page_mapping> vm_page_mapping_link;
#else
typedef struct { void *previous; void *next; } vm_page_mapping_link;
#endif
typedef struct vm_page_mapping {
vm_page_mapping_link page_link;
vm_page_mapping_link area_link;
struct vm_page *page;
struct vm_area *area;
} vm_page_mapping;
#ifdef __cplusplus
class DoublyLinkedPageLink {
public:
inline vm_page_mapping_link *operator()(vm_page_mapping *element) const
{
return &element->page_link;
}
inline const vm_page_mapping_link *operator()(const vm_page_mapping *element) const
{
return &element->page_link;
}
};
class DoublyLinkedAreaLink {
public:
inline vm_page_mapping_link *operator()(vm_page_mapping *element) const
{
return &element->area_link;
}
inline const vm_page_mapping_link *operator()(const vm_page_mapping *element) const
{
return &element->area_link;
}
};
typedef class DoublyLinkedQueue<vm_page_mapping, DoublyLinkedPageLink> vm_page_mappings;
typedef class DoublyLinkedQueue<vm_page_mapping, DoublyLinkedAreaLink> vm_area_mappings;
#else // !__cplusplus
typedef void *vm_page_mappings;
typedef void *vm_area_mappings;
#endif
// vm page
typedef struct vm_page {
@@ -31,12 +81,15 @@ typedef struct vm_page {
struct vm_page *cache_prev;
struct vm_page *cache_next;
int32 ref_count;
vm_page_mappings mappings;
uint32 type : 2;
uint32 state : 3;
uint32 busy_reading : 1;
uint32 busy_writing : 1;
uint8 type : 2;
uint8 state : 3;
uint8 busy_reading : 1;
uint8 busy_writing : 1;
uint16 wired_count;
int8 usage_count;
} vm_page;
enum {
@@ -56,6 +109,13 @@ enum {
PAGE_STATE_UNUSED
};
enum {
CACHE_TYPE_RAM = 0,
CACHE_TYPE_VNODE,
CACHE_TYPE_DEVICE,
CACHE_TYPE_NULL
};
// vm_cache_ref
typedef struct vm_cache_ref {
struct vm_cache *cache;
@@ -82,6 +142,7 @@ typedef struct vm_cache {
uint32 temporary : 1;
uint32 scan_skip : 1;
uint32 busy : 1;
uint32 type : 5;
} vm_cache;
// vm area
@@ -97,6 +158,7 @@ typedef struct vm_area {
struct vm_cache_ref *cache_ref;
off_t cache_offset;
vm_area_mappings mappings;
struct vm_address_space *address_space;
struct vm_area *address_space_next;